Servo 0.1: Embeddable Engine on crates.io
Servo 0.1: Embeddable Engine on crates.io
Thesis
On 2026-04-13 the Servo project published servo 0.1.0 on crates.io — the first release of the engine as a library, not only as the servoshell demo browser. The 0.1 version number is deliberate: the team has not defined what 1.0 means yet, but the bump signals growing confidence that the embedding API is usable for real embedders. Monthly crates keep moving (by late 2026 the crate line includes 0.7.x regular releases plus a parallel 0.1.x LTS line). This chapter teaches the mental model of embedding Servo: what the crate is for, what 0.1 vs LTS vs monthly means, and which build/feature knobs matter — without downloading the engine’s enormous dependency graph in the book lab.
Toolchain note: examples assume a recent stable Rust. This authoring host has rustc 1.99.0. Current servo releases advertise MSRV 1.88.0 (see crates.io); LTS migration notes may raise clang and Rust floors when you jump major LTS lines.
Mental model
Your application (windowing, input, IPC, privileges)
│
│ embedding API (servo crate + embedder traits)
▼
┌─────────────────────────────────────────────────────┐
│ Servo library │
│ constellation · script · layout · paint · net · … │
│ optional: webgl / webgpu / webxr / media-gstreamer │
└─────────────────────────────────────────────────────┘
│
▼
OS graphics / audio / network backends (surfman, etc.)
| Concept | Meaning |
|---|---|
servo crate |
The embeddable engine on crates.io (MPL-2.0) |
servoshell |
Demo browser — not published to crates.io; build from the GitHub tree |
| 0.1.0 milestone | First library release; embedding API “good enough for some users,” not a stability covenant |
| Monthly / regular line | Fast-moving; breaking changes expected between minors |
| LTS line | Best-effort ~6-month cadence, ~9-month support, security fixes only; may need git deps for CVE backports |
servo-embedder-traits |
Hooks embedders implement (e.g. custom resource readers) |
baked-in-resources / bundled |
Default path that embeds default resources in the binary; disable and supply your own reader if you need that |
Risk profile (from the Servo book): rendering known, trusted content inside your app is a different threat model from a general-purpose browser that loads the open web. Evaluate accordingly — Servo is still pre-1.0.
Worked examples
Case 1: Read the milestone announcement, then pin deliberately
The 0.1.0 blog post is the historical milestone. For new work in late 2026 you typically choose:
| Goal | Pinning strategy |
|---|---|
| Track features / file upstream bugs easily | Latest regular release on crates.io (e.g. 0.7.x) |
| Ship a product with scheduled upgrades | Current LTS (see LTS release in the Servo book) |
| Reproduce a 0.1-era tutorial | servo = "=0.1.0" (expect migration work later) |
# Cargo.toml — illustrative pins (check crates.io before locking)
[dependencies]
# Regular line (example version as of 2026-10; bump intentionally):
servo = "0.7"
# Or an LTS / milestone pin when you need a slower moving API:
# servo = "=0.1.4"Do not treat 0.1 as “more stable than 0.7” merely because the number is smaller — on crates.io, 0.1.x after the LTS decision is the long-term branch family, while 0.2–0.7 are the regular train. Read the Servo book’s LTS page before you pick.
Case 2: Embedding API shape (no full build in this chapter)
Documentation for embedding lives under The Servo Book → Embedding. The stable ideas:
- Depend on the
servolibrary crate (not servoshell). - Drive the engine from your event loop: create a
Servo/ builder, feed input, composite frames into your windowing stack. - Decide resources: keep default
bundled/baked-in-resources, or disable default features and callservo_embedder_traits::submit_resource_readerwith your ownResourceReader(OpenHarmony’s filesystem reader is the cited pattern upstream). - Select feature flags deliberately. Modularization moved many web features behind flags; LTS migration notes recommend considering
default_web_featureswhen you want the broad web surface.
// embed_sketch.rs — API orientation only (will not compile without the servo crate
// and platform deps). Do not cargo-add servo in the book lab: the dependency
// tree and system libraries (e.g. gstreamer for media) are large.
//
// use servo::ServoBuilder; // names evolve — follow the book for your pin
//
// fn main() {
// let mut servo = ServoBuilder::new(/* embedder handles */)
// // .prefs(...)
// .build();
// // pump events → servo.handle_events(...) → present frames
// }
fn main() {
println!("See https://book.servo.org/embedding/overview.html for current builders");
}$ rustc --version
rustc 1.99.0 (b940084d7 2026-09-28)
$ rustc embed_sketch.rs -o /tmp/embed_sketch && /tmp/embed_sketch
See https://book.servo.org/embedding/overview.html for current builders
Case 3: Building without ./mach (embedder perspective)
Upstream notes that embedding builds often go through cargo directly, but ./mach normally sets environment variables and enables media-gstreamer by default. If you bypass mach:
- Run
./mach print-envon a Servo checkout when cross-compiling (Android / OpenHarmony) and mirror those variables. - Expect to install platform media/graphics dependencies yourself if you enable gstreamer features.
- Prefer feature flags over “copy servoshell’s Cargo.toml blindly.”
This book chapter does not run cargo add servo or ./mach bootstrap — both pull toolchains and system packages beyond the no-install lab policy. Use the Servo book’s “Building servo without mach” section on a dedicated machine.
Case 4: Migrating off 0.1 LTS (preview)
The Servo book’s “Migrating from 0.1 to 0.6 LTS” list is the boring checklist when you finally jump:
- Enable
default_web_features(or an explicit subset) after modularization. - Re-validate prefs — unknown preference names can panic.
- Update mouse button enums (
Left/Middle/Right→Primary/Auxiliary/Secondary). - Relocate WebXR registry registration as documented for your target version.
- Budget for MSRV and clang bumps on the new LTS.
Read the full list for your target LTS; do not crochet a partial migrate.
The trap
- Publishing or depending on servoshell. The demo browser is not the embeddable product line on crates.io.
- Assuming crates.io LTS patches always exist. Security backports may force
gitdependencies when MSRV blocks a crates.io bump — plan for that in corporate allow-lists. - Leaving default features on “for convenience” on constrained devices. Media, WebGL, WebGPU, and WebXR are heavy; turn on what you need.
- Treating 0.1 as production-complete. The project is explicit: no 1.0 definition yet. Trusted-content widgets ≠ full browser replacement.
- Skipping resource ownership. If you disable baked-in resources and forget a
ResourceReader, startup fails in confusing ways. The OpenHarmony example is the reference pattern.
The boring rule
Depend on the servo library crate, pick regular vs LTS on purpose, keep servoshell out of your Cargo.toml, and follow book.servo.org/embedding for the builder/event-loop API on the version you pinned. Evaluate threat model before you point the engine at untrusted URLs.
Try this
- Open crates.io/crates/servo and list the latest regular version vs the latest
0.1.x. Write one sentence on which you would pin for a shipping app and why. - Read the embedding overview and LTS pages in the Servo book; sketch your app’s event-loop ownership on paper (who owns the window, who calls into Servo).
- On a disposable machine (not this no-install lab), create a hello-embed crate against an LTS pin and run only what the book’s embedding chapter shows — then stop before enabling every feature flag.
- Skim the 0.1→0.6 migration notes and mark which items would touch your sketch.
Sources
- Servo is now available on crates.io (2026-04-13)
- crates.io: servo (version history and features)
- Servo Book — Embedding overview
- Servo Book — LTS releases