A tiny, readable browser engine - not a Chromium or WebKit wrapper. Every stage that turns bytes on the wire into pixels on the screen is implemented here in plain Rust, one commit at a time, so you can learn how browsers (and Rust) actually work.
Robin is a modern, from-scratch reimagining of the classic Intro to Rust: building a browser engine tutorial (itself inspired by Matt Brubeck's Let's build a browser engine! / robinson - hence the name Robin). The original is wonderful but now abandoned and outdated; this repo brings the same idea up to modern Rust, makes it render real pages, and is built to be agent-first so you can point a coding agent at it and learn by doing.
No JavaScript, no flexbox, no GPU - just a parser, a cascade, a layout engine and a software rasterizer, all hand-written. Yet it's enough to read the web:
| Hacker News | Wikipedia | Google (no-JS) |
|---|---|---|
![]() |
![]() |
![]() |
(These are rendered from the offline snapshots in assets/snapshots/;
regenerate them with scripts/render-demos.sh. The
Wikipedia shot is the article body - see chapter 12
for why the nav stacks on top without float support.)
- Parses real HTML into a DOM - tolerant of the messy markup real sites ship
- Parses CSS - selectors, the cascade, specificity, inheritance
- Builds a layout tree - the box model, block + inline flow, text wrapping
- Paints to a pixel buffer and saves a PNG, or opens a scrollable window
- Rasterizes anti-aliased text with bundled fonts (no system fonts needed)
- Fetches pages over HTTPS, from local files, or from bundled offline snapshots
It is deliberately small and has real limits (no JavaScript, no flexbox/grid, no
incremental layout). Those limits are the point -
see docs/12-limitations-and-next-steps.md.
You need a recent Rust toolchain (rustup.rs). Then:
# Render a bundled snapshot of Hacker News to a PNG (no network needed)
cargo run --release -- assets/snapshots/hackernews.html --png out/hn.png
# Render a live page over HTTPS
cargo run --release -- https://example.com --png out/example.png
# Open an interactive, scrollable window
cargo run --release -- assets/snapshots/wikipedia.html --windowHandy flags: --dump-dom and --dump-layout print the tree at that stage,
--width <px> sets the viewport width, and --clip-top/--clip-height crop the
PNG to one band of a tall page. Run cargo run -- --help for all of them.
You do not need to be a Rust expert - this repo is a good way to become one. Here's the gentlest path:
- Install Rust with rustup.rs (one command). Check it
worked:
cargo --version. - Run the tests:
cargo test. Everything should pass. You just compiled and exercised a whole browser engine. - Read Chapter 0, then
Chapter 1: The DOM. The DOM module
(
src/dom.rs) is ~150 lines and uses only basic Rust - it's the friendliest place to begin. - Do the exercises at the end of each chapter. Run one module's tests while
you work, e.g.
cargo test dom.
Every chapter has a "Rust notes" section that points out the Rust ideas
(ownership, enum/match, Option, lifetimes, iterators) as you meet them in
real code. If a concept is new, the official, free The Rust Programming
Language book explains each one well - keep it
open in a tab. And if you're using a coding agent, just ask it to explain any
line; this repo is set up to help it teach you (see below).
Each box is one Rust module in src/, and the page flows through them
top to bottom. Solid arrows carry the page's data from stage to stage; dotted
arrows show the font engine, which layout uses to measure text and paint uses
to draw it.
flowchart TD
URL["URL / file / snapshot"] --> NET["net.rs<br/><i>fetch bytes + linked CSS</i>"]
NET -->|HTML| HTML["html.rs<br/><i>tokenizer + tree builder</i>"]
HTML -->|DOM tree| DOM["dom.rs<br/><i>Node / Element / Text</i>"]
NET -->|"CSS (linked + inline)"| CSS["css.rs<br/><i>selectors + declarations</i>"]
DOM --> STYLE["style.rs<br/><i>the cascade + user-agent sheet</i>"]
CSS -->|Stylesheet| STYLE
STYLE -->|styled tree| LAYOUT["layout.rs<br/><i>box model + inline flow</i>"]
LAYOUT -->|box tree| PAINT["paint.rs<br/><i>display list</i>"]
PAINT -->|draw commands| RENDER["render.rs<br/><i>Canvas (software rasterizer)</i>"]
TEXT["text.rs<br/><i>font metrics + glyphs</i>"] -. measure .-> LAYOUT
TEXT -. draw glyphs .-> RENDER
RENDER -->|pixels| PNG["PNG file"]
RENDER -->|pixels| WIN["window.rs<br/><i>scrollable window</i>"]
The CLI in src/main.rs wires these together; the
chapters below walk each module in this order.
This repo's git history is the tutorial. Each commit adds exactly one idea,
and each maps to a chapter in docs/:
git log --oneline --reverse # walk the whole pipeline, one concept at a time| # | Chapter | Module |
|---|---|---|
| 0 | How to use this repo | - |
| 1 | The DOM | dom.rs |
| 2 | The HTML parser | html.rs |
| 3 | The CSS parser | css.rs |
| 4 | Style & the cascade | style.rs |
| 5 | Block layout | layout.rs |
| 6 | Painting | paint.rs, render.rs |
| 7 | Text rasterization | text.rs |
| 8 | Inline layout & text flow | layout.rs |
| 9 | Networking | net.rs |
| 10 | The interactive window | window.rs |
| 11 | Rendering real pages | (the messy-web fixes) |
| 12 | Limitations & next steps | - |
Every chapter ends with exercises that extend that stage - that's where the
real learning happens. Run a single stage's tests with e.g. cargo test layout.
Robin is agent-first. Point a coding agent (Claude Code, Cursor, …) at this repo and it has everything it needs to teach you, not just to dump answers:
AGENTS.md/CLAUDE.md- a codebase map, the build/test commands, conventions, and explicit guidance to coach youdocs/- a chapter per stage, with graded exercises- A clean module-per-stage layout and per-module tests you can run one at a time
A good first prompt: "I'm learning Rust. Walk me through src/dom.rs, then give
me exercise 1 from docs/01-the-dom.md and review my attempt."
Pure standard library for the core stages (DOM, HTML, CSS, style, layout); each remaining stage adds exactly one focused crate, exactly when it's first needed:
| Crate | Used for | First appears in |
|---|---|---|
image |
PNG output (codec only) | painting |
fontdue |
glyph rasterization | text |
ureq + url |
HTTPS fetch + URL resolution | networking |
minifb |
the interactive window | window |
MIT for the code (see LICENSE); the bundled DejaVu fonts are under
their own permissive license (see assets/fonts/FONT-LICENSE.txt).
Inspired by tensor-programming's original tutorial and Matt Brubeck's robinson.



