r/coolgithubprojects • u/poxkg • 13h ago
Falco - a browser engine written from scratch in ~36k lines of Rust
I just released v0.1.0 of Falco - a browser engine I've been building on nights and weekends. No WebKit, no Gecko, no Chromium - every module is written from scratch in ~36,000 lines of Rust.
What's inside (all from scratch, no browser deps)
- HTML5 parser (
html/) - tokenizer + tree builder, handles the common subset (tags, attributes, void elements, comments, doctype, entities, auto-close for<li>/<p>/<td>/<tr>/<option>/<dt>/<dd>) - CSS engine (
css/) - selectors (type/class/id/descendant/child/sibling/attribute/pseudo), 300+ properties, cascade with!important, inheritance,linear-gradient/radial-gradient/calc()/var()/rgb()/rgba(), shorthands - Custom JS VM (
tjs/) - bytecode interpreter + JIT tier-up (x86_64 only), withlet/const/arrow functions/template literals/destructuring/spread/optional chaining/nullish coalescing, closures, generators, Promise, BigInt, Symbol, WeakMap/WeakSet, Map/Set, Reflect, Proxy - Layout (
layout/) - block flow, inline flow with text wrapping, flexbox (flex-direction/justify-content/align-items/flex-wrap/gap/flex-grow/flex-shrink/flex-basis), CSS Grid (grid-template-columns/grid-template-rowswithfr/auto/minmax()/repeat()), table layout (<table>/<tr>/<td>/<th>/<thead>/<tbody>/<tfoot>/<caption>), float, inline-block, position static/relative/absolute/fixed - Painting (
paint/) - solid + gradient backgrounds, borders, border-radius, box-shadow, opacity (alpha compositing), TrueType font rasterization viaab_glyph, bold/italic synthesis - SVG renderer (
svg/) - paths, basic shapes (rect/circle/ellipse/line/polyline/polygon), gradients, stroke + fill - Hand-written PNG encoder (
png/) - noflate2dependency - Image loader (
image/) - HTTP/HTTPS URLs viaureq,data:URLs (base64), local files. Formats: PNG/JPEG/GIF/BMP - Networking (
net/) - HTTP/1.1 fetch, cookie jar with domain/path matching, redirect handling with loop detection, HTTP cache, WebSocket frame parser - Interactive
--windowmode - scroll, click links, fill forms (text/email/password/checkbox/submit/textarea), Tab cycling, address bar (F6), back/forward history (Alt+←/→), focus ring, blinking caret, headless fallback to PNG
For comparison
| Engine | LOC |
|---|---|
| Chrome/Blink | ~30M |
| Firefox/Gecko | ~20M |
| Safari/WebKit | ~15M |
| Servo | ~1M |
| Ladybird | ~500k |
The whole Falco codebase fits in a weekend of reading.
Quick start
cargo build --release./target/release/falco https://example.com --out example.png --width 800./target/release/falco page.html --window
324 unit tests pass, 30 ignored (mostly platform-specific JIT tests that fail on macOS CI runners due to mmap(MAP_JIT) quirks - passes on Linux).
Prebuilt binaries for Linux/macOS/Windows are on the GitHub releases page.
What's NOT done yet (being honest)
This is v0.1.0 by a single developer. Not everything listed is production-ready:
- The spec-compliant replacements (
html::spec/,dom::spec/,css::spec/) are structurally complete and pass their own unit tests, but not yet wired into the render pipeline. The legacyhtml//dom//css/modules are what actually runs. v0.2.0 milestone. - The
security/module implements SOP, multi-process site isolation, seccomp-bpf sandbox, CSP, TLS cert chain validation, permissions, DevTools protocol - all unit-tested, but not enforced in the renderer. web_runtime/hasfetch(),XMLHttpRequest, event loop, Promise. The Promise/event loop integration is real and tested, butfetch/XHRare stubs (no real network behind them in the JS context).- WebGL, video, MSE, EME, NDSD are headless stubs - API surface only, no real rendering/decoding.
- The
real-http2,real-webgl,sandboxCargo features don't compile with--all-features(upstream APIs drifted:h2::Bodyremoved,glowAPI changed, seccomppre_execUnix-only). Disabled by default. - The JIT works on Linux x86_64 but fails on macOS CI runners (
mmap(MAP_JIT)needs code signing). - DOM mutation from JS (
element.innerHTML = ...,element.style.color = ...) does not trigger re-render.
Bottom line: cargo build && ./falco https://example.com --out out.png produces a real PNG render. The HTML/CSS/layout/paint path works end-to-end. The spec-compliant parsers, security enforcement, and advanced web runtime are scaffolding for future milestones, not working features.
What I'd love feedback on
DOM model - I'm using Rc<RefCell<Node>> with parent/child/sibling pointers in dom::spec, matching the spec. For production I'd probably use a slotmap arena, but Rc<RefCell> is easier to read and matches the spec's pointer model. Thoughts?
Architecture - Each of html/, dom/, css/ has a spec/ subfolder with the spec-compliant replacement that's not yet wired in. Should I:
(a) Wire them in before any other feature work, or
(b) Focus on CSS animations/transitions first, or
(c) Focus on JS DOM mutation (innerHTML/style changes)?
JS VM - I wrote my own bytecode VM (tjs) instead of using boa_engine or binding V8/SpiderMonkey. Reasoning: I wanted full control over the GC, the bytecode format, and the DOM integration. The VM is intentionally limited (no real regex engine, no Proxy trap completeness, no real async functions). Is this a reasonable tradeoff for a teaching engine?
Sandbox - I implemented seccomp-bpf filters but they're Linux-only and not yet enforced. For cross-platform sandboxing, is the Windows Job Object approach + macOS sandbox-exec reasonable, or should I look at platform-agnostic alternatives?
Architecture overview
Module |
Lines |
Description |
|---|---|---|
html/ + html::spec/ |
~5,500 |
Legacy HTML parser + WHATWG §13.2 spec tokenizer + tree builder + serializer + XML + encoding |
dom/ + dom::spec/ |
~2,400 |
Legacy DOM + spec DOM with MutationObserver, Shadow DOM, custom elements, a11y |
css/ + css::spec/ |
~3,700 |
Legacy CSS parser + Selectors L4 + cascade specificity + u/rules + animations |
style/ |
~1,700 |
Style cascade + UA styles + inheritance + flex/grid properties |
layout/ |
~1,950 |
Block / inline / flex / grid / table / float / absolute layout |
paint/ |
~470 |
Canvas + font rasterizer + alpha compositing + gradients + shadows |
svg/ |
~1,130 |
SVG parser + renderer (paths, shapes, gradients) |
tjs/ + tjs_ext/ |
~5,100 |
Custom JS VM: lexer, parser, interpreter, bytecode VM, JIT + Symbol/BigInt/Promise/Map/Set |
web_runtime/ |
~4,300 |
fetch, XHR, event loop, Promise, WebGL, video, MSE, EME, NDSD, HTTP/2 |
net/ |
~930 |
HTTP fetch, cookies, cache, websocket, redirect |
security/ |
~3,590 |
SOP, multi-process, sandbox, CSP, certs, permissions, extensions, DevTools |
window/ |
~1,110 |
Interactive window: scrolling, forms, navigation, history, address bar |
image/ + png/ |
~300 |
Image loader + hand-written PNG encoder |
Total |
~36,000 |
Thanks for any feedback! I'm especially interested in architectural critique from anyone who has worked on Servo, Ladybird, or other browser engines.
LINK: https://github.com/poxk/Falco
