addyosmani/rust-browser

Robin - build a web browser engine from scratch in Rust

★ 8Forks 5HTMLGitHub ↗Compare
browserrustweb-browser

README

🐦 Robin - build a web browser engine from scratch in Rust

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 rendering and scrolling Hacker News

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.

It renders real pages

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)
Hacker News rendered by Robin Wikipedia rendered by Robin Google rendered by Robin

(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.)

What it does

  • 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.

Quick start

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 --window

Handy 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.

New to Rust? Start here

You do not need to be a Rust expert - this repo is a good way to become one. Here's the gentlest path:

  1. Install Rust with rustup.rs (one command). Check it worked: cargo --version.
  2. Run the tests: cargo test. Everything should pass. You just compiled and exercised a whole browser engine.
  3. 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.
  4. 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).

How it works

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>"]
Loading

The CLI in src/main.rs wires these together; the chapters below walk each module in this order.

Learn it commit by commit

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.

Built to learn with an agent

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 you
  • docs/ - 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."

How it's built

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

License

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.

Contributors

addyosmani

Issues