Where it runs
Every line here was run, not assumed: the binary was started on that system and asked to check its own layout.
✓ run and checked ○ builds, or follows from what was measured ✗ known not to work
Linux
| ✓ | Debian 11 · 12 · 13 | layout clean, scripts running |
| ✓ | Ubuntu 20.04 · 22.04 · 24.04 | layout clean, scripts running |
| ✓ | Fedora 41 | JavaScriptCore comes inside webkit2gtk4.1 there |
| ✓ | CentOS 7 — glibc 2.17 | the oldest C library the binary asks for, from 2012. Anything newer is in range |
| ✓ | Alpine and other musl systems | spark build linux-musl-x86_64 / -arm64; webkit2gtk-4.1 brings the engine |
Windows
| ✓ | Windows 10 · 11, x86_64 | the target this is built and checked against |
| ✓ | Windows, 32-bit (win-x86) | 285 KB, same layout, same scripts |
| ○ | Windows on ARM (win-arm64) | not run on real hardware here — and such a machine runs the x86_64 build under emulation anyway |
| ○ | Windows 7 · 8.1 | the binary imports the Universal CRT, which ships with Windows only from 10. Earlier needs KB2999226, which Windows Update has delivered since 2015. Building against the older msvcrt instead would need a second toolchain: zig ships no import library for it |
| ✓ | curl.exe for spark.fetch | in System32 since Windows 10 1803; a Wine prefix has none, so requests answer null there |
| ✓ | Wine | how Windows is checked from a Mac. Its own JScript is below ES5, which is why the bundling step targets es5 |
macOS
| ✓ | macOS 11 and later, Apple silicon | the machine this is developed on |
| ○ | macOS 11 and later, Intel | the universal binary carries the slice; not run on Intel hardware here |
Windowing
| ✓ | GTK 3 | what the Linux host talks to, opened at run time |
| ✓ | Wayland | natively: the Linux host links neither libX11 nor libXft |
| ✓ | X11 | the same host, on the older session |
What the three JavaScript engines actually agree about
Spark ships no engine. macOS and Linux use the JavaScriptCore the system already has; Windows uses Chakra, and Chakra is ES5.1. That is a real trade, and a trade nobody measures is one nobody can hold us to — so the same document is run on all three and what each one answered is checked into the repository. This table is that file.
| question | macOS | Linux | Windows |
|---|---|---|---|
es6.let | yes | yes | no |
es6.arrow | yes | yes | no |
es6.promise | yes | yes | no |
es6.map | yes | yes | no |
es6.set | yes | yes | no |
es6.symbol | yes | yes | no |
es6.objectAssign | yes | yes | no |
es6.startsWith | yes | yes | no |
es6.includes | yes | yes | no |
es2017.padStart | yes | yes | no |
es2019.flat | yes | yes | no |
text.upper.sharpS | STRASSE | STRASSE | STRAßE |
text.compare | before | before | threw |
text.normalize | yes | yes | no |
number.addition | 0.30000000000000004 | 0.30000000000000004 | 0.3 |
number.big | 1e+21 | 1e+21 | 1E+21 |
number.parseIntOct | 8 | 8 | 0 |
number.maxSafe | yes | yes | no |
regexp.unicode | yes | yes | no |
regexp.named | yes | yes | no |
date.toISO | 1970-01-01T00:00:00.000Z | 1970-01-01T00:00:00.000Z | threw |
date.parse | 1577934245000 | 1577934245000 | NaN |
22 of 44 questions. The rest all three answered the same way.
parseInt("08") is 0 on Windows and
8 elsewhere, 1e21 prints with a capital E, and
0.1 + 0.2 prints as 0.3 rather than the
seventeen digits everything else shows. Bundling fixes syntax. It does not
fix these.spark test js # run it everywhere and compare
spark test js --write # record what the engines say now
A difference already written down is a fact about the world. A new one is a change, and the build says so.
How it is checked
spark cross app/index.html
The same document through macOS, a Linux container and Wine, each asked
“is every widget where the layout put it?” and “what can the
keyboard reach?”, each leaving a screenshot behind. The distribution
table above comes from running the Linux binary in a
clean container of each, installing nothing but
libgtk-3-0 libfontconfig1, then adding the JavaScript engine
to see the scripts run.
libjavascriptcoregtk-4.1-0; Fedora ships it inside
webkit2gtk4.1. Spark opens it at run time under every name it is
known by, and a machine without it still starts and still shows the document,
with one line saying its scripts will not run.