Window.js is an open-source JavaScript runtime for desktop graphics programming
github.com
github.com
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!
My one question: Would it be possible to integrate with SDL2? https://www.libsdl.org/
Note that Window.js does not expose GLFW directly; it exposes APIs that are more similar to the web, for familiarity to web devs.
For example, GLFW has this for mouse input:
https://www.glfw.org/docs/latest/input_guide.html#input_mous...
But Window.js wraps that in window.addEventListener and "mousedown" events:
https://windowjs.org/doc/window#window.addEventListener https://windowjs.org/doc/window#event-mousedown
If you give it a try to build a game then keep in mind that it doesn't have a sound API yet, though that's part of the future plans.
Finally, is there something specific in libsdl that you'd like to have and Window.js doesn't support?
From all my user research, it looks like nothing beats up, down, left, right, confirmation and cancellation actions, so that's all I really need.
Are those gamepad events accessible through addEventListener?
https://github.com/windowjs/windowjs/issues/19
Window.js replicates web APIs where it makes sense, so I'd look into duplicating the Gamepad API:
https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API
Does that make sense to you?
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.
The largest part is, by far, v8; I think there's room to remove unused code there.
You can see the size of the binary in the GitHub Actions builds:
https://github.com/windowjs/windowjs/actions
Each build workflow has a "Binary size" step at the end, that outputs the binary size, size after stripping, and size after using UPX.
Here's what the latest build got:
* Windows: 6,639,616 bytes (19,523,072 before UPX)
* macOS: 8,196,112 bytes (23,431,800 before UPX)
* Linux: 8,186,668 bytes (28,679,960 before UPX and stripping, 22,346,264 bytes after stripping)
Do you happen to be familiar with ANGLE? What happens if I just expose GLES 3.0 bindings as WebGL2 based on the native drivers on each platform?
(my earlier understanding was that ANGLE was a WebGL-to-Direct3D translation layer, for compat on Windows.)
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).
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.
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:
https://github.com/windowjs/windowjs/discussions/27
https://github.com/windowjs/windowjs/discussions/28
Does this cover what you had in mind? Are there better ways to support Typescript?
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.
Isn’t that a lot of work? Or is there an obvious way to hook it up that I’m missing?
This has already been done for Processing/p5.js:
https://windowjs.org/about/processing
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...
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)
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.
Documentation is here:
UI example is: https://github.com/microsoft/windows-samples-rs/tree/master/...
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.
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:
https://p5js.org/examples/simulate-smokeparticles.html
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)
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.
* seems like Plask is only for macOS (Window.js also supports Windows and Linux)
* Plask exposes the Skia APIs directly to Javascript; Window.js exposes a <canvas>-alike API instead (but also based on Skia)
* Plask supports video playback with AVPlayer; Window.js doesn't have video support (for now :-)
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 :-)
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":