Servo 0.3.0 contains all of the changes we landed in May, which came out to 391 commits (March: 534). For security fixes, see § Security.
We’ve shipped several new web platform features:
- ‘font-kerning: none’ (@simonwuelker, #44634)
- ‘font-variant-east-asian’ (@simonwuelker, #44989)
- ‘font-variant-ligatures’ (@simonwuelker, #44903)
- ‘font-variant-numeric’ (@simonwuelker, #44950)
- ‘font-variant-position’ (@simonwuelker, #45142)
- mp4 files without fast start in <video> (@calvaris, #45084)
<form enctype="multipart/form-data">(@yezhizhen, #45028)<form enctype="text/plain">(@yezhizhen, #45111)- <![CDATA[]]> layout (@mrobinson, #44791)
Plus a bunch of new DOM APIs:
- onslotchange property on ShadowRoot (@jdm, #44688)
- screenLeft and screenTop on Window (@TG199, #45128)
- new Blob() with
{endings: "native"}(@yezhizhen, #44803) - new PerformanceMark() (@shubhamg13, #44702)
- parseHTML() on Document (@kkoyung, #44952)
- readAsBinaryString() on FileReader (@yezhizhen, #44858, #44921)
- performance.measure() with mark values ‘redirectStart’, ‘redirectEnd’, ‘secureConnectionStart’, and ‘responseEnd’ (@shubhamg13, #44673, #44624, #44850, #44739)
We’ve also fixed some build issues on Windows (@mukilan, #45079), FreeBSD (@delan, @mrobinson, @mukilan, #44600), and for anyone building Servo on NixOS or with Nix (@freyacodes, #45051, #45135).
This is another big update, so here’s an outline:
-
Security
– memory safety fixes -
Work in progress
– execCommand(), Sanitizer, IndexedDB, accessibility, workers -
Embedding API
– MSRV, cookies, preferences, diagnostics -
For users and developers
–--host-file,--userscripts, DevTools Debugger -
More on the web platform
– focus, forms, navigation, SubtleCrypto, WebGPU -
Performance
– about:memory, threads, layout, DOM, build times -
Stability
– crashes, hangs, static analysis
Security
Servo’s JS runtime, SpiderMonkey 140.10.0, had several memory safety bugs that have been fixed in Servo 0.3.0 with the update to SpiderMonkey 140.10.1 (@jschwe, #44755). For more details, see CVE-2026-7322, CVE-2026-7323, and MFSA 2026-36.
Work in progress
We’re continuing to implement document.execCommand() for rich text editing, under --pref dom_exec_command_enabled (@TimvdLippe, #44735, #44973, #44887).
This release adds support for the ‘backColor’, ‘foreColor’, ‘createLink’, ‘unlink’, ‘superscript’, ‘subscript’, and ‘removeFormat’ commands (@TimvdLippe, #44644, #44682, #44657, #44710, #44677), plus partial support for the ‘insertParagraph’ command (@TimvdLippe, #44909).
We’re also working on the Sanitizer API, under --pref dom_sanitizer_enabled.
With the feature now enabled in servoshell’s experimental mode (@kkoyung, #44701), this release adds support for setComments(), setDataAttributes(), allowProcessingInstruction(), removeProcessingInstruction(), and removeUnsafe() on Sanitizer (@kkoyung, #44734, #44983).
IndexedDB continues to improve, under --pref dom_indexeddb_enabled.
This release brings a more conformant abort() on IDBTransaction (@Taym95, #43950).
All of the features above are enabled in servoshell’s experimental mode.
We’ve made more progress towards accessibility support, including the name from contents algorithm (@alice, @delan, @mrobinson, #44439) and several changes towards building the accessibility tree incrementally (@alice, @delan, @mrobinson, #44766, #45035, #45207, #44768, #44785, #44801, #44767, #45029). The latter is critical for performance in real-world web content.
We’re now working on SharedWorker and ServiceWorker, under --pref dom_sharedworker_enabled and --pref dom_serviceworker_enabled respectively.
This release adds support for new SharedWorker() (@Taym95, #44761), and parts of the ServiceWorker API (@gterzian, @arihant2math, #45082, #44787).
Embedding API
Servo now requires Rust 1.88.0 or newer, up from the old MSRV of 1.86.0 (@sagudev, #44815). We run compile tests with the MSRV, but most of our testing is now done with Rust 1.95.0 (@simonwuelker, #44632).
Breaking changes to the cookies methods in our SiteDataManager API (@longvatrong111, #44708):
-
SiteDataManager::clear_cookiesnow takes an additionalcallbackargument, allowing it to be called async – to continue calling it sync, passNoneas thecallback -
SiteDataManager::clear_session_cookiesnow takes an additionalcallbackargument, allowing it to be called async – to continue calling it sync, passNoneas thecallback -
SiteDataManager::set_cookie_for_urlnow takes an additionalcallbackargument, allowing it to be called async – to continue calling it sync, passNoneas thecallback -
SiteDataManager::set_cookie_for_url_asynchas been removed in favour ofset_cookie_for_url– to migrate, replaceset_cookie_for_url_async(callback)withset_cookie_for_url(Some(Box::new(callback)))
Breaking changes to our Preferences API (@Narfinger, @mrobinson, #44307):
-
threadpools_image_cache_workers_max,threadpools_indexeddb_workers_max, andthreadpools_webstorage_workers_maxhave been removed in favour of a combinedthread_pool_workers_max -
threadpools_fallback_worker_numhas been renamed tothread_pool_fallback_workers -
threadpools_async_runtime_workers_maxhas been renamed tothread_pool_async_runtime_workers_max -
threadpools_webrender_workers_maxhas been renamed tothread_pool_webrender_workers_max
We’ve also reworked our DiagnosticsLogging API (@mukilan, #44703):
-
You can now set options with
DiagnosticsLogging::toggle_option, and check if they are enabled withDiagnosticsLogging::is_enabled -
Each option is a variant of
DiagnosticsLoggingOption, a new type that also has useful methods for exposing these options in embedder UI -
(Breaking change)
DiagnosticsLoggingno longer haspubfields representing each option – to migrate, replace field writes and field reads withtoggle_optionandis_enabledrespectively -
(Breaking change)
DiagnosticsLogging::extend_from_stringno longer accepts ahelpoption – this option only existed to support servoshell’s-Z help/--debug=helpoption, so the code implementing it has been moved to servoshell
For users and developers
servoshell has two new options:
-
You can now configure the path to a hosts file with --host-file= (singular), as an alternative to the HOST_FILE (singular) environment variable (@jschwe, #44880).
-
You can now provide a directory of user scripts to run in every document with --userscripts= (@jdm, #44754).
When using the Debugger tab in the Firefox DevTools:
-
You can now “blackbox” a script by clicking Ignore source (@freyacodes, #44359). This prevents breakpoints from being hit inside that script, and it should also allow you to step through execution in the debugger without pausing inside that script.
-
The Scopes panel is more accurate now (@atbrakhi, @eerii, #44765).
For developers of Servo itself, please note that per project policy, you must not use the output of large language models or other generative AI tools in your contributions. To help us enforce that, we now have CI checks that reject AI agents as coauthors (@SimonSapin, @delan, #44723).
We’ve also fixed build issues with --features vello (@Gae24, @yezhizhen, #44875, #45036).
More on the web platform
We’ve improved the default appearance of <dl>, <ol>, <ul>, <table>, <thead>, <tbody>, <tfoot>, <tr>, <td>, <th>, <dir>, <menu>, and <form> (@avis137, #44837, #44920).
CryptoKey is now serializable, allowing it to be used in structuredClone() and postMessage() (@kkoyung, #45163).
We’ve improved JS error messages in several parts of the DOM (@n0blenote, @jdm, @TG199, @PuercoPop, #44704, #45186, #44656).
We’ve improved the conformance of form submission (@yezhizhen, #44943, #44953, #44954, #44957), tab navigation (@mrobinson, #44684), javascript: url navigation (@jdm, @TimvdLippe, #43490), ‘Refresh’ headers and <meta http-equiv=Refresh> (@jschwe, @mrobinson, #45113, #45116), ‘line-break: anywhere’ (@mrobinson, @SimonSapin, #44609), assign() on Location (@TG199, @jdm, #44298), crypto.subtle.deriveBits() (@kkoyung, #44706), getComputedStyle() (@Loirooriol, #44856), performance.measure() (@shubhamg13, #44675), readAsDataURL() on FileReader (@yezhizhen, #44897, #44924), stream() on Blob (@Taym95, #45133), and ML-KEM in SubtleCrypto (@kkoyung, #45153).
We’ve also landed improvements to GPUSupportedLimits (@sagudev, #45114), GPUTexture (@sagudev, #45154), createBindGroup() on GPUDevice (@sagudev, #45140), and other WebGPU features (@sagudev, #45097).
We’ve fixed bugs related to <svg> with ‘Content-Security-Policy’ (@TimvdLippe, @jdm, #44974), ‘:active’ (@SharanRP, @mrobinson, #43953), ‘:hover’ (@SharanRP, @mrobinson, #43979), ‘align-items’ (@yezhizhen, #44396), ‘border-image-outset’ (@lumiscosity, #45039), ‘padding’ with ‘overflow: scroll’ (@stevennovaryo, #44263), ‘pointerup’ events (@mrobinson, #44666), ‘slotchange’ events (@jdm, #44688), dynamic import() (@Gae24, #44741), and clip() on CanvasRenderingContext2D (@yezhizhen, #44831).
Performance
We’ve built a tool that will help us improve ‘about:memory’ by finding untracked allocations (@jdm, @TimvdLippe, @webbeef, #44674, #44980).
Servo now requires fewer OS threads per CPU, after we combined the thread pools for the image cache, web storage, and IndexedDB (@Narfinger, @mrobinson, #44307).
We’ve landed a bunch of layout optimisations:
-
The fragment tree is now immutable for the most part, with small pockets of interior mutability where mutability is needed. This means that most fragment tree accesses no longer have to incur the runtime cost of borrowing an AtomicRefCell (@mrobinson, @Loirooriol, #44849).
-
Two steps in the layout process, calculating containing blocks and building the stacking context tree, require traversing the fragment tree. This can be expensive, but we’ve now combined them into a single fragment tree traversal in most cases (@SimonSapin, @mrobinson, #44911, #45210).
-
Another step in the layout process, calculating scrollable overflow, used to require traversing the entire fragment tree. We’ve effectively eliminated that traversal, by making the calculation both lazy and incremental (@mrobinson, @Loirooriol, #44854).
-
We’ve improved the caching of fragments, shaping results, and other layout results between reflows (@mrobinson, @Loirooriol, @SimonSapin, #45038, #44769).
-
We’ve made incremental fragment layout more precise (@Loirooriol, @mrobinson, #44925).
-
We’ve reduced the memory usage of text shaping (@mrobinson, @SimonSapin, #44609).
DOM attributes are much more efficient in this release:
-
When scripts write attribute values, we avoid serialising them until the attribute is read back by a script (if ever), speeding up frequent writes to inline styles by up to 25% (@mrobinson, #44931).
-
When we parse attributes in HTML or read attribute values internally, we avoid constructing Attr nodes until a script actually needs them, reducing memory usage and making garbage collection less likely (@webbeef, @TimvdLippe, @mrobinson, #44209, #45023, #45031, #45060).
We’ve eliminated a traversal of the whole DOM tree whenever an <iframe> is attached to the tree, which is especially noticeable when parsing documents with many <iframe> tags (@mrobinson, #45236).
Stylesheet locks now use AtomicRefCell, which is even more efficient than a parking_lot::RwLock (@mrobinson, #44883).
On OpenHarmony, we now have a real refresh driver for reduced idle CPU usage (@jschwe, @yezhizhen, #44927), and we now cache the font list on disk for faster startup (@RichardTjokroutomo, @d-desyatkin, #44158).
We’ve also reduced allocations, GC rooting steps, and other operations in many parts of Servo (@jschwe, @kkoyung, @mrobinson, @SteveSharonSam, @Narfinger, @jdm, @nodelpit, @simonwuelker, #44961, #44944, #44972, #45231, #45078, #44662, #44679, #44967, #44963, #44933, #44935, #44905).
To improve Servo’s build times, we’re moving more code out of our massive script crate (@Narfinger, @jdm, #44598, #44636, #44823), and reduced the size of our dependency tree (@jschwe, #44818).
Stability
Several crashes and hangs have been fixed:
- in ‘content’ (@mrobinson, @Loirooriol, @SimonSapin, #45227, #44762)
- in MediaStream (@jdm, #44781)
- in item() on attributes on Element (@webbeef, #44721)
- in appendRule() on CSSKeyframesRule (@mrobinson, #45173)
- in initEvent() on FocusEvent (@mrobinson, #44870)
- in stop() on Window (@TimvdLippe, #44804)
- in
document.execCommand("delete")(@TimvdLippe, #44748) - in
--debug-mozjsbuilds (@Gae24, @SharanRP, #44745, #45001) - when evaluating scripts in DevTools while paused (@atbrakhi, #45050)
- when previewing some JS values in DevTools (@eerii, @atbrakhi, #45054)
- when shaping zero-width spaces in layout (@mrobinson, #45176)
- when toggling servoshell’s experimental mode at runtime (@mrobinson, @Loirooriol, #45226)
We’ve continued our long-running effort to use the Rust type system to make certain kinds of dynamic borrow failures impossible (@Gae24, @MavenRain, @Narfinger, @SteveSharonSam, @TimvdLippe, @elomscansio, @jdm, @kkoyung, @yezhizhen, #44712, #44759, #44879, #45014, #45058, #45061, #45076, #45098, #45110, #45149, #45117, #45184, #45201, #44806, #44930, #44942, #44946, #45233, #45181, #44659, #44660, #44664, #44668, #44992, #45000, #45081, #45009, #45225, #45087, #45244, #45245, #45247, #44663, #44665, #44993, #45040, #45053, #44647, #44671, #44681, #44717, #44733, #44686, #44653).
New contributors
A special thanks to the following people for landing their first patch in Servo:
- AbdAlRahman Gad (@AbdAlRahmanGad, #45213)
- Onyeka Obi (@MavenRain, #44806)
- Steve Sharon Sam (@SteveSharonSam, #45030)
- avis137 (@avis137, #44837)
- Xabier Rodríguez (@calvaris, #45084)
- June (@kimjune01, #44816)
- Matt Van Horn (@mvanhorn, #44740)
- nicole (@n0blenote, #44704)
- panxt8 (@panxt8, #44991)
Interested in helping build a web browser? Take a look at our curated list of issues that are good for new contributors!
Donations
Thanks again for your generous support! We are now receiving 7659 USD/month (+4.2% from April) in recurring donations. This helps us cover the cost of our speedy CI and benchmarking servers, one of our latest Outreachy interns, and funding maintainer work that helps more people contribute to Servo.
Servo is also on thanks.dev, and already 35 GitHub users (+2 from April) 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.
We now have sponsorship tiers that allow you or your organisation to donate to the Servo project with public acknowlegement of your support. If you’re interested in this kind of sponsorship, please contact us at [email protected].
Use of donations is decided transparently via the Technical Steering Committee’s public funding request process, and active proposals are tracked in servo/project#187. For more details, head to our Sponsorship page.