Servo is a prototype engine: mach bootstrap, Rust 1.88.0, and two Android NDK versions in one README
GitHub describes it as Servo aims to empower developers with a lightweight, high-performance alternative for embedding web technologies in applications.. The repository metadata lists Rust as its primary language. The metadata lists the MPL-2.0 license. This article stays within the project description and details documented in the GitHub repository README.
At a glance
- What is it?
- Servo is a web browser engine written in Rust that its own README calls a prototype, developed on five 64-bit platforms. What a contributor needs to know is how the build driver differs per shell, why the workspace skips Rust 1.90, and that the Android instructions name one NDK version in an environment variable and a different one in the install command.
- Who is it for?
- Use Servo if you are working on a browser engine itself or embedding web rendering in a Rust application, since the C API under ffi/ and the servoshell port are what the repository actually produces. Do not expect a browser to install for end users, because the README describes a prototype and the build output is a shell plus library bindings.
- Can I use it commercially?
- Yes, with conditions. MPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The Android section names NDK 28 in the variable and 29 in the command
The Android instructions contain an inconsistency worth catching before you spend an evening on it. The environment variable section tells you to set ANDROID_NDK_ROOT to a path ending in a specific NDK build:
sudo $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --install \
"build-tools;36.0.0" \
"emulator" \
"ndk;29.0.14206865" \
"platform-tools" \
"platforms;android-37" \
"system-images;android-37;google_apis;x86_64"The command installs ndk;29.0.14206865. The variable above it is set to $ANDROID_SDK_ROOT/ndk/28.2.13676358/. Follow both literally and the directory you exported does not exist. Which one the build wants is something you find out by reading the build configuration, not from the README.
The rest of the same block narrows the target in two more ways. The system image is x86_64, so on an ARM machine the emulator runs under translation rather than natively. ANDROID_SDK_ROOT can be any directory, and every Android build dependency is installed there, which is convenient and also means your SDK location becomes part of your build environment.
One build driver, three shells, and a flavor flag on OpenHarmony
Every platform ends with the same two steps, and the difference between them is the shell. On macOS and Linux you install curl first, then uv and rustup, restart your shell so cargo is on the path, then run:
curl -LsSf https://astral.sh/uv/install.sh | sh
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
./mach bootstrap
./mach buildOn Windows the same driver is written differently, .\mach bootstrap and .\mach build, and it expects the Visual Studio Installer to have three specific components: a Windows 10/11 SDK of at least 10.0.19041.0, the MSVC v143 x64 and x86 build tools, and C++ ATL for the latest v143 build tools. The repository ships mach, mach.bat and mach.ps1 at the top level, which is why the same command has three spellings.
The OpenHarmony path adds a flag to the same driver: --flavor=<default|harmonyos>, passed to mach build, mach package or mach install. So a scripted build is not portable across these platforms without knowing which shell you are in and whether the flavor argument applies. Build servoshell is what ./mach build produces.
The workspace pins Rust 1.88.0 and skips 1.90 on purpose
Cargo.toml sets rust-version = "1.88.0" for the workspace and edition 2024, and the comment above that line reads Skip 1.90 which causes mis-compilation, with a link to a rust-lang issue. That is a specific, reproducible reason for a version ceiling that has nothing to do with the code in this repository, and it means a toolchain update on your side can break a build that was green yesterday.
There are two version knobs and they are governed differently. The minimum is the one in Cargo.toml, and the comment above it describes the policy: before increasing it, open a discussion on Zulip explaining why, because the project has yet to decide on a policy for updating the minimum supported Rust version. The default toolchain is separate, in rust-toolchain.toml, and the same comment says that one may be bumped freely. So contributors can move to a new compiler without discussion, and users cannot move the floor without one.
The workspace itself is a slice rather than the whole tree. Members are components/media/examples, components/xpath, ffi/capi, ports/servoshell, tests/capi and tests/unit/*, with default-members set to ports/servoshell, and .cargo and support/crown excluded. A plain cargo build at the root builds the shell, not every component in the repository.
The Python layer is version 0.0.1 tooling with dependencies in four files
There is a pyproject.toml in a Rust project, and reading it explains why: the name is servo, the version is 0.0.1, and requires-python is >=3.11. The dependencies are declared dynamic, pulled from four separate files: python/requirements.txt plus three from the web platform test tooling under tests/wpt/tests/tools, covering the test requirements, wptrunner, and a flake8 requirements file. A comment at the top notes that uv logs warnings if the file does not contain a project table, which is why the table is named servo rather than left as tooling.
The consequence is that the Python side of Servo is build and test tooling rather than engine code, and its 0.0.1 version has no relationship to the engine version of 0.6.0 in Cargo.toml. Anyone reading versions to identify a Servo build has two numbers to disambiguate.
The configuration is thorough for a tooling layer. Ruff runs with a 120 character line length and selects E, W, F and ANN rules, excluding third_party, python/mach, components/net, components/shared and tests. Pyrefly type checking searches python, the wpt test tooling, and the WebIDL parser and codegen directories under components/script_bindings. There is also a uv.lock at the top level, so the Python tooling is at least pinned even though the file that lists its dependencies is spread across four places.
Three release lines in the tag list and only one marked LTS
The recent releases are v0.6.0 tagged as v0.6.0 (LTS) on 2026-09-29, v0.5.0 on 2026-08-31, and v0.1.3 on 2026-08-22. Read the dates and the order looks wrong: 0.1.3 was tagged three weeks after 0.5.0 and a month before 0.6.0. So these are not successive versions of one line, and sorting the tag list by date does not tell you which line a change belongs to.
The signal is the suffix. 0.6.0 carries LTS in its tag name, which marks the line intended to be kept stable, and the workspace version in Cargo.toml matches 0.6.0, so the default build is on that line. The 0.5.0 and 0.1.3 tags are separate tracks, and the repository does not explain in the README what they are for. The repository is not archived and its last push was on 2026-09-27, one day before the 0.6.0 tag.
For anyone tracking Servo, the practical rule is to pick a line by the LTS marker and not by the version number, and to read the changelog for the specific line rather than assuming the highest number is the newest state of the code.
MPL-2.0 for the engine and a second licence file for the specs
The repository carries two licence files at the top level: LICENSE and LICENSE_WHATWG_SPECS. GitHub records the project as MPL-2.0 and Cargo.toml declares license = "MPL-2.0" in the workspace package metadata, so the engine code has one stated licence in three places.
The second file is the one to notice. A separate licence covering WHATWG specifications is not a pattern you see in most application repositories, and it exists because the web standards the engine implements are documents with their own terms, separate from the implementation. Copying a spec file out of this tree and dropping it into your project is therefore not the same act as copying a Rust source file, and the two are governed by different files sitting next to each other.
This is a description of what the files are and where they sit, not advice on how to apply them. The practical point is narrow: when you take material out of this repository, establish which of the two files covers it, and if your compliance process needs a single answer, ask before you vendor anything from the spec side.
Prototype on five 64-bit targets, and the build produces a shell and a C API
The README calls Servo a prototype web browser engine, and that word does a lot of work in the sentence that follows: it is currently developed on 64-bit macOS, 64-bit Linux, 64-bit Windows, 64-bit OpenHarmony, and Android. Every one of those is 64-bit, and the list is a statement about where development happens rather than a support matrix. There is no 32-bit target in it, and the README does not discuss one.
What a build produces is narrower than a browser. The Cargo workspace points default-members at ports/servoshell, which is the shell, and ffi/capi is a workspace member holding a C API. The repository description frames the goal as a lightweight, high-performance alternative for embedding web technologies in applications, which matches that layout: the engine as a set of components under components/, a shell to drive it, and a C interface for embedding it in something else. The alternative to a browser you install is a library you link, and the repository is built for the second case.
The rest of the tree supports that reading. support/ and resources/ sit alongside etc/, docs/, tests/ and python/, and the housekeeping files are unusually specific for a prototype: deny.toml for dependency policy, servo-tidy.toml, taplo.toml for TOML formatting, rustfmt.toml, shell.nix, a .devcontainer directory, a servobuild.example, .python-version and uv.lock. That is a project with real infrastructure behind a small release number.
The README defers build detail to the Servo Book and coordination to Zulip
The README is short by design and it says where the rest is. For detailed build instructions it points to the Servo Book under Getting the Code and Building Servo, and for news and guides to servo.org. What it keeps is the platform matrix, the per-platform dependency lists, and the two commands that matter.
Coordination has three named channels rather than one. Development happens in GitHub Issues, on the Servo Zulip, and in video calls advertised in the Servo Project repository. The third is unusual and it matters for a project of this kind: the calls are where design decisions get made, and the repository that advertises them is servo/project rather than servo/servo.
What the README does not carry is a picture of the current state. There is no compatibility table, no statement of which web platform tests pass, no list of what changed in a release, and no description of what a prototype engine is not yet able to do. For an engine, those are the questions that decide whether you can use it, and all of them are answered elsewhere or not at all. Read the Book for the build, and read the release notes for the line you are pinning, because the README will not tell you what the browser can currently do.
Editorial conclusion
Use Servo if you are working on a browser engine itself or embedding web rendering in a Rust application, since the C API under ffi/ and the servoshell port are what the repository actually produces. Do not expect a browser to install for end users, because the README describes a prototype and the build output is a shell plus library bindings. Verify first by reading the two Android NDK references side by side, since the environment variable and the sdkmanager command name different versions, and by confirming your Rust toolchain is at least 1.88.0 and not 1.90.
Frequently asked questions
How do I build Servo from source?
On macOS and Linux you install curl, then uv and rustup, restart your shell so cargo is available, then run ./mach bootstrap followed by ./mach build, which builds servoshell. On Windows the same driver is invoked as .\mach bootstrap and .\mach build, and the Visual Studio Installer needs a Windows 10/11 SDK of at least 10.0.19041.0, the MSVC v143 x64 and x86 build tools, and C++ ATL for the latest v143 build tools.
What platforms is the Servo browser engine developed on?
The README lists 64-bit macOS, 64-bit Linux, 64-bit Windows, 64-bit OpenHarmony and Android, and describes it as a list of where development currently happens. The OpenHarmony instructions add DEVECO_SDK_HOME, OHOS_BASE_SDK_HOME, OHOS_SDK_NATIVE and SERVO_OHOS_SIGNING_CONFIG, plus a --flavor=<default|harmonyos> flag for mach build, mach package and mach install.
What is the minimum Rust version Servo needs?
Cargo.toml sets rust-version = "1.88.0" with edition 2024, and a comment in the file says to skip 1.90 because it causes mis-compilation, linking a rust-lang issue. The comment also states that raising the minimum requires a Zulip discussion first, while the default toolchain in rust-toolchain.toml may be bumped freely.
What licence is Servo released under?
The engine is MPL-2.0: GitHub records that licence, Cargo.toml declares license = "MPL-2.0" in the workspace package metadata, and LICENSE sits at the top level. The tree also carries LICENSE_WHATWG_SPECS, a separate file covering the specifications.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/servo-servo)