# Gosub Engine: an embeddable Rust browser engine with no JavaScript yet

> Gosub is a modular, async browser engine you embed in your own user-agent, not a browser you run. The HTML5 and CSS3 parsers, layout and render backends work; scripting is not wired in.

**gosub-io/gosub-engine** — The Gosub browser engine

- Repository: https://github.com/gosub-io/gosub-engine
- Website: https://gosub.io
- Stars: 3,689 · Forks: 181
- Language: Rust
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/gosub-io-gosub-engine

## What problem Gosub Engine solves, and who it is for

Most browser engines are shipped as part of a browser. Gosub is packaged the other way round: it is a library with a single entry point, `GosubEngine` in the `gosub_engine` crate, and it expects you to bring the parts that touch the screen. The README states that you provide a render backend and a compositor, while the engine owns a multi-zone and multi-tab model, an async networking stack, cookie and storage isolation per zone, and an event bus.

That split defines the audience. If you are writing a desktop application that needs to display arbitrary web content inside its own window, or a headless service that fetches and lays out pages without a browser process, Gosub is aimed at you. You drive it through `TabCommand` and react to `EngineEvent`; your user-agent is the thing that decides what a tab is and when it appears. The repository ships examples for exactly this shape of integration: `examples/winit-cairo`, `examples/winit-skia`, `examples/winit-vello`, `examples/gtk4-cairo`, `examples/gtk4-skia`, `examples/egui-cairo` and others, alongside `bin/gosub-mini-browser` and `bin/gosub-screenshot`.

It is not aimed at anyone who wants a browser binary to install and browse with. There is a mini-browser binary in the workspace, but the README frames the project as an engine to embed, and the documentation is organised around embedder concerns: configuration, zones and tabs, resource pipelines, render pipeline internals.

## How the engine is put together: crates, zones and the command/event seam

The workspace is split by concern, and the README's component table is the clearest map of it. `gosub_engine` is the unified entry point. `gosub_interface` holds the shared traits that wire components together, described as the config system. `gosub_html5` and `gosub_css3` are the tokenizer and parser crates. `gosub_render_pipeline` covers layout via Taffy, stages, tiling and the compositor, with `gosub_lattice` handling CSS table layout separately. Rendering is pluggable: `gosub_renderer_cairo` is a CPU Cairo backend, `gosub_renderer_skia` is CPU or GPU, and `gosub_renderer_vello` is GPU through wgpu. `gosub_fontmanager` handles shaping and measurement, `gosub_jsapi` implements browser Web APIs, and `gosub_v8` holds the V8 bindings.

Networking lives outside the repository: `gosub-sonar` is an external crate, described as an async, streaming, priority-scheduled networking stack. The README credits it with inflight coalescing, redirect handling and per-zone cookie isolation.

The concurrency model is the part worth understanding before you design around it. Zones are isolated profiles that hold cookies and storage; tabs are independent worker tasks. Commands flow in as `TabCommand` or `EngineCommand`, and events flow out as `EngineEvent`, covering navigation, resources and redraw. Form controls follow the same pattern: the engine raises `EngineEvent::PickerRequested` for colour, date and time pickers, and the embedder is the one that opens them. Nothing in this design assumes a window exists, which is why the Null backend can be used headless.

The README points to `docs/two-worlds.md` for the document and style models and the seam that joins them, and says to read it before diving into either. That is an unusual warning to put in a README, and it is a fair signal that the internal architecture is not something you can infer from the public API alone.

## Building Gosub and opening your first tab

The README does not print an install command, so the repository itself is the source of truth here. `Cargo.toml` declares the package as `gosub_bin` with `rust-version = "1.92"` and edition 2021, and `rust-toolchain.toml` sits at the top level, so a toolchain-aware Cargo will pick the right compiler. A workspace build is the first step:

```bash
cargo build --all
```

The `Makefile` wraps the same thing with a `build` target that sources `test-utils.sh` and runs `cargo build --all`. For a first real use, the repository provides `examples/tutorial.rs`, which the README describes as starting the engine, opening a tab, navigating and handling events. The `Makefile` documents the test and build targets, and `docs/examples.md` is where the README points for running the examples, including headless, GUI (winit, GTK4, egui) and component tools.

If you want to see a page rendered without a window, the README documents headless usage in `docs/headless.md`, and the render backend list includes a Null backend for exactly that. The component tools are separate binaries; `bin/gosub-screenshot` and `bin/gosub-mini-browser` are workspace members, and `docs/binaries.md` is the index for the standalone `cargo run --bin …` tools.

Configuration is the choice you make before anything renders. `docs/configuration.md` covers selecting a render backend and font system, `docs/moduleconfig.md` explains what `DefaultRenderConfig` wires for you and how to go fully custom, and `gosub_config` is the configuration store crate. The README does not document rollback or version pinning for the engine itself.

## The JavaScript gap is the limitation that decides your adoption

The README is direct about this: scripting is not wired into the engine. The `gosub_v8` and `gosub_jsapi` crates exist and build, but no page runs JavaScript. Web-platform-tests drive the DOM through a separate test-only QuickJS binding, `gosub_domjs`, which is not part of the engine's runtime path.

The practical consequence is that Gosub can parse, lay out and paint a large class of pages, and then fail on any page whose content depends on script. That covers most modern sites. It also means the conformance numbers need reading carefully: a gated web-platform-tests run in CI and a reftest runner are both present, and `docs/wpt.md` is where the README says the numbers stand, but a passing DOM test driven by a test-only binding is not the same as a working scripted page in the engine.

A second limitation is structural rather than missing. You supply the compositor. The engine owns tiling and stages in `gosub_render_pipeline`, but the compositing side of the contract is yours, which is a real integration cost if you were hoping to drop the engine into an existing view hierarchy and get pixels out.

There is also a workspace hygiene signal worth noting: `Cargo.toml` sets `unsafe_code = "forbid"` at the workspace level and denies `unwrap_used`, `expect_used`, `panic`, `todo` and `unimplemented` in clippy. That constrains what contributors can write, and it is a reasonable guess that it slows some low-level work, though the README does not discuss the trade-off.

## Gosub against Servo and against a system WebView

Servo is the obvious comparison, and the difference is in packaging rather than parsing. Servo is also a Rust browser engine, but it is developed as a browser engine project with its own embedding story; Gosub is built around an embedder-supplied render backend and compositor, with three renderer crates in-tree (Cairo, Skia, Vello) and a Null backend for headless work. If you want an engine that makes the rendering decision for you, that is a different proposition from one that hands you the choice.

The second alternative is not an engine at all: a system WebView. Platforms ship one, it runs JavaScript, and it is already on the machine. The difference in approach is total. A WebView gives you a complete, scripted browsing context you do not control; Gosub gives you a scriptless engine whose zones, tabs, networking and storage you can isolate and instrument, at the cost of building the parts a WebView already has.

A reasonable way to frame the choice: pick Gosub when the value is in owning the pipeline and the isolation model, and pick a WebView when the value is in rendering the web as it actually is. The README's own framing supports this. It describes the engine as modular and embeddable, and it points contributors at exploratory work such as proofs-of-concept and reading specs rather than pure coding.

## Maintenance, licence and what an upgrade costs you

The repository is not archived, and the last push was on 2026-09-21. A nightly build was published on 2026-09-23. That is a recent cadence, and the README describes the engine as under active development, which the push date supports.

The cost of tracking it is the cost of tracking a young Rust workspace. The package version in `Cargo.toml` is `0.1.1`, so there is no stable API promise to lean on. The workspace pins a specific compiler through `rust-toolchain.toml` and requires `rust-version = "1.92"`, which means your build environment has to follow the project's toolchain rather than the other way round. Dependencies are pinned centrally in `[workspace.dependencies]`, and the `Makefile` includes `test-check`, which runs `cargo check --locked --all --all-features`, plus a `test-deny` target that runs `cargo deny check` for advisories, licences, bans and sources. If you vendor or fork the engine, those targets are the cheapest way to see what changed.

The licence is MIT, declared in both the README and the `Cargo.toml` package metadata. MIT is permissive and imposes no copyleft obligation on your own code, but the dependency tree is a separate question: `deny.toml` and `audit.toml` exist at the top level, and the `test-deny` target is how the project checks its own dependency licences. Run that check against your own tree if you redistribute a binary. This is not legal advice; read the licence texts yourself.

## Conclusion

Adopt Gosub if you are building a user-agent, a headless renderer or a conformance harness and you want the engine to own zones, tabs, networking and layout while you supply the render backend and compositor. Do not adopt it if your pages need JavaScript: the README states that no page runs JavaScript and that V8 and the web-API crates exist and build but are not wired in. Before committing, read docs/status.md for the per-component gaps, confirm the render backend you need is among Null, Cairo, Skia and Vello, and check docs/wpt.md for where the conformance numbers actually stand.

## FAQ

### Does Gosub Engine run JavaScript?

No. The README states that scripting is not wired into the engine, and that while the V8 and web-API crates exist and build, no page runs JavaScript. Web-platform-tests drive the DOM through a separate test-only QuickJS binding called gosub_domjs.

### How do I install Gosub Engine?

The README does not give an install command. The repository is a Cargo workspace with rust-toolchain.toml at the top level and rust-version = "1.92" in Cargo.toml, so a workspace build with cargo build --all is the starting point, and the Makefile provides a build target that does the same.

### Which render backends does Gosub Engine support?

The README lists a Null backend for headless use, Cairo for CPU via GTK4, Skia for CPU or GPU, and Vello through wgpu for GPU. You provide the render backend and compositor; docs/configuration.md covers choosing one and docs/moduleconfig.md covers what DefaultRenderConfig wires for you.

### What is the licence for Gosub Engine?

MIT, declared in the README and in the Cargo.toml package metadata. The repository also carries deny.toml and audit.toml, and the Makefile has a test-deny target that runs cargo deny check for advisories, licences, bans and sources.

## Sources

- [gosub-io/gosub-engine on GitHub](https://github.com/gosub-io/gosub-engine)
- [License: MIT](https://github.com/gosub-io/gosub-engine/blob/main/LICENSE)
- [Project website](https://gosub.io)
- [README](https://github.com/gosub-io/gosub-engine/blob/main/README.md)
- [Releases](https://github.com/gosub-io/gosub-engine/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/gosub-io-gosub-engine
