Open-source project
servo/webrender avatar
servo/webrender

servo/webrender: the GPU renderer behind Firefox and Servo, and how to build against it

A GPU-based renderer for the web

3,374 stars327 forksRustMPL-2.0

At a glance

What is it?
WebRender is a Rust 2D rendering engine that draws through OpenGL and ships as the graphics layer of Firefox and Servo. This review covers what it does, how the workspace is laid out, and where the GitHub mirror stops being the right place to send a patch.
Who is it for?
Adopt WebRender if you are building a browser engine, a compositor, or a GUI toolkit that needs a scene-graph renderer over OpenGL and you can absorb a large Rust dependency with a moving API. Do not adopt it if you want a stable drawing library with a versioned surface, or if your target is a platform where OpenGL is not the path you ship on.
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 3 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

What WebRender replaces, and who the README is written for

WebRender is a GPU-based 2D rendering engine written in Rust. Firefox, the Servo research browser, and unnamed other GUI frameworks draw with it, and it currently uses the OpenGL API internally. That single sentence in the README defines both the audience and the constraint. The audience is people building a rendering stack: a browser, a compositor, a toolkit. The constraint is that the drawing model is tuned for web content, where a page becomes a tree of display items that get batched and rasterised on the GPU rather than painted into a CPU surface.

The README is not written for an application developer who wants to draw a chart. It opens with a note about upstream homes, contribution workflow, and Bugzilla, then moves to dependency updates and patch overrides. That ordering tells you who the document expects: someone already inside the Gecko or Servo tree, not someone evaluating a library for a side project. If you are in the second group, the repository will feel like it is addressed to somebody else, because it is.

The workspace split: webrender, webrender_api, wrench and swgl

The top-level Cargo.toml is a workspace with five members: examples, webrender, webrender_api, wrench, and example-compositor/compositor. That split is the architecture in miniature. webrender holds the renderer itself. webrender_api is the crate consumers depend on for the types and messages they send across, which is why the README's local-override snippet patches both crates together rather than just one. wrench is a tooling crate. The examples workspace is what you build when you want to see the engine draw something without embedding a browser.

Several other directories sit outside the workspace member list: glsl-to-cxx, peek-poke, swgl, wr_glyph_rasterizer, wr_malloc_size_of, and fog. The names describe their jobs. glsl-to-cxx translates shader source into C++ and swgl is a software rendering path, which matters because the README states that tests run using OSMesa to get consistent rendering across platforms. peek-poke and wr_malloc_size_of are support crates for serialisation and allocation accounting. The workspace Cargo.toml also patches crates.io: firefox-on-glean points at the local fog directory, and glutin is pinned to a git branch described in the file as a patched version that works on android. That pin is a real maintenance cost, not a detail you can ignore when you vendor this tree.

Building the examples and a first run

The README does not give an install command. There is no cargo install line, no published binary, and the crates.io badge points at the webrender crate rather than a CLI. What the repository does give you is a workspace with an examples member, and the examples directory contains the runnable programs: basic.rs, animation.rs, blob.rs, document.rs, iframe.rs, image_resize.rs, multiwindow.rs, scrolling.rs, texture_cache_stress.rs, and yuv.rs, among others. The README does not spell out a build or run command, so there is no command to quote here; the example file names are the entry points, and the workspace is what you compile.

Because the renderer uses OpenGL internally, expect an example to open a window and draw through the platform GL stack. The README warns that tests run under OSMesa for consistent rendering across platforms, and that differences can still appear depending on font libraries on your system. That warning applies to the examples too: text output is the part most likely to differ from machine to machine, which is why the README links a gist about making text tests useful on Fedora specifically.

Using a local WebRender with Servo

The one concrete integration recipe in the README is for pointing a Servo build at a local checkout. You edit Servo's Cargo.toml and append a patch section naming both crates.

toml
[patch."https://github.com/servo/webrender"]
"webrender" = { path = "<path>/webrender" }
"webrender_api" = { path = "<path>/webrender_api" }

Replace <path> with the path to your local copy, then build as normal. Both entries are needed because the API crate is the boundary consumers compile against; patching only the renderer leaves the two halves out of sync. The README also documents the reverse direction for dependency bumps: after updating shaders in WebRender, go to the servo directory and run ./mach update-cargo -p webrender, then open a pull request to servo. That is a two-repository workflow, and it is the clearest signal that this is not a drop-in library.

The upstream mirror split is the biggest practical limitation

The README states plainly that the upstream home for this code is the gfx/wr folder of mozilla-central at hg.mozilla.org, and that the GitHub repository at github.com/servo/webrender should be considered a downstream mirror, though it carries extra metadata such as wiki pages that do not exist in mozilla-central. It then says improvements should generally be submitted upstream in Gecko, while changes relevant to Servo or unsuitable for upstream may be accepted here.

That is a governance boundary, and it decides where your time goes. A fix that benefits Gecko will be reviewed through Bugzilla, with the README pointing at the Core :: Graphics: WebRender component. A patch opened only on GitHub may be the wrong venue even if the code is correct. The mirror also means the GitHub history is not the authoritative one, so if you are pinning a revision for a downstream product, you need to know which of the two trees you are pinning. Nothing in the README describes a rollback path or a release cadence for the mirror, and the only release listed in the repository metadata is a rustc-perf entry from 2022, which tells you little about how this code is versioned for consumers.

How this differs from a CPU rasteriser or a compositor library

The obvious alternative for a Rust project that needs to draw is a CPU-side 2D library, or a compositor crate that hands you surfaces and lets you decide how to paint them. The difference is where the work happens and what you have to bring. A CPU rasteriser gives you predictable output and no GPU driver dependency, which is exactly why WebRender keeps a software path in swgl and why its tests run under OSMesa: the project itself needs a deterministic reference when the GPU is not the point. If your output must be byte-identical across machines, a CPU path is the simpler contract.

A compositor library differs in the other direction. It typically gives you layers and lets you position them, leaving the drawing of content to you. WebRender takes a scene description through webrender_api and owns batching, rasterisation, and the GL calls. You get less control over the pipeline and more of the pipeline handled for you. That trade is only worth taking if your content looks like web content, because the batching decisions are built around that shape.

Licence and the cost of tracking this tree

The repository is under MPL-2.0, a file-level copyleft licence, which is a different obligation from a permissive licence if you modify WebRender source files and distribute the result. This is not legal advice; read the licence text and your own counsel's reading of it before you vendor the tree into a shipped product.

The upgrade cost is the part engineers underestimate. The workspace pins glean at exactly =61.0.0, patches firefox-on-glean to a local fog path, and pulls glutin from a personal git branch for Android support. Those pins exist because this code lives inside a larger product, and they mean a downstream consumer cannot simply take the newest crates.io versions of everything and expect the tree to resolve. The last push to this repository was on 2026-09-20, so the mirror is receiving changes, but the README's own direction is that upstream work happens in Gecko first. Budget for reading two trees, not one.

Editorial conclusion

Adopt WebRender if you are building a browser engine, a compositor, or a GUI toolkit that needs a scene-graph renderer over OpenGL and you can absorb a large Rust dependency with a moving API. Do not adopt it if you want a stable drawing library with a versioned surface, or if your target is a platform where OpenGL is not the path you ship on. Before you write any code, read the README note that mozilla-central is the upstream home and this GitHub repository is a downstream mirror, then confirm where the change you need actually belongs.

Frequently asked questions

What is Firefox WebRender?

It is the GPU-based 2D rendering engine written in Rust that Firefox draws with, according to the README. The same engine is used by the Servo research browser and by other GUI frameworks, and it currently uses the OpenGL API internally.

What is gfx webrender compositor?

The README does not use the phrase compositor for WebRender itself. It does list example-compositor/compositor as a workspace member, so a compositor example ships alongside the renderer in this repository.

Where is the upstream home of servo/webrender?

The README states that the upstream home is the gfx/wr folder of mozilla-central at hg.mozilla.org, and that the GitHub repository at github.com/servo/webrender is a downstream mirror. The mirror carries extra metadata such as wiki pages that do not exist in mozilla-central.

How do I use a local copy of WebRender with Servo?

Edit Servo's Cargo.toml and append a patch section mapping both webrender and webrender_api to local paths, then build as normal. The README shows the exact patch block with a <path> placeholder.

How do I run the WebRender examples?

The examples live in the examples workspace member, with files such as basic.rs, animation.rs and blob.rs. The README does not document a run command, but the example files are the entry points in the workspace.

What licence does servo/webrender use?

The repository is under MPL-2.0, a file-level copyleft licence. That places different obligations on you than a permissive licence if you modify source files and distribute the result.

Official sources

  1. License: MPL-2.0
  2. Project website
  3. README
  4. Releases
  5. servo/webrender on GitHub
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/servo-webrender.svg)](https://hysenlabs.com/projects/servo-webrender)