Falco: Tiny browser engine written from scratch in Rust Falco, a browser engine written from scratch in Rust by a single developer, is now available as v0.1.0, comprising roughly 36,000 lines of code that render HTML, CSS, JavaScript, SVG, and images to PNG or an interactive window. The engine includes a custom JS VM with JIT compilation, a hand-written PNG encoder, and support for flex/grid/table layout, but many spec-compliant modules (e.g., WHATWG tokenizer, Shadow DOM, Selectors Level 4) are compiled but not yet integrated into the render pipeline, with full integration planned for v0.2.0. Logo by Sanya — t.me/SanyochekDev A tiny, fast browser engine written in Rust. Renders HTML, CSS, JavaScript, SVG and images — to a PNG, or to a live interactive window. Quick start quick-start · Interactive mode interactive-mode---window · Features what-it-supports · Architecture architecture · Contributing /poxk/Falco/blob/main/.github/CONTRIBUTING.md Falco is a real browser engine in roughly 36,000 lines of Rust . It parses HTML, applies CSS, executes JavaScript, loads images, computes layout, and paints to a canvas — either as a PNG file or a live interactive window where you can scroll, click links, fill out forms, and navigate. HTML ──▶ DOM ──▶ Style tree ──▶ Layout tree ──▶ Paint commands ──▶ Canvas ──▶ PNG / Window ▲ ▲ ▲ │ │ │ HTML5 tokenizer CSS cascade Flex / Grid / Table / Float / Absolute + tree builder + Selectors 4 + Inline / Block flow │ JS custom VM with closures, generators, Promise, BigInt, Symbol │ Image loader ──▶ HTTP / data: URL / local file Falco is not a wrapper around WebKit, Gecko, or Chromium. Every module — HTML tokenizer, CSS parser, layout engine, JS VM, font rasterizer, PNG encoder — is written from scratch in Rust. To set expectations clearly — this is v0.1.0, an early release by a single developer. Not everything listed in this README is production-ready. Here's what is actually wired into the render pipeline and what is structurally complete but not yet called: - HTML parser html/ — legacy parser, not spec-compliant but functional - DOM types dom/ — minimal node types, no observers/shadow - CSS parser css/ — selectors, properties, cascade, color parsing - Style cascade style/ — UA styles + inheritance + flex/grid props - Layout layout/ — block / inline / flex / CSS Grid / table / float / absolute - Painting paint/ — fonts ab glyph , gradients, shadows, alpha compositing - SVG renderer svg/ — paths, basic shapes, gradients, stroke + fill - Hand-written PNG encoder png/ - Image loader image/ — HTTP, data: URLs, local files - JS VM tjs/ — bytecode interpreter + JIT x86 64, Linux-only - JS-DOM bindings js tjs/ , js runner/ — document.getElementById , console.log , alert , onclick - Networking net/ — HTTP/1.1 ureq , cookies, cache, websocket, redirect - Interactive --window mode — scrolling, forms, navigation, history These exist as spec-compliant replacements for the legacy modules. They compile and have their own unit tests, but render with base url does not call into them yet. This is the v0.2.0 milestone. html::spec — WHATWG §13.2 tokenizer all 80 states + tree builder all 22 insertion modes + serializer + XML parser + encoding detection dom::spec — spec DOM with MutationObserver, Shadow DOM, custom elements, accessibility tree css::spec — Selectors Level 4 :has , :is , :where , cascade layers, container queries tjs ext/ — Symbol, BigInt, Promise, microtasks, Map/Set, WeakMap/WeakSet, Reflect security/ — SOP, multi-process, seccomp sandbox, CSP, TLS cert chain validation, permissions, extensions, DevTools protocol. All algorithms are in place and unit-tested, but the renderer doesn't enforce them yet. web runtime/ — fetch , XMLHttpRequest , event loop, Promise. The Promise / event loop integration is real and unit-tested, but fetch and XHR are stubbed no real network behind them in the JS context . WebGL, video, MSE, EME, NDSD are headless stubs — they implement the API surface but don't actually render WebGL frames, decode H.264 video, or do DRM. They exist as scaffolding for future work. media/ — @media queries are parsed but always applied no conditional cascade yet real-http2 , real-webgl , sandbox Cargo features do not compile with --all-features because their upstream APIs have drifted h2::Body removed, glow API changed, seccomp pre exec is Unix-only . They are disabled by default and the CI clippy step does not check them.- The JIT tjs/jit.rs works on Linux x86 64 but fails on macOS CI runners because mmap MAP JIT requires code signing with the com.apple.security.cs.allow-jit entitlement. JIT tests are marked ignore on macOS. - DOM mutation from JS element.innerHTML = ... , element.style.color = ... does not trigger re-render. - HTML5 spec-compliant tree repair adoption agency, foster parenting is in html/spec/tree builder.rs but the legacy parser is what actually runs. Bottom line: if you cargo build && ./falco https://example.com --out out.png , you get a real PNG render. The HTML/CSS/layout/paint path works end-to-end. The spec-compliant parsers, security enforcement, and advanced web runtime WebGL/video/DRM are scaffolding for future milestones , not working features. Please read the code before claiming otherwise. Build release binary lands in target/release/falco cargo build --release Render a local HTML file to PNG ./target/release/falco page.html --out page.png --width 1200 Render a URL to PNG ./target/release/falco https://example.com --out example.png --width 800 Open interactive live window desktop only — scrolls, hover, link clicks ./target/release/falco page.html --window Render with external CSS merged on top of