I was planning to have the project in a more complete state before announcing to HN :-)
It was mostly a fun project to put together v8, GLFW and Skia, and I hope others find it useful and fun to work on too.
If you find this interesting then consider getting in touch via GitHub Discussions or the mailing list and helping out with the next features: WebGL 2 API, networking (fetch) API, sound, etc.
I don't have much experience collaborating in opensource projects so any feedback is very welcome. Thanks for having a look!
You may already know this, but for WebGL you should use ANGLE. It's what the browsers mostly use and will guarantee compatibility across platforms. Trying to implement the WebGL API over desktop GL yourself will be a never ending black hole of issues. https://chromium.googlesource.com/angle/angle/+/main/README....
Most desktop platforms unfortunately don't provide a native GLES driver, so you'd have to translate desktop GL to GLES. This is harder than it sounds, if you care about getting everything right. ANGLE handles that for you. Additionally it contains dozens of workarounds for serious driver issues on various platforms. And implementations of WebGL extensions that differ from GL/GLES extensions.
In addition to all that, it does let you use DirectX on Windows instead of GL (and Metal on Mac and Vulkan wherever). The reason you want that is that many Windows PCs do not have a GL driver installed. Microsoft does not ship one, so if the OEM didn't install one and the user didn't install one then it simply doesn't exist. And even when the GL driver is installed, it is often buggier than the DirectX driver. Similarly on Mac, GL is buggier than Metal (and officially deprecated).
> Most desktop platforms unfortunately don't provide a native GLES driver, so you'd have to translate desktop GL to GLES.
This is somewhat less true than it used to be since one of the required features of OpenGL 4.3 is GLES 3.0 compatibility. Unfortunately, Mac OS is stuck on GL 4.1 forever (at least until they drop support completely anyway) and the other points you bring up are quite valid.
For new development in native cross platform graphics I would recommend Dawn or wgpu-native as a base instead of GL. That will get you excellent portability with a modern style of API.
Very cool! I'm a web dev and I've wanted to get into game dev. From my cursory glance, this seems like exactly what I'd like to build on top of: just the essentials for a performant interactive application.
libsdl and GLFW are very similar! I ended up using GLFW because it's closer to what I wanted to do with Skia and WebGL, and I didn't need the 2D functionality of SDL.
Note that Window.js does not expose GLFW directly; it exposes APIs that are more similar to the web, for familiarity to web devs.
100%. Sticking close to web APIs will guarantee the longest shelf life of code written against it. I'm a big fan of Deno rather than Node for the same reasons.
Thanks for building a cool project, I'll definitely be tracking along.
I've been working on something that should be fairly compatible, but I'll need to do a little tweaking on my end for windowjs: https://thelanding.page/tag/
It's basically a reactive client-side library that aims to decouple the necessary UI things like state management and event delegation from the DOM. It's tiny (~300 lines of code iirc). No external dependencies besides a lazy loaded Virtual DOM library that wouldn't be needed in a windowjs environment.
instead of an html function that renders when state changes, i can create a function that can draw on the windowjs canvas, probably on requestAnimationFrame.
I’m curious what the resulting package would look like. Like you’re including the v8 runtime but not chrome itself (A la electron). I suspect it would be smaller but no idea how much smaller.
1. provide type declarations for the Window.js APIs, and
2. integrate with the Typescript compiler during development (e.g. F5 to reload, run typescript sources "directly", show compiler errors in the console / main window, etc.)
I've just started these discussion on GitHub, please share your thoughts:
It looks like a cool project, but... why not use lightweight webviews (WebView2/WKWebView)? Or even the heavyweight Electron/NW.js? These brings you full web API compatibility, extensibility points, and webviews have a small footprint too. What does this project aim to do differently? I don't mean to criticise a hobby project if that's what this is, it's all well and good, I'm just wondering what the thinking is.
Electron is a lot more feature-complete and mature, and that's what should be used for any serious projects indeed :-)
Window.js is a subset; it doesn't include the DOM nor the CSS APIs, nor a lot of web APIs.
Window.js is a tool I wish I had for exploratory 2D (and 3D) programming, without having to install multiple tools, SDKs and runtimes, and without the restrictions that web pages have when it comes to desktop applications. I wanted something like Processing but with more control, or like <canvas> but without all the browser cruft around it, and in a native window.
I think it could be a very useful tool to learn WebGL via webglfundamental.org, for example, and having something that runs on the desktop quickly.
A goal of Window.js is to eventually run Processing (p5.js), Pixi.js, Phaser and Threejs programs, as long as they don't use the DOM too much.
Three.js should load and run as long as its usage of window, document, etc works as it expects. So the plan is to have a small loader that prepares the environment that Three.js expects before loading it.
After the initial load, all of the p5.js APIs make CanvasRendering2DContext calls, which Window.js implements natively.
Almost all of the p5.js examples work with this approach, except those that use DOM elements like buttons and sliders. Those elements could also be faked, with some patience :-)
I think it's pretty cool that p5.js scripts can run on a desktop window this way, outside of the browser!
As an aside, I also originally intended to implement an HTML renderer on something like Window.js, and make a "browser from scratch" based on it. Maybe for another day...
One immediate comparison that springs to my mind is the Löve 2D engine [1], which is a tiny game engine written entirely around Lua scripting (so that Lua includes the full game run loop as well).
Lua is a good scripting language, but it doesn't have the ubiquity of JS (and Löve doesn't have the ubiquitous deployment of the modern browser). Also, Lua doesn't have a static type ecosystem (though there are interesting projects like TypescriptToLua [2] exploring that space, but you can from the name they are following/lagging the JS ecosystem here).
There probably is a need to package more browser games as "real" games and a lightweight Canvas-focused approach could find a nice like Löve, especially if it were easier, for instance, to maybe port to consoles for small/indie game teams than one of the web views or Electron. (Though certainly Microsoft already has a version of WebView2 running on the Xbox.)
Browsers have a large amount of overlap with operating systems - and with efforts to move more of web tech into userland (web components/etc all starting to rationalize HTML and other layers as being built on top of other more fundamental web APIs, etc)
After seeing how pretty Windows 11 applications are, I've been trying to create Windows desktop applications using Go or Rust but I have no idea what the Windows GUI API looks like and am unable to find/create bindings.
Linux's GTK4 is pretty easy to use, it's like vanilla JS and it's easy to get started.
Microsoft made it really hard to get started, and I gave up not long after I started.
I'm really glad you mentioned PixiJS - that would be a very compelling use case for me! I formerly built a lot of casual 2D / 2.5D games in AIR. Pixi is my favorite screen graph library now by far.
The biggest thing I think the JS/canvas/WebGL ecosystem is really lacking, sorry to say, is the ability to compile to .ipa and .apk, with something like AIR Native Extensions (which worked along the lines of Phonegap plugins to centralize access to Android and iOS APIs in a common library). Cordova is dead and there's no replacement. And Cordova was never really meant for writing games. Something like this with WebGL support that just opened a full screen phone app running PixiJS - even with just minimal connectivity APIs - would be a great option for quickly building indie games.
Yeah... I looked into that a little, but I've always avoided React like the plague. Looking at JSX just drives me up a wall, and I'm not into the idea of the React Native pseudo-DOM. Oddly it feels a little like Flex/MXML which also annoyed me to no end.
Note that Chrome also builds on Skia, via the Blink rendering engine. So Skia is very well aligned with the needs of the Canvas API.
As for performance, Window.js has a bit less overhead since it doesn't have a DOM and doesn't implement web security.
On the other hand, Chrome is widely used and has a super talented team that knows systems programming, GPU programming, etc in a lot of depth and have spent a ton of time optimizing web APIs. So I wouldn't be surprised if Chrome and Electron have better performance in benchmarks -- this is definitely something to measure!
As an example, this p5js example runs very slowly on Window.js:
The reason is that it's doing something like a getPixel(x, y) call in a loop, which Chrome somehow optimizes; in Window.js this is going to be a roundtrip to the GPU for each pixel, which is extremely expensive.
(IMO, the right way to implement getPixel based on the Canvas API would be to read all the pixels once via canvas.getImageData)
I don't remember very much, but have you tried making a SkImage snapshot on the first call to getImageData (and calls to drawImage that use that canvas), and just reusing that? I think it might do its own caching when you read pixels from it
Also invalidate the snapshot on any calls that invalidate the contents of the snapshot of course (stroke, fill, drawImage, fillRect, strokeRect... probably a couple others).
I have also reimplemented the canvas 2d api using skia for my own stuff.
Ideally yes, Window.js should make it possible (and easy!) to build fully accessible programs. I don't have much experience in this area though, so I'd have to look for help building this :-)
There's AccessKit which would work great if we were a few years in the future and they'd finished their bindings and non-windows implementations. Other than that I don't know of anything cross-platform other than Qt which is rather large.
Not quite, as this is a native program and not a Javascript module.
Window.js is like Node itself, but has different APIs. The main difference is that it gives you a desktop window and the Canvas 2D API, and doesn't have any of Node's networking APIs.
Other differences to Node:
* every source is imported to Window.js as an ES6 module.
* Window.js does not support NPM and doesn't aim to.
* Node uses callbacks for async APIs, Window.js uses Promises
* Node is widely tested and used, Window.js is quite new and experimental :-)
Other projects have built bindings for GLFW for Node. Have a look at the GLFW documentation and search for "node":
I was planning to have the project in a more complete state before announcing to HN :-)
It was mostly a fun project to put together v8, GLFW and Skia, and I hope others find it useful and fun to work on too.
If you find this interesting then consider getting in touch via GitHub Discussions or the mailing list and helping out with the next features: WebGL 2 API, networking (fetch) API, sound, etc.
I don't have much experience collaborating in opensource projects so any feedback is very welcome. Thanks for having a look!