Engine

Building a Browser Engine in Rust: Where It Stands

Nemo · · 3 min read

Monok is a browser written in Rust, but version 1 does not render pages with a Rust engine. The shell (tabs, panes, Magic Bar, terminal, favorites, blocking, internal pages) is Rust, and it talks to web content through an engine trait; the engine behind that trait in v1 is the system’s WebKit, through WKWebView. A Rust engine of our own was the original plan and is paused. This post maps both: what ships, and what the engine would be made of.

What does v1 look like inside?

Crate What it does in v1
engine-api The engine boundary: traits, events, content rules and a conformance suite
engine-system WKWebView behind those traits; the only WebKit code in the app
shell The chrome: tabs, top bar, favorites, Magic Bar, find bar, the ⋮ menu, browser:// pages, and the AppKit window
panes The per-tab pane tree: splits, focus, resize, zoom
terminal PTY, emulation and drawing for terminal panes
adblock-rules EasyList and EasyPrivacy converted to WebKit content rules, plus the weekly updater
storage Bookmarks, history, settings and the session in one file
update The signed update feed
paint, text Draw the chrome with vello_cpu and lay out its text with parley

The browser’s own interface is not a web page: it is drawn by vello_cpu into native macOS layers, with the main menu, full screen and dialogs left to AppKit. The engine-system crate passes the engine trait’s conformance suite, 12 of 12 checks.

Why an engine trait?

So the engine can change without rewriting the browser. The shell knows nothing about WebKit: it sends navigations and receives events. A second engine, our own or Chromium, would be one more implementation of the same trait. The reasoning behind starting with WebKit is in why v1 runs on WebKit.

What was the own engine going to be?

Step Crate Status
Parse HTML html5ever Early crate in the repository, unused by v1
Style Our own, on cssparser and selectors Early crate, unused by v1
Layout taffy for block, flex and grid; parley for inline text Early crate, unused by v1
Paint vello_cpu In use, for the chrome only
Script rquickjs (QuickJS) Never started

The hard part was always going to be the middle: the style system, and the Web APIs that JavaScript expects. The Web APIs post lists what React and Angular apps call, which is the bar any engine has to clear.

Why Rust for a browser on WebKit?

Memory safety for the parts we write, a small binary, and good crates for text, drawing, terminals and filter lists. The release build of 0.1.0 is 6.83 MB (arm64, stripped) and draws its first frame in 139 to 162 ms on an M5 Pro.

FAQ

Does Monok have its own engine?

Not in v1. Pages are rendered by WebKit through WKWebView. The own engine is paused.

Does Monok use Servo?

No. The paused engine used html5ever, which came out of the Servo project, but never Servo’s engine.

Can I use it today?

Yes. Version 0.1.0 is a download for macOS 14 or later.

More in Engine

Contact

Bug reports, sites you want to see working, ideas. We reply by email.