Gosub Browser Engine
An embeddable, async browser engine written in Rust.
Join us on our development Zulip chat, or our Discord server for general chat. If you'd like to contribute, start with the contribution guide.
About
Gosub is a modular, embeddable browser engine. The primary entry point is GosubEngine in the
gosub_engine crate. You provide a render backend and a compositor; the
engine owns a multi-zone/tab model, an async networking stack, cookie and storage isolation per
zone, and an event bus. Your user-agent (UA) drives everything via TabCommand and reacts to
EngineEvent.
Core components:
| Crate | Role |
|---|---|
gosub_engine |
GosubEngine — the unified entry point |
gosub_interface |
Shared traits wiring the components together (the config system) |
gosub_html5 |
HTML5 tokenizer / parser |
gosub_css3 |
CSS3 tokenizer / parser |
gosub-sonar |
Networking stack (async, streaming, priority-scheduled) — external crate |
gosub_lattice |
CSS table layout |
gosub_render_pipeline |
Render pipeline — layout (Taffy), stages, tiling, compositor |
gosub_renderer_cairo |
Cairo render backend (CPU) |
gosub_renderer_skia |
Skia render backend (CPU / GPU) |
gosub_renderer_vello |
Vello / wgpu render backend (GPU) |
gosub_fontmanager |
Font system — text shaping and measurement |
gosub_jsapi |
Browser Web API implementations (console, fetch, DOM, …) |
gosub_v8 |
V8 JavaScript engine bindings |
gosub_config |
Configuration store |
For the full crate listing see docs/crates.md.
Status
The engine is under active development. What works today:
- Multi-zone / multi-tab model — zones isolate cookies and storage; tabs are controlled via
TabCommand - Async networking — streaming HTTP fetcher with priority queues, inflight coalescing, redirect handling, and per-zone cookie isolation
- Event-driven UA interface —
EngineEvent(navigation, resource, redraw) flows out;TabCommand/EngineCommandflow in - HTML5 and CSS3 parsing — spec-compliant parsers for both, including shadow DOM (parsing, flat-tree traversal, CSS scoping)
- Resource pipeline — parser-driven sub-resource discovery; stylesheets, images, web fonts and data URLs all fetched through one fetcher, with hierarchical cancellation
- Layout and paint — block, inline, flex and grid via Taffy, floats, absolute and fixed positioning, and CSS tables via
gosub_lattice - Form controls — text editing, and colour / date / time pickers opened by the embedder through
EngineEvent::PickerRequested - Pluggable render backends — Null (headless), Cairo (GTK4), Skia (CPU / GPU), Vello (wgpu)
- Conformance measurement — a gated web-platform-tests run in CI, plus a reftest runner; see docs/wpt.md for where the numbers stand
docs/status.md is the detailed version of this list — per component,
what works and what does not, with the numbers.
Not there yet: scripting is not wired into the engine. The V8 and web-API crates exist and
build, but no page runs JavaScript — see docs/javascript.md. WPT drives
the DOM through a separate test-only QuickJS binding (gosub_domjs).
Documentation
docs/README.md indexes every page under /docs. The pages below are the
ones worth reading first.
Getting started
- Tutorial — start the engine, open a tab, navigate, handle events
- Configuration — choosing a render backend and font system
- Running the examples — headless, GUI (winit / GTK4 / egui), and component tools
- Headless usage — rendering real pages without a window
- WebAssembly — compile and run the engine in the browser
- Development — tests and benchmarks
Reference
- What the engine can do today — per-component capability and gaps
- Crates — the workspace crate layout, and where to find anything
- Component tools — the standalone
cargo run --bin …tools
Architecture
- The two worlds — the two parallel document/style models and the seam that joins them. Read this before diving into either.
- Interface trait families —
ModuleConfigurationand theHas*traits that wire the workspace together - Module configuration — the same picture from an embedder's side:
what
DefaultRenderConfigwires for you and how to go fully custom - Zones and tabs — zones as isolated profiles, tabs as independent worker tasks, and the command/event flow between them
- Resource pipelines — how fetched bytes become typed assets
- CSS internals —
gosub_css3from text to computed value - HTML5 parsing — tokenizer, tree builder, arena DOM
- Render pipeline
- Lattice table layout · Fonts · JavaScript stack
- Networking — architecture and design notes
- Cookies
- Storage (local / session)
- Pump — moving HTTP stream data to targets
Conformance
- WPT quickstart — clone to a fixed test in about ten minutes. The fastest way to make a first contribution.
- Web-platform-tests — the harness in full: what is bound, the expectations format, the reftest runner, and what CI does
Contributing
We welcome contributions. Because the engine is still taking shape, a lot of work is exploratory — building proofs-of-concept, reading specs, and making architectural decisions — rather than pure coding.
Join us on Zulip or Discord before diving in; it will save you time and help us keep things coordinated. See CONTRIBUTING.md for the details.