Northstar is a minimalist web browser written from scratch in C. Its engine targets practical HTML5, modern CSS and JavaScript compatibility without embedding Gecko, WebKit, Blink or another browser engine. Linux is the primary platform; macOS and Windows are also supported.
See Nordstjernen Web Browser also, which is the most complete, fully featured web browser project we are making. Nordstjernen has builds for Windows, Linux, MacOs.
Northstar is licensed under the GNU General Public License, version 3 or later.
- This repo is the Northstar web browser, a minimalist, simple and good web browser. This is more about research about browser tech.
- Nordstjernen Web Browser is the most complete, fully featured web browser.
We are doing web browser innovation, research and development, and part of this is making multiple web browser variants to test and compare
Web standards: Behaviour is measured against the specification text, section by section, not against another browser. The engine runs web-platform-tests through headless mode; see docs/compliance.md for the current per-area scores and the known structural gaps.
Security: on Linux the browser runs behind a Landlock filesystem
sandbox (plus PR_SET_NO_NEW_PRIVS), with a default-deny seccomp syscall
filter in both GUI and headless/tooling modes · no JIT.
See SECURITY.md for the exact per-mode posture.
Minimalism: one page per window, one process. The GTK shell runs on the main thread and the page engine on one dedicated thread with its own main loop, so a slow page never freezes the window; the shell posts requests to that thread and gets rendered frames back, all inside the same process. The engine is a compact body of C — about 191,000 lines of original C, excluding the vendored WAMR, Wuffs and audio decoders — small enough for one person to read and audit end-to-end. See docs/architecture.md for how it fits together.
This edition strips Northstar down to a tab-less, single-process desktop browser, based on the Nordstjernen project. It deliberately omits tabs, per-tab renderer processes, WebGL, WebGPU, an embedded PDF viewer and AI-style web APIs. It does not send telemetry or update pings.
Audio still plays in-process (MP3, MP2, Ogg Opus/Vorbis). Images decode in-tree (PNG/APNG, GIF, BMP, JPEG and WebP via Wuffs, AVIF through libavif when available, and SVG in the engine).
- HTML parsed to a DOM by lexbor; CSS by the engine's own
cascade — flex, grid and subgrid, transforms, gradients,
@keyframes, scroll snap, container queries, cascade layers,:has(), nesting,@property, and typedcalc()math over lengths, angles, times and resolutions. - JavaScript on the quickjs-ng interpreter (or Fabrice Bellard's
original QuickJS) — DOM, Shadow DOM, Mutation/Intersection/Resize/
Performance observers,
Intl, Canvas 2D (Path2D,ImageBitmap,DOMMatrix,OffscreenCanvas), WebCrypto (crypto.subtleover OpenSSL). - Custom elements — autonomous and customized built-in elements.
- Workers — dedicated workers with structured-clone messaging, message channels and broadcast channels.
- Storage — IndexedDB over SQLite,
localStorage/sessionStorageand the Cache API (caches, request/response pairs per the Service Workers specification, kept in IndexedDB), each partitioned by origin. - Live connections — WebSockets (with libcurl 8.11 or newer, or one built with WebSocket support) and server-sent events.
- Navigation API —
window.navigationfor single-page routing. - Service workers — origin-scoped registration, persistence, controlled-page fetch interception and offline pages served from the Cache API.
- WebExtensions — installed local extensions with manifest content
scripts, safe packaged resources,
storage.local,i18nand declarativeNetRequest rule sets. - Networking over HTTP/2 with libcurl — HTTP/3 through Alt-Svc when
the linked libcurl provides it — HTTPS-first navigation, HSTS,
optional DNS-over-HTTPS, CSP, subresource-integrity (SRI) checks for
scripts, and cookies partitioned by site — one libcurl cookie store per
site, shared by
document.cookieand that site's network requests. - Safe browsing — before a top-level navigation is fetched, its host
is checked against a local SHA-256 blocklist. The check runs entirely
on-device. The bundled list carries only test entries; a real list goes
in
~/.config/northstar/safebrowsing.listor is named byNS_SAFEBROWSING_LIST. - Media — images (PNG/APNG, GIF, BMP, JPEG, WebP, optional AVIF,
SVG); audio (
<audio>) decodes and plays in the browser process, alongside a Web Audio graph.<video>plays MPEG-1 (video/mpeg), decoded in-tree by the same pl_mpeg that already handles MP2 audio. Frames are decoded as the clip plays, so memory holds one frame whatever its length; a program stream's MP2 track plays alongside it, andcontrolsdraws a play/pause button, seek bar, time and mute button. MPEG-1 is an ISO standard whose patents have expired, so it costs no dependency and no licence; it is also not a format the modern web serves, so this is video support for local and self-hosted clips rather than for streaming sites. - Printing —
Ctrl+Plays the page out for paper and hands the sheets to the operating system's own print dialog throughGtkPrintOperation: CUPS on Linux, the Win32 dialog on Windows, the Cocoa panel on macOS.@media printmatches,@pagesets the sheet size and margins, andbreak-before/break-after/break-insidedecide where a sheet ends. - MathML — a minimalist presentation-MathML renderer.
- Spell checking — optional, via the Enchant library.
- WebAssembly — the JavaScript API over WAMR's fast interpreter, vendored in-tree; no JIT and no ahead-of-time compilation.
- One process, no tabs — each window shows one page (New Window opens another in the same process), and the page engine runs on its own thread inside the shell process; there are no renderer processes. A watchdog restarts the browser, with its session, after a crash or hang.
- UI — bookmarks, history, downloads, find-in-page, zoom, full
screen, printing, save as PDF or image, page source, developer tools
with a JS console, settings, private browsing (
--private), and a UI translated into 40 languages that follows the operating-system language. - Headless mode — text, DOM, layout, PNG and PDF dumps, scripted input and web-platform-tests runs from the command line; see docs/building.md.
On Debian or Ubuntu, install the required development packages:
sudo apt install build-essential git pkg-config meson ninja-build cmake \
libgtk-4-dev libcurl4-openssl-dev libssl-dev libuchardet-dev \
libharfbuzz-dev libfribidi-dev libcairo2-dev libfontconfig-dev \
libfreetype-dev libpsl-dev libsqlite3-dev libseccomp-dev libsdl2-dev \
zlib1g-dev
meson setup builddir
meson compile -C builddir
./builddir/src/gtk/northstarFor macOS (Homebrew or MacPorts), other Linux distributions and Windows, see docs/building.md.
The development helper configures the default build directory when needed and runs the same compile command:
./scripts/dev.sh build
./scripts/dev.sh smokeThe smoke command renders deterministic local fixtures through the headless engine and compares them with the checked-in baselines. A single page can also be rendered directly:
./builddir/src/gtk/northstar --headless --dump=text about:startMeson feature options include -Davif=disabled, -Daudio=disabled and
-Dwasm=disabled for smaller builds. -Djs_engine=quickjs builds on
Fabrice Bellard's original QuickJS instead of the default quickjs-ng.
WAMR, Wuffs, pl_mpeg and minimp3 are vendored in-tree. ns-pango, lexbor
and quickjs-ng are pinned upstream subprojects (see subprojects/*.wrap)
that meson setup fetches; see
docs/building.md for how
a pin is moved.
Northstar's engine is written from scratch — it contains no forked browser engine (no Gecko, WebKit, or Blink). It is the GPL edition of the Nordstjernen project.
Pinned upstream meson subprojects (subprojects/*.wrap), fetched by
meson setup:
| Component | Role |
|---|---|
| lexbor v3.0.1 | HTML5 → DOM parser and the WHATWG URL module |
| quickjs-ng v0.17.0 | JavaScript engine — no JIT |
| QuickJS 2026-06-04 | The original JavaScript engine, used instead of quickjs-ng with -Djs_engine=quickjs |
| ns-pango | Text itemization, shaping and line breaking — a Pango fork with a cross-layout shaping cache |
lexbor (3.0 or newer) and quickjs-ng take a system copy instead when the build finds one; ns-pango is always the subproject, since the fork's renamed symbols are what let it coexist with the system Pango that GTK loads.
Vendored in-tree (built from the main tree, no submodules):
| Component | Role |
|---|---|
| WAMR 2.4.5 (subset) | WebAssembly fast interpreter |
| Wuffs v0.4 | Memory-safe image decoding — PNG/APNG, GIF, BMP, JPEG, WebP |
| pl_mpeg (MIT) | In-process MPEG-1 video and MP2 audio decode |
| minimp3 (CC0) | In-process MP3 audio decode |
Required system libraries: GTK 4 (≥ 4.14; ≥ 4.22.1 on Windows),
GLib (≥ 2.80), Cairo (≥ 1.18), HarfBuzz (≥ 8.3), FriBidi (≥ 1.0.6), fontconfig
(≥ 2.15), FreeType, libcurl (≥ 8.5), OpenSSL (libcrypto), uchardet,
libpsl, SQLite and zlib — Ubuntu 24.04, Debian 13 and Fedora 40 meet
every floor; Ubuntu 22.04 and older cannot build it. The engine lays
text out through ns-pango rather than the system Pango; GTK still links
the system Pango for its own widgets, and the two coexist because every
symbol in the fork is renamed. Linux builds also require libseccomp.
SDL2 provides audio output: it is picked up when present and required
with -Daudio=enabled.
Optional (auto-detected): libavif (AVIF images), opusfile / vorbisfile (in-process Ogg audio), Enchant (spell-checking) and libthai (Thai line breaking).
Northstar is free software, licensed under the GNU General Public License, version 3 or later — see LICENSE.
Project home: https://nordstjernen.org/northstar-browser/ · Copyright 2026 Andreas Røsdal.

