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.


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:
- the & selector for CSS nesting (@Loirooriol, #36246, #36254, #36248, #36249)
- ‘scale’, ‘rotate’, and ‘translate’ (@chocolate-pie, @Loirooriol, #35926)
- ‘will-change’ (@yezhizhen, #35787)
- the ‘fit-content()’ sizing function (@Loirooriol, #36056)
- the ‘image-set()’ notation (@chocolate-pie, #36210)
We’ve also landed a bunch of new web API features:
- the Response.json() static method (@sebsebmc, #36589, #36523)
- the CSSStyleSheet() constructor (@Loirooriol, #36521)
- the seekable property on HTMLMediaElement (@rayguo17, #36541)
- the label property on HTMLOptGroupElement (@simonwuelker, #35970)
- the align property on HTMLParagraphElement (@stephenmuss, #36054)
- ClipboardItem and navigator.clipboard.writeText() (@Gae24, #36336, #36498)
- addRule(), removeRules(), replaceSync(), and the rules property on CSSStyleSheet (@Loirooriol, @webbeef, #36313, #36586)
- getLineDash(), setLineDash(), and lineDashOffset on CanvasRenderingContext2D (@stevennovaryo, #36257)
- ReadableByteStreamController and pipeTo() on ReadableStream (@Taym95, @gterzian, #35410, #35650)

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).

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:
- pinch zoom, page zoom, and HiDPI scaling are now handled independently for each webview (@mrobinson, @shubhamg13, #36419, #36312)
- mouse click events no longer need to be generated by the embedder, only mouse button down and up events (@yezhizhen, #36413)
- webviews are now created with WebViewBuilder (@mrobinson, #36483)
- EmbedderMethods is now ServoBuilder (@mrobinson, #36276, #36549)
- WindowMethods have moved to WebViewDelegate and ServoDelegate (@mrobinson, #36223, #36400)
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).

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:
- added partial support for IntersectionObserver (@stevennovaryo, #35551)
- initial work on implementing the URLPattern API (@simonwuelker, #36144)
- history.replaceState() can be called from file:// documents (@kkoyung, #35864)
- members of radio input groups apply validity constraints more consistently (@jerensl, @elomscansio, @Barry-dE, #36197, #36090, #36103)
- file inputs show the selected file (@dklassic, #35789)
On security and networking:
- the
nonce
attribute is used in Content Security Policy checks (@simonwuelker, #35876) - Request objects with FormData bodies use the correct Content-Type (@andreubotella, #36194)
- text response bodies containing a BOM consume it (@andreubotella, #36192)
- notifications fetch associated image resources (@pewsheen, #35878)
On the DOM:
- passive event listeners can be created (@shanehandley, #35877)
- removing an event listener that has not run prevents it from running (@tharkum, #36163)
- we removed some cases where custom element callbacks fired incorrectly (@xiaochengh, #35960, #35883)
touchmove
events are more reliable (@kongbai1996, #36218 #36200) and support thecancelable
property (@kongbai1996, #35713)- ResizeObserver callbacks are only invoked when elements change size (@simonwuelker, #36226)
- cancelled enqueued animation frame callbacks no longer run (@xiaochengh, #35849)
- scripts are no longer executed in documents that should disable scripting (@simonwuelker, #35871)
- script elements adopted between documents use the original document to determine when to execute (@xiaochengh, #35718)
And on many other bugs:
- Backspace no longer removes entire lines in <textarea> (@elomscansio, @jdm, #36112)
- improved overflow handling in some special cases (@yezhizhen, #35670)
- fixed incorrect fallback font caching (@mrobinson, #35705)
- fixed the intrinsic block size of replaced elements with auto width (@Loirooriol, #35275)
- ‘table-layout: fixed’ is no longer ignored when ‘inline-size’ is ‘auto’ (@Loirooriol, #35882)
- margins of block-level box stretches are always zero, regardless of collapsing status (@Loirooriol, #35904)
- indefinite stretch contributes to intrinsic sizes (@Loirooriol, #36030)
- static positions include ancestor padding (@Loirooriol, #36051)
- table rows with a span of >1 are sized appropriately (@PotatoCP, #36064)
- input element contents ignore any outer display value (@PotatoCP, #35908)
- indexing properties with values near 2^32 resolves correctly (@reesmichael1, #36136)
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.
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!