Two months in Servo: CSS nesting, Shadow DOM, Clipboard API, and more!

Try our new about:memory page and --enable-experimental-web-platform-features.

Posted 2025-05-09

Before we start, let’s address the elephant in the room. Last month, we proposed that we would change our AI contributions policy to allow the use of AI tools in some situations, including GitHub Copilot for code. The feedback we received from the community was overwhelmingly clear, and we’ve listened. We will keep the AI contributions ban in place, and any future proposals regarding this policy will be discussed together, as a community.

At the same time, we have other big news! Complex sites such as Gmail and Google Chat are now usable in Servo, with some caveats. This milestone is only possible through the continued hard work of many Servo contributors across the engine, and we’re thankful for all of the efforts to reach this point.

Google Chat rendering in Servo
Gmail rendering in Servo

Servo now supports single-valued <select> elements (@simonwuelker, #35684, #36677), disabling stylesheets with <link disabled> (@Loirooriol, #36446), and the Refresh header in HTTP responses and <meta> (@sebsebmc, #36393), plus several new CSS features:

We’ve also landed a bunch of new web API features:

servoshell showing new support for ‘image-set()’, ‘fit-content()’, ‘scale’, ‘translate’, ‘rotate’, ‘setLineDash()’, caret and text selection in <input>, and single-valued <select>

The biggest engine improvements we’ve made recently were in Shadow DOM (+70.0pp to 77.9%), the Trusted Types API (+57.8pp to 57.8%), Content Security Policy (+54.0pp to 54.8%), the Streams API (+31.9pp to 68.1%), and CSS Text (+20.4pp to 57.6%).

We’ve enabled Shadow DOM by default after significantly improving support, allowing Servo to render sites like wpt.fyi correctly (@simonwuelker, @longvatron111, @elomscansio, @jdm, @sakupi01, #35923, #35899, #35930, #36104, #34964, #36024, #36106, #36173, #36010, #35769, #36230, #36620).

wpt.fyi rendering in Servo

ReadableStream, WritableStream, DOMPoint, DOMPointReadOnly, and DOMException can now be sent over postMessage() and structuredClone() (@gterzian, @kkoyung, @jdm, @mrobinson, #36181, #36588, #36535, #35989).

We’ve started working on support for stream transforms (@Taym95, #36470) and the trusted types API (@TimvdLippe, @jdm, #36354, #36355, #36422, #36454, #36409, #36363, #36511, #36596). We’ve also laid the groundwork for supporting the ::marker pseudo element (@mrobinson, #36202), animated images in web content (@rayguo17, #36058, #36141), and getClientRects() and getBoundingClientRect() on Range (@simonwuelker, #35993).

Servo can now render the caret and text selection in input fields (@dklassic, @webbeef, #35830, #36478), and we’ve landed a few fixes to radio buttons (@elomscansio, #36252, #36431), file inputs (@sebsebmc, #36458), and input validation (@MDCODE247, #36236).

Having disabled by default Servo’s original, experimental layout implementation back in November 2024, we’ve now taken the step of deleting all of the disabled code (@Loirooriol, @TimvdLippe, @mrobinson, #35943, #36281, #36698) and moving all of the remaining layout code to layout (@mrobinson, #36613). Our new layout engine is improving significantly month over month!

We’ve added a new --enable-experimental-web-platform-features option that enables all engine features, even those that may not be stable or complete. This works much like Chromium’s option with the same name, and it can be useful when a page is not functioning correctly, since it may allow the page to make further progress. Servo now uses this option when running the Web Platform Tests (@Loirooriol, #36335, #36519, #36348, #36475), and the features enabled by this option are expected to change over time.

Servo-the-browser (servoshell)

Our devtools integration now supports iframes (@simonwuelker, #35874) and color scheme simulation (@uthmaniv, #36253, #36168, #36297), shows computed display values when inspecting elements (@stephenmuss, #35870), and supports multiple tabs open in the servoshell browser (@atbrakhi, #35884). We’ve also landed the beginnings of a Sources panel (@delan, @atbrakhi, #36164, #35971, #36631, #36632, #36667). To use devtools, we now require Firefox 133 or newer (@atbrakhi, #35792).

Dialogs support keyboard interaction to close and cancel them (@chickenleaf, #35673), and the URL bar accepts any domain-like input (@kafji, #35756). We’ve also enabled sRGB colorspaces on macOS for better colour fidelity (@IsaacMarovitz, #35683). Using the --userscripts option without providing a path defaults to resources/user-agent-js. Finally, we’ve renamed the OpenHarmony app bundle (@jschwe, #35790).

Servo-the-engine (embedding)

We’ve landed some big changes to our webview API:

Embedders can now inject userscript sources into all webviews (@Legend-Master, #35388). Links can be opened in a new tab by pressing the Ctrl or modifier (@webbeef, @mrobinson, #35017). Delegates will receive send error notifications for requests (@delan, #35668), and we made progress towards a per-webview renderer model (@mrobinson, @delan, #35701, #35716).

We fixed a bug causing flickering cursors (@DevGev, #35934), and now create the config directory if it does not exist (@yezhizhen, #35761). We also fixed a number of bugs in the WebDriver server related to clicking on elements, opening and closing windows, and returning references to exotic objects (@jdm, #35737).

Under the hood

We’ve finally finished splitting up our massive script crate (@jdm, #35988, #35987, #36107, #36216, #36220, #36095, #36323), which should cut incremental build times for that crate by 60%. This is something we’ve wanted to do for over eleven years (@kmcallister, #1799)!

webgpu rebuilds are now faster as well, with changes to that crate no longer requiring a script rebuild (@mrobinson, #36332, #36320).

Stylo has been upgraded to 2025-03-15 (@nicoburns, @Loirooriol, #35782, #35925, #35990), and we upgraded to the 2024 Rust edition (@simonwuelker, #35755).

We added a memory usage view for Servo embedders: visit about:memory for a breakdown of identified allocations (@webbeef, @jdm, #35728, #36557, #36558, #36556, #36581, #36553, #36664).

about:memory screenshot

Perf and stability

We’ve started building an incremental layout system in Servo (@mrobinson, @Loirooriol, #36404, #36448, #36447, #36513), with a huge speedup to offsetWidth, offsetHeight, offsetLeft, offsetTop, and offsetParent layout queries (@mrobinson, @Loirooriol, #36583, #36629, #36681, #36663). Incremental layout will allow Servo to respond to page updates and layout queries without repeating layout work, which is critical on today’s highly dynamic web.

OffscreenRenderingContext is no longer double buffered, which can improve rendering performance in embeddings that rely on it. We also removed a source of canvas rendering latency (@sagudev, #35719), and fixed performance cliffs related to the Shadow DOM (@simonwuelker, #35802, #35725). We improved layout performance by reducing allocations (@jschwe, #35781) and caching layout results (@Loirooriol, @mrobinson, #36082), and reduced the latency of touch events when they are non-cancelable (@kongbai1996, #35785).

We also fixed crashes involving touch events (@kongbai1996, @jschwe, #35763, #36531, #36229), service workers (@jdm, #36256), WritableStream (@Taym95, #36566), Location (@jdm, #36494), <canvas> (@tharkum, @simonwuelker, #36569, #36705), <input> (@dklassic, #36461), <iframe> (@leftmostcat, #35742), ‘min-content’ and ‘max-content’ (@Loirooriol, #36518, #36571), flexbox (@mrobinson, #36123), global objects (@jdm, #36491), resizing the viewport (@sebsebmc, #35967), and --pref shell_background_color_rgba (@boluochoufeng, #35865). Additionally, we removed undefined behaviour from the Rust bindings to the SpiderMonkey engine (@gmorenz, #35892, #36160, #36161, #36158).

The project to decrease the risk of intermittent GC-related crashes continues to make progress (@jdm, @Arya-A-Nair, @Dericko681, @yerke, #35753, #36014, #36043, #36156, #36116, #36180, #36111, #36375, #36371, #36395, #36392, #36464, #36504, #36495, #36492).

More changes

Our flexbox implementation supports min/max keyword sizes for both cross and main axes (@Loirooriol, #35860, #35961), as well as keyword sizes for non-replaced content (@Loirooriol, #35826) and min and max sizing properties (@Loirooriol, #36015). As a result, we now have full support for size keywords in flexbox!

We made lots of progress on web API features:

On security and networking:

On the DOM:

And on many other bugs:

Donations

Thanks again for your generous support! We are now receiving 4664 USD/month (+6.8% over February) in recurring donations. This helps cover the cost of our self-hosted CI runners and our latest Outreachy interns, Usman Baba Yahaya (@uthmaniv) and Jerens Lensun (@jerensl)!

Servo is also on thanks.dev, and already 24 GitHub users (+3 over February) that depend on Servo are sponsoring us there. If you use Servo libraries like url, html5ever, selectors, or cssparser, signing up for thanks.dev could be a good way for you (or your employer) to give back to the community.

4664 USD/month
10000

As always, use of these funds will be decided transparently in the Technical Steering Committee. For more details, head to our Sponsorship page.

Conference talks

Josh Matthews (@jdm) will be speaking about Servo at RustWeek 2025, on Tuesday 13 May at 17:05 local time (15:05 UTC). See you there!

Back