SparkStartGuideReferencePlatformsCompare GitHub

Native apps from markup,
with nothing bundled.

Spark reads HTML-ish markup and builds real operating-system widgets — a real NSButton, a real Win32 button, a real X11 one. The JavaScript is the engine your system already ships. No browser, no runtime beside the app. A whole app is one file of a few hundred kilobytes.

<button id="greet">Greet</button>

Not a picture of a button. The real control, with its own focus ring, its own keyboard behaviour, and its own line to VoiceOver and Narrator.

The same document, on three systems

Spark on macOS
macOS · AppKit
Spark on Windows
Windows · Win32
Spark on Linux
Linux · X11

One markup file, three native toolkits, and a layout computed once in shared C so none of them can disagree about where anything is. spark cross runs it on all three, checks that every widget landed where the layout put it, and leaves those screenshots behind. That is how the pixels are kept the same rather than hoped to be.

What you get

Real widgets

AppKit, Win32 and X11 controls — not a canvas pretending to be one.

Nothing bundled

JavaScriptCore on macOS and Linux, Chakra on Windows. Both already on the machine.

One file

spark pack glues the app onto the binary. A few hundred KB, not 180 MB.

Accessible by construction

A real button is exposed to VoiceOver and Narrator. No webview can buy that.

Idle costs nothing

No render loop. The clock runs only while something is actually moving.

Cross-checked

Every release runs the same document through macOS, a Linux container and Wine.

The whole idea in four lines

Structureis layout: <row>, <col>, <grid>, <stack>, <scroll>
Attributesare cosmetics: gap, pad, bg, radius — no CSS, no cascade, no selectors
Layoutis computed once, in shared C, because three hosts is three chances to decide the same thing differently
JavaScriptis the system's own, and the DOM it sees is a small honest subset
Dropping CSS was a decision, not a gap. GTK4 and Qt both independently ship a real CSS engine on real native widgets — and both leave out the layout properties. That is the empirical boundary. Saying "CSS" also promises a specification nobody can finish.

Where it runs

Debian 11–13, Ubuntu 20.04–24.04, Fedora 41, CentOS 7, Alpine, Windows 10 and 11 including 32-bit, macOS 11 and later — each one started and asked to check its own layout and run the document's scripts. The full table.

Sixty seconds

git clone https://github.com/eddime/spark-native && cd spark-native
./spark new myapp
./spark dev myapp/index.html

The window opens and every save reloads it — the system says when the file changed, so nothing is polling. Then the rest of the way to a signed app.