10 Aug 2026
Planet Mozilla
Thunderbird Blog: Desktop Calendar: A Design Journey

Hello, Thunderbird community and followers of the blog! This is Jesse from the design team. Today's post is about our recent journey in redesigning the calendar portion of Thunderbird, and what you can expect us to deliver in the near future.
The calendar is a key part of any productivity toolset, from your PC Desktop to your office wall. There has been a calendar in Thunderbird since early in the project, and like all parts of the application, it's evolved on its own terms, for better or for worse. It has many layers of functionality, but the experience has lost parity with current UI standards - at this point, it feels stylistically dated and functionally convoluted.
So, with the help of the design team and the developers and the community, we have taken on the task of modernizing and streamlining the calendar. This is my account of the designers' part of that journey.
The Big Picture
Here are some of our guiding principles for this redesign:
First, we are here to serve the entire user base, not just the technical experts, or the productivity enthusiasts, or the brand new adoptees. For this reason, the dialog with the community is critical: we need to understand as many of the use cases and interaction patterns as possible, and we want to support them broadly, and efficiently, and effectively. Our ideal solution is open and flexible, respecting the broad range of users who rely on Thunderbird.
Second, a key point: Thunderbird is aiming higher than being simply "the other email client." We are all committed to creating an experience that meets and exceeds expectations, and competes directly with the oliphaunts in the room: the Google Calendars, the Apple and Microsoft application suites, and the many targeted productivity apps that jockey for this space.
And as always, we will do this transparently, with an open source philosophy, in collaboration with our users and contributors.
The Journey
This design journey has been ramping up for several years now, in parallel with other company initiatives (Mobile! Web! Accessibility!). As our design practice has evolved, we have worked on the project from several directions, redesigning dialogs and rethinking patterns and collecting insights. For a while, this meant a lot of partial designs, but without a guiding vision.
Among these early designs, one of our success stories was a visual and functional update of the Event Details dialog, to replace the existing, rather archaic event details window ("archaic" both visually and in terms of code). These were one of the first redesigns to reach a point where it could be implemented - prioritized partly because it's a self-contained element, able to be tested without reworking the whole calendar code base.
If you use Thunderbird Daily, you may recognize this:
We've followed this pattern for several other bits and bobs, including the dialog for editing an event, and the notification for unanswered invitations. In all cases, these changes will create better contrast and visual hierarchy, and improve the visibility and organization of controls:
This alone could provide enough work for several release cycles. But designing isolated elements creates inconsistency and debt, both for design and development. As the design process on Calendar increased in velocity, it became clear that we needed to articulate a unifying vision.
Bringing it together
With these designs setting a direction, we had to step back and decide how all the pieces would fit together. In order to do that, we still had to answer three more questions:
- How does the actual calendar grid look, set to view a day, a week, a month, or a year?
- How does the user change their view and navigate forward and backward?
- How does the user connect to their calendars, and manage them all in one place?
These considerations led us to a lean design, with screen space broken up into three main sections. First is the grid, which provides the main element at the center of the layout - the user's primary workspace. Second is the navigation bar, directly above the grid. Third is a sidebar for managing calendars - the nerve center for your calendars and data sources. This design, focused on the most important functional areas, provided a great foundation for all the necessary functionality, with low friction and strong fundamentals.
The blueprint for our design (called a "wireframe" in the UX design world) ended up looking like this:
The grid acts as the user's main workspace, and the header and navigation provide their basic controls.
Here is a final design mock-up, which will provide the basis for development (this one is showing a week view in the main grid):
Given the wide range of our users' scheduling needs, we decided the calendar sidebar should be collapsible, and useful at both large and small sizes, so that users could decide how much of a footprint they needed to manage their calendar list.Here is the screen with the sidebar in a collapsed state, showing a Month view in the main grid:
And here is this screen after the user has pressed "New Event," showing the Create Event window over the interface:
Where we go from here
As these elements came together, we also turned outward and looked to our community for more feedback. Through the various stages of design, we published two TopicBox posts (here and here), and we ran a short but informative survey, looking for initial reactions to the direction we were taking.
This feedback has been very encouraging, and also enlightening: we have seen a positive response to our designs, and we've also gathered lots of insights on what you cite as most important (task integration, platform interoperability, and a re-assessment of agenda, mini-month, and multi-week views, to name a few).
These discussions gave us some additional confidence, but more so, they reminded us that we are still at the beginning of a longer arc. After we develop version 1 of our new calendar design, we will follow signals from our users as we plot a path forward. The new calendar design will clean up and simplify many aspects of the experience, but it will only be a promising first step (sort of the Rivendell stage of the epic). We will have many more cycles of design and iteration to bring our users the toolset they deserve.
For now, we venture forth, from design to implementation, and then from implementation to feedback and engagement. The new calendar will be released gradually, via proper channels, so users can try it and provide feedback - and feedback will be appreciated! We will be looking for usability testers and survey participants as we keep refining the roadmap.
The future of calendar is wide open, and much brighter and less gray than the bygone era. We appreciate all the support we've gotten from the community so far, and we hope you'll continue with us as we keep making Thunderbird awesome.
The post Desktop Calendar: A Design Journey appeared first on The Thunderbird Blog.
10 Aug 2026 6:59pm GMT
Mozilla Security Blog: Updated GPG key for signing Firefox and Thunderbird Releases
Today, we moved to a new GPG signing subkey used to sign certain Firefox and Thunderbird artifacts (namely Linux tarballs, RPM packages, checksums files) after an unencrypted copy of the previous subkey was inadvertently committed to a private GitHub repository.
Our review of available audit records found no evidence that the key was accessed by an unauthorized party while it was present in the repository. Access to the repository was limited to a small group within Mozilla, all of whom already had authorized access to the key through other means.
We have revoked the previous signing key and added safeguards to prevent similar issues in the future.
For most users, no action is required.
There are two cases where you may need to take action:
- If you manually verify our GPG signatures, you will need to import the new signing key and the revocation for the old key.
- If you use Firefox RPM packages, some manual intervention may be required. See the instructions below for details.
Thunderbird does not provide official RPM packages, so there is no RPM-specific action required.
RPM Users
Different RPM package management tools deal with GPG key rotations and revocations differently. See the sections below for what action (if any) you need to take to ensure you continue to receive the latest Firefox updates.
Fedora 43 and later
No special action needed. During the next update, dnf will download the updated key and you just need to confirm the import. Make sure the shown fingerprint matches 827E 6586 0867 9618 CD34 9F93 678E 455D 7676 7AA3 before accepting.
Fedora 42 and older, RHEL/Rocky/Almalinux
Dnf on these releases cannot replace the key on its own. Updates will fail with "Import of the key didn't help, wrong key?" or "The GPG keys listed for the mozilla repository are already installed but they are not correct for this package". The old keys must be removed manually:
sudo rpm -e --allmatches gpg-pubkey-14f26682d0916cdd81e37b6d61b7b526d98f0353
sudo rpm --import https://packages.mozilla.org/rpm/firefox/signing-key.gpg
sudo dnf clean all
Important: Remove the previous signing key before importing the new one. If you run rpm --import while the previous key is still installed, the command may report success even though the key is not updated.
openSUSE/SUSE based distributions
Same as the previous section, zypper won't replace the key on its own and it must be removed manually. Updates will fail with "Signature verification failed" or "NOKEY". Use the following commands:
sudo rpm -e --allmatches gpg-pubkey-14f26682d0916cdd81e37b6d61b7b526d98f0353
sudo rpm --import https://packages.mozilla.org/rpm/firefox/signing-key.gpg
sudo zypper refresh
New GPG Key Details
The GPG fingerprint is 14F2 6682 D091 6CDD 81E3 7B6D 61B7 B526 D98F 0353. The new signing subkey's fingerprint is 827E 6586 0867 9618 CD34 9F93 678E 455D 7676 7AA3, and it expires 2028-08-05.
The new public key and revocation of the previous one can be fetched from:
- KEY files of the latest Firefox Nightly (https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central/)
- keys.openpgp.org, or
- inline below
This can be used to validate releases signed with the new key. Due to the nature of GPG signing, releases signed with the previous key will no longer be verifiable after importing the revocation.
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
=LpNb
-----END PGP PUBLIC KEY BLOCK-----
The post Updated GPG key for signing Firefox and Thunderbird Releases appeared first on Mozilla Security Blog.
10 Aug 2026 6:37pm GMT
Firefox Tooling Announcements: Firefox Profiler Deployment (August 10, 2026)
The latest version of the Firefox Profiler is now live! Check out the full changelog below to see what's changed:
Highlights:
- [fatadel] Improve discoverability of downloading a local profile (#6216)
- [Nazım Can Altınova] Add the ability to apply source maps from the CLI (#6229)
Other Changes:
- [fatadel] Create the Network track from the timeline-network schema display location (#6224)
- [Markus Stange] Only call
getRawFrameTableBuilderWithExistingContentsonce per symbolication batch. (#6233) - [Nazım Can Altınova] Handle the cli daemon startup failures more gracefully with better errors (#6241)
- [Nazım Can Altınova] Handle Text and Log marker payloads with their marker schema (#6247)
- [Nazım Can Altınova] Bump the Gecko profile version to make sure that the Text and Log marker changes are picked up in the frontends (#6252)
- [fatadel] Deactivate a menu button as soon as its panel is dismissed (#6251)
- [Nazım Can Altınova]
Sync: l10n → main (August 10, 2026) (#6253) - [Nazım Can Altınova] Bump profiler-cli version to 0.8.0 (#6254)
Big thanks to our amazing localizers for making this release possible:
- de: Ger
- de: Michael Köhler
- el: George kitsoukakis
- en-CA: chutten
- en-CA: Saurabh
- en-GB: Ian Neal
- es-CL: ravmn
- fy-NL, nl: Fjoerfoks
- fr: Théo Chevalier
- fy-NL: Fjoerfoks
- ia: Melo46
- it: Francesco Lodolo [:flod]
- nl: Fjoerfoks
- ru: michellemelsspam
- ru: Valery Ledovskoy
- tr: giray
- tr: Selim Şumlu
- zh-TW: Pin-guang Chen
Find out more about the Firefox Profiler on profiler.firefox.com! If you have any questions, join the discussion on our Matrix channel!
1 post - 1 participant
10 Aug 2026 5:06pm GMT
Niko Matsakis: Cylic trait implementations: motivation
Lately I've been thinking about cyclic trait implementations. This is a problem that I've been trying to understand for years and years and I finally feel like I'm geting somewhere. I'm going to try to write out a series of blog posts documenting those explorations and, hopefully, culminating in a design that could be RFC'd. In this first post, I want to talk about one of the interesting questions, what I am going to call "internal" vs "external" proofs. I know that this material can seem abstract, so I'm going to try and connect it to "real Rust" as much as possible! This particular blog post is an introduction, explaining the general problem and giving some motivation for why we care.
What are cyclic trait implementations?
Right now in Rust we require most traits to have non-cyclic, or inductive, implementations. To explain what I mean, let's consider this trait:
trait Dump {
fn dump(&self);
}
Now imagine that we have an impl of this for i32:
// Impl I
impl Dump for i32 {
fn dump(&self) {
println!("{self}");
}
}
A simple impl for Rc<T> and `Option:
// Impl RC
impl<T> Dump for Rc<T>
where
T: Dump,
{
fn dump(&self) {
T::dump(self)
}
}
// Impl Opt
impl<T> Dump for Option<T>
where
T: Dump,
{
fn dump(&self) {
if let Some(v) = self {
T::dump(v)
}
}
}
and finally a recursive List type that has an impl as well:
struct List<T> {
value: Rc<T>,
next: Option<Rc<List<T>>>,
}
// Impl L
impl<T> Dump for List<T>
where
T: Dump,
{
fn dump(&self) {
Dump::dump(&self.value);
if let Some(n) = &self.next {
Dump::dump(n);
}
}
}
If I try to show that List<i32>: Dump, I do that by
- Applying "impl L" to show that
List<i32>: Dumpifi32: Dump- Then applying "impl I" to show that
i32: Dump
- Then applying "impl I" to show that
There's no cycle here - that is, I didn't have to use impl L to show that impl L is valid.
Cyclic logic sounds bad, but it can be exactly what you want
Now, when I said that "the impl L didn't have to use the impl L to show that it is valid" that might not have sounded suspicious to you. In fact, it's a pretty natural idea. After all, generally when you try to establish a logical argument, you aren't allowed to use cyclic reasoning. That is, you can't say: I know that Niko likes Rust because Niko likes Rust. So, in the same sense, it seems natural that I should not be able to say "I know that List<i32> implements Dump because List<i32> implements Dump".
But actually, it would sometimes be really useful to say exactly that. One example is so-called "perfect derive". In our Dump impl above, we had one where-clause, T: Dump. And if you were to create a custom derive for Dump and write #[derive(Dump)], the impl I showed is typically exactly what you would get. But it's not necessarily what you want. Consider what you get with #[derive(Clone)]:
// Impl LC1
impl<T> Clone for List<T>
where
T: Clone, // <-- generated but not really required!
{
fn dump(&self) {
List {
value: Clone::clone(&self.value),
next: Clone::clone(&self.next),
}
}
}
Here, the derive is going to create an impl that requires T: Clone. But if you look closely, you'll see that all the fields only use Rc<T>, so in fact, we should be able to clone a List even without T: Clone! But how is the compiler to know this?
You might think that the compiler could do some super smarty-pants analysis on the fields to figure it out. And, in a way, it can: that is what cyclic trait solving is all about. The thing is, while the compiler can do that, the derive cannot - the derive doesn't have access to the definitions of other types and so forth, and clearly we would need to know things about Option and Rc to figure out whether T: Clone is required here.
But what we could do is to generate a different impl. Instead of adding T: Clone for each type parameter, we could add a where-clause for each field type. This makes sense: after all, we are just going to be calling Clone on every field, so it's quite logical to say that the impl is valid if every field is cloneable:
// Impl LC2
impl<T> Clone for List<T>
where
Rc<T>: Clone,
Option<Rc<List<T>>>: Clone,
{
// .. as above ..
}
Under this formulation, we can see that all we have to be able to do is to clone an Rc<_> and clone an Option<Rc<_>>, neither of which require that T: Clone.
This idea is called perfect derive
We call this idea [perfect derive][] and it's been a goal for a while. The thing is, cyclic reasoning is tricky to get right. The Clone example is actually an easy one: that one doesn't really require cyclic reasoning:
- To show that
List<i32>: Clonewe have to show that…Rc<i32>: Clone, which is easy becauseimpl<T> Clone for Rc<T>doesn't have any where-clauses1Option<Rc<List<i32>>>: Cloneuses theimpl<T> Clone for Option<T> where T: Cloneimpl which requires…Rc<List<i32>>: Clone, which is again easy
But it's not so easy for Dump
But if we use that same "cyclic derive pattern" to generate our Dump impl, things don't work out so well. Instead of just a T: Dump bound, our Dump impl now has two bounds:
// impl L1
impl<T> Dump for List<T>
where
Rc<T>: Dump, // <-- Used to be `T: Dump`
Option<Rc<List<T>>>, // <-- This one is new!
{
fn dump(&self) {...}
}
Now imagine we try to show List<i32>: Dump. We begin by applying impl L1, which requires us to show that its where clauses hold:
- To show
List<i32>: Dumpwe use impl L1, which has two where-clauses:Rc<i32>: Dump, this one is easy because theRcimpl requires thati32: Dumpwhich is true.- But
Option<Rc<List<i32>>>: Dumpis tricky. TheOptionimpl requires that…- We need to prove
Rc<List<i32>>: Dump, and then theRcimpl requires that…- We need to prove
List<i32>: Dump, but that is what we started with! That's cyclic logic!
- We need to prove
- We need to prove
Ugh. Something's tricky here!
We can't just accept any old cycle because of supertraits
Now, maybe you think we can just accept any cycles. And for these examples, it would be fine: but it's not correct if you consider supertraits. Consider this trait and impl pair:
trait Magic: Copy { }
// Impl M
impl<T> Magic for T
where
T: Magic,
{}
If you are naive, this weird trait-impl pair can be used to prove that any type is Copy, regardless of whether it has a Copy impl. For example:
- Say we want to prove that
String: Copy. We observe that if a type implementsMagic, it must implementCopy, so…- We begin by proving
String: Magic. We use the impl M, which requires- that we show
String: Magic, which is a cycle, so we accept it.
- that we show
- We begin by proving
Uh oh, now we did something wrong. We proved that String: Copy even though there is no Copy impl. Something is fishy.
Now clearly we can all see the problem here - the implementation of Magic didn't really add any information. It was just a tautology, saying that T: Magic if T: Magic. It's not wrong, but implementing Magic was supposed to tell us more than just the fact that there is an impl of Magic, it was supposed to tell us also that the supertrait Copy is implemented. And that's not true here.
But if you think about it, it's hard to decide why we should reject impl M but accept the impl L1 of Dump for List<T>. They both wind up with a cyclic proof. So what's the difference? This is the question we'll be exploring over the next few blog posts.
Soundness for traits
This gets at an interesting question: what does it mean for the trait system to be sound. This seems obvious but actually it was a question I found kind of non-obvious for a long time.
We've found two satisfactory answers to that question. One of them involves converting to dictionary-passing style. Nadri explained that in a blog post. I think that's a great post to read. I'm going to give another definition here that doesn't require converting to a dependently typed program2
My rough definition is this3: the trait system is sound if, whenever it accepts some program P, that program cannot have a function that believes some Trait holds for the T, but there is no impl of Trait that can be used. So in the case of Magic and Copy, it's easy to write a program that shows simple cyclic trait solving is unsound:
trait Magic: Copy {}
impl<T: Magic> Magic for T {}
fn is_copy<T: Copy>() {
// this function believes `T: Copy`
}
fn main() {
// this can be called because we believe that
// * `String: Magic` because
// * `String: Magic`, and we accept cycles.
// And then `String: Magic` implies `String: Copy`.
is_copy::<String>();
}
By my definition, any sound type/trait system must reject this program because, if it were to execute, then execution would reach is_copy::<String> and yet there is no Copy impl that is judged to ber applicable to String. Uh oh!
Coming next
As I promised, this post was mostly focused on "setting the scene". My goal was to explain what the problem is that we are trying to solve - permitting "good cyclic impls" but forbidding bad ones. I didn't spend a lot of time on the bad ones, but it turns out that there's a wide variety of unsound things one can do, some of which the compiler currently gets wrong, others of which it would only get wrong if we started permitting cycles.
My motivation for getting into this work is a bit complicated. I want perfect derive. But it's also a loose end in our trait semantics that I really want to see nailed down before we move onto other tasks. Having auto traits (e.g., Send) work differently from other traits is clearly a "smell", and without a strong understanding of the logical underpinnings of our trait system it's easy to get things wrong when we build extensions.
In the next few posts I'll go a bit deeper into the exploration I and others have been doing. I'll talk about some of the "false starts" we took along the way and why they don't work, and then about some of the solutions that are under consideration. Working through this stuff has really helped me to broaden my understanding of various areas of logic. By the time we're done, we'll cover4 coinduction and productivity, modal logic and the later modality, and we'll see how our techniques might even help us with resolving specialization5.
I cited it earlier, but if you want to read other tasks on the same subject, I definitely recommend Nadri's post on dictionary-passing style.
-
Apart from the default
Sizedbound, I'm ignoring that here ↩︎ -
I have found that both the dictionary-passing interpretation and the logic approach I'm using are valuable. In the end, they're more or less equivalent, which I guess shouldn't be surprising if you've heard of the Curry Howard Correspondence, but I'll talk about that later perhaps. ↩︎
-
I would like to, but haven't, define a simplified version of Rust that includes trait solving and simple type checkoing and show that it cannot "go wrong". ↩︎
-
In a shallow way, I'm no expert! ↩︎
-
Plot twist, bet you didn't see that coming! I sure didn't. ↩︎
10 Aug 2026 1:35pm GMT
Ludovic Hirlimann: 20+ years of running "alpha quality" browser as my main web browser
I have been accessing, using the internet since probably around 1991, using my dad's academic account and then schools and then home. I've used the internet before the web existed, sending emails, downloading freeware and sharewares from "huge" ftp repository. Sharing ftp site, using Usenet to find more and share more. This was a time you had to buy Ethernet NuBus card and install both Ethernet drivers and TCP/IP ones.
Then one day something called NCSA Mosaic came into the picture - this changed the way I consumed 'the network'. After a while some friends showed me Netscape, and mosaic faded away. I've used Netscape on Mac, Windows 3.11, NT, on workstations running Unix (hello Dec Alpha).
At the time my gig was either running OS/2, and Linux Slackware on my Pentium machine. I then got into the Beos world, and that was one OS that Netscape didn't ship binaries for. Microsoft had started pushing Internet explorer (IE). I was starting to work and *had* to use Windows. I came up with the idea of using Mozilla at work in order to find bugs that would later be fixed when I'd use it home on my favorite OS.
So I started using Mozilla builds for windows, and then following planet and mozilla.org to be aware of the process. I would now and then file bugzilla issues, often to discover they've been filled already :-) I clearly remember the day tabs were introduced. I walked around the room I was working in showing the great new feature to my colleagues that were using Mozilla. There were no formal releases, at the time CI-CD didn't exist completely yet, so you could keep the same version for a day or for a week depending on how broken the tree was
Then I continued using builds until updates became available, and I choose to use the nightly channel. At that time my motivation had changed, I had moved from dead BeOS to NeXTStep+1 aka Mac OS X. There was no way for me to help My then browser of choice Camino at work. Mac OS X was way less popular in the tech industry that it is now.
The web landscape was dominated by IE , the mac version was unfortunately different meaning that using it made a bunch of websites unusable.
When Firefox got out, Camino started dying and I switched boats.
I then got employed by Mozillamessaging and used both Thunderbird and Firefox nightlies. I was the QA lead and there were no way I could test all the software and hardware combination used by our users. So crowd testing was very valuable to me. At this point I had stopped reporting issues and the only thing I was reporting were crashes.
Since 2010 a bunch of Chrome related browsers have started taking the web over, a bit like in 2006 when Microsoft was running the show, instead now google is. I currently run 2 versions of Firefox, nightly for personal stuff and release for work related ones. I occasionally have to fire a chrome related browser because testing with Ff from the vendors is not being done (I'm looking at DocuSign and FoundryVtt ).
So running nightly software has not been a burden at all, because there are a few crashes here and there, but I always submit, so the stability team at Mozilla can investigate. The idea is that if it crashes on me, it won't crash on my Dad's computer because he runs releases. Once or twice in the course of those 20 years did I have to either reinstall or create a new profile. That's how stable nightly has been for me.
I'm annoyed at some of the decision Mozilla makes, but again they are the most independent browser maker out there with a big enough team to deal with the development surface of a browser. Hence, for some forseable future I'll be running nightlies in hopes of keeping the web open. I'm lurking at Servo and following it's development, reporting issues there because I see it has an alternative to Firefox, but it's far from being ready yet.
I'd encourage some of my readers to try/use Nightly. If you choose to do so, send in crash reports and enable telemetry.
10 Aug 2026 11:48am GMT
06 Aug 2026
Planet Mozilla
Mozilla Addons Blog: How the publicSuffix API was created
Firefox 153 ships the new publicSuffix WebExtensions API. This API lets extensions ask the browser for the registrable domain (eTLD+1) of a hostname. It uses the browser's built-in, always-up-to-date copy of the Public Suffix List, removing the need for extensions to bundle and maintain a copy of the list.
This feature was one of the most-voted bugs in WebExtensions on Bugzilla, and would not have been possible without the contributions by Francis McKenzie (aka mckenfra). So, thank you, Francis!
What the API does and why it exists
A "public suffix" is a domain suffix under which people can register their website names, such as .com, .co.uk, and github.io. Knowing where the public suffix ends and the registrable domain begins matters for any task that groups or isolates sites. Or any task involving the need to determine whether a given input is a likely domain, such as the autocompletion feature in the address bar that doubles as a search box.
Before this API, extensions that needed it had to bundle a copy of the Public Suffix List and update the extension whenever the list changed. As these changes happen frequently, the bundled lists were often out of sync with the browser's interpretation.
The Firefox Multi-Account Containers extension has a longstanding request to configure containers for all subdomains. This feature would let people assign an entire domain, such as *.example.com, to a container instead of adding every subdomain by hand. Francis implemented this feature in a patch to the Multi-Account Container extension, building on top of the publicSuffix API in Firefox 153.
Behind the scenes
The first Firefox patch for this API went up in June 2022, but it wasn't the one that shipped. That month, the bug was referred to the WebExtensions Community Group for cross-browser design, which would benefit extension developers beyond Firefox. After reaching consensus on the capability request in March 2024, Francis submitted a detailed proposal for the publicSuffix API in accordance with the WECG proposal process.
What followed was nearly a year of review. Francis made a strong case for the API having a synchronous shape, unlike almost every other extension API. Browser vendors and the Public Suffix List maintainers chimed in to leave feedback. The proposal changed shape several times in response. Approval came from Safari and Firefox in May 2025, with Chrome still tentative. Final Chrome sign-off landed in April 2026 after review at a WECG face-to-face meetup in London, and the proposal was merged. Francis then submitted the Firefox implementation patches, which landed in June and shipped in July with Firefox 153 (see changes for add-on developers in Firefox 153)!
On the WECG
None of this happened in a Mozilla-only queue. The WebExtensions Community Group exists so that an API like this doesn't end up as three incompatible browser-specific versions. If you've ever hit a wall building an extension because some capability isn't available, filing an issue at w3c/webextensions and participating in discussions is the way to make it visible to the people who can help make it happen.
As the publicSuffix API's WECG issue shows, the process is open, with browser engineers, extension developers, and other subject matter experts (such as the Public Suffix List maintainers) discussing the API shape in public. When Firefox's implementation was nearing completion, another Chromium contributor began an independent Chrome implementation, which revealed a possible improvement to the API. This insight resulted in a minor modification, which was approved within days. This shows the strength of multiple independent implementations collaborating on a common API.
As always, you can file extension-related issues on Bugzilla under the WebExtensions product, and cross-browser API proposals are discussed in the W3C WebExtensions Community Group. For questions, the Add-ons Discourse is the best place to start.
The post How the publicSuffix API was created appeared first on Mozilla Add-ons Community Blog.
06 Aug 2026 10:04am GMT
05 Aug 2026
Planet Mozilla
Firefox UX: Let your designs fail for the right reasons
How AI-assisted native prototypes changed what usability testing could show me.
If you've ever simplified an interaction just to make a prototype manageable, you've probably felt the tension between what you designed and what the prototype could actually support. The risk is that when a design fails in usability testing, you can't always tell why. Was the experience itself the problem, or was it really the prototype getting in the way: a missing connection, a laggy transition, a path you didn't build?
I ran into this while working on Report Broken Site for Firefox Android, and it led me to a different way of prototyping: building directly inside the real app with AI (Claude), so the test reflects native fidelity rather than a simulation of it. That's when I started worrying just about the design failing, and not the prototype.
Feature: Report Broken Site
Reaching limits of walled prototypes
In tools like Figma, prototyping requires anticipating every possible interaction and defining it explicitly. For the user to feel the true experience, each path needs to be connected, each transition set, and each variation accounted for. As complexity grows, it tends to increase the cost of maintaining it: screens multiply, connections become fragile, and animations become tedious to maintain.
At some point, you're no longer designing the experience. You're managing the prototype.
E.g. Changing the animation for one node, requires updating it everywhere manually.
To cope, we simplify the prototype. We reduce the number of paths, guide users through predefined flows, and limit what they can do on the prototype. The result is what I've started thinking of as a walled prototype - like a walled garden: a bounded space where users can move, but only within the paths we've pre-defined.
Some designers might argue that Figma's recent additions of variables and advanced logic solve this problem. However, even with these tools, the designer is still building and managing the prototype. Figma prototypes simulate a system; it is not the system itself or a part of it. These prototypes have been useful, but they have also shaped the participant testing experience in ways that haven't always been obvious.
When the logic of a feature is handled by manual connections, the canvas quickly turns into spaghetti of fragile dependencies.
Prototypes shape participant behavior
This becomes especially noticeable in usability testing. Test participants tend to recognize when they are interacting with a prototype, and that awareness can change how they behave. They may hesitate to explore, follow the perceived intent of the task, or tap around when they get stuck.
For example, to keep a prototype manageable, I might only make a few issue types selectable. But then participants are doing two things at once: deciding what they want to do and guessing what the prototype will allow. Their feedback can become shaped by the prototype's limits, not just the design - like a visitor to the walled garden checking which paths are actually open to them.
That constraint can be useful in early concept testing, where a narrower path helps focus the conversation. It becomes more limiting when we are trying to understand how the full experience behaves.
Research and practice have long acknowledged that prototype fidelity and testing setup can influence participant behavior. But in practice, many workflows still rely on constrained, screen-to-screen simulations.
I've often wondered:
How a user's perceived experience might change if they weren't encountering the feature in the isolation of a walled prototype?
From walled to native fidelity prototypes
Designing and prototyping is often described in terms of fidelity - from low-fidelity sketches to high-fidelity designs ready for dev handoff. That framing focuses on how closely we represent the product, but not necessarily how the experience itself behaves.
As building realistic interactions becomes easier using AI, it may now be possible to move beyond simulating flows in Figma and towards observing how people actually behave. So, alongside designing it in Figma, I built the feature directly into a local version of the Firefox Android app using Claude. It wasn't straightforward at first, but even the friction of getting it working revealed things I wouldn't have seen in a Figma prototype.
When I did this, I noticed there were no predefined paths to manage or fragile connections to maintain. The experience felt more continuous, allowing users to move more freely, not just within the feature, but within the app itself. I started thinking of these as prototypes with native fidelity - native to the app, native to the device, and aligned with how users expect interactions to behave.
When prototypes need to handle dynamic behavior
The difference between the two types of prototypes is not just theoretical; it starts to change what the experience can support. In walled prototypes, content is often fixed, and interactions move users between predefined screens. While this works for simple flows, it becomes harder to represent how interfaces behave when content needs to update dynamically based on user interaction.
In the Report Broken Site feature, this was important. A walled prototype struggles with:
- Capturing website data: Depending on the browsing tab, metadata like the URL, screenshot, browser info, and tracking data needs to be captured and reflected back to the user.
- URL editing: Simulating real text entry, cursor movement, and auto-correct behavior.
- Branching logic: If a user selects "Site doesn't load" as issue type, the details are optional, but if they choose "Something else," details become required.
- Error handling: For "Something else," the system must validate input length in the description box and show an error if it's insufficient.
Have you ever run into interactions like these and found yourself simplifying them, just to make the prototype manageable?
When I built it directly using Claude, the native fidelity prototype was able to handle metadata capture, text input, and branching logic more naturally.
The native fidelity prototype inherits native behaviors like metadata capture, keyboard interactions, and dynamic state changes.
The environment is part of the experience
Another challenge is the environment in which the prototype is experienced. In walled prototypes, layouts are often fixed, and responsiveness is limited. Differences in device size, orientation, or performance can introduce inconsistencies that don't reflect the intended final experience.
In practice, this can show up as:
- Oversized UI elements on larger devices as the prototype was created for an average phone size.
- Laggy interactions on slower networks as Figma prototypes fail to be responsive sometimes.
- Layouts that don't adapt as expected because of the constraints of the prototyping environment.
When the interaction is built directly in the app, the experience inherits the native environment of the device. Layouts respond to screen size, interactions feel more consistent, and the overall experience is closer to what users would encounter in the final product. This could reduce the likelihood of testing interfaces being mistaken for design issues.
Tradeoffs and new realities
This approach introduces its own challenges. First time setup for a designer is complex, and navigating the codebase and working through unfamiliar tools takes effort.
Using Claude on the Firefox for Android codebase in Android Studio to build the prototype.
Adopting this approach requires a shift in the UX designer's toolkit. It raises the barrier to entry by requiring baseline comfort with the terminal, build environments, and IDEs. But it also allows designers to move beyond "faking the experience" in Figma prototypes and start building directly in the app.
Building the prototype this way also changes how the work evolves. Instead of worrying about defining everything upfront, requirements tend to emerge through interaction -i.e. edge cases, missing states, and unclear behaviors as the experience is built. In Figma, many of these details are easy to overlook; when you create a prototype by building directly, they become easier to find.
Of course, this realism has its limits. While the experience feels like a continuous system rather than a sequence of steps, I haven't yet connected it to a backend, pulled in APIs, or tested cross-device capabilities across mobile, tablet, and desktop. I'm still at the start of this exploration. What I want to understand next is how native fidelity prototypes change the testing environment itself: whether participants explore differently, whether failures are easier to interpret, and what new friction this approach introduces for designers and teams.
Start failing for the right reasons
To put it simply: if prototypes constrain user behavior, they may also shape the insights we get from usability testing.
For Report Broken Site, the value of the native prototype was not just that it handled more states. It gave me a more honest way to sit with the experience before putting it in front of participants. I could edit the URL, switch issue types, trigger validation, and move around the app as the feature would exist in context. Because this was a mobile experience, that context mattered: I could test it on a real device, with real navigation patterns, real input behavior, and the surrounding app experience intact. Those details helped me look past whether the prototype was working and focus more directly on whether the experience was working.
That is what I mean by letting the design fail for the right reasons: understanding whether an experience fails because of the design itself, not because of a missing screen-to-screen connection, bad transition, or laggy Figma prototype. The next step is to test whether this translates into different participant behavior and more useful usability insights.
Originally published on medium.com.
05 Aug 2026 5:46pm GMT
This Week In Rust: This Week in Rust 663
Hello and welcome to another issue of This Week in Rust! Rust is a programming language empowering everyone to build reliable and efficient software. This is a weekly summary of its progress and community. Want something mentioned? Tag us at @thisweekinrust.bsky.social on Bluesky or @ThisWeekinRust on mastodon.social, or send us a pull request. Want to get involved? We love contributions.
This Week in Rust is openly developed on GitHub and archives can be viewed at this-week-in-rust.org. If you find any errors in this week's issue, please submit a PR.
Want TWIR in your inbox? Subscribe here.
Updates from Rust Community
Official
- Enabling the next iteration of the borrow checker on nightly
- Funding team progress update
- rust-lang/rust is adopting an LLM policy
- All Hands 2026 retrospective
Newsletters
Project/Tooling Updates
- Kevat 0.4.0 - fast, resumable copy and move to external drives, now with a GUI on all three platforms
- kache 0.13.0: keying the env vars proc-macros read
- kobe 101: lease a Kubernetes cluster, don't create one
- Rewriting FalkorDB in Rust: Make It Work, Make It Stable
- Announcing
webrtcv0.20.0: Async-Friendly, Runtime-Agnostic WebRTC on Sans-I/O Corertc - Proxelar 0.5.0: sessions, rules, and more ways to capture traffic
- mirador 1.0.0: a personal terminal dashboard
- BitFun 0.2.15: an open-source desktop AI agent built on a Rust runtime
- mvis v0.5.0: CI/CD Profiling & Allocation Histograms
- multicalc 0.9.0: scientific computation for embedded and robotics systems
- Auto-correcting wrong-layout typing on Wayland is nearly impossible. We did it anyway
- wimux 0.1.0: a native Windows terminal multiplexer
- amtr: a btop-style context-window monitor for Claude Code sessions, and the forensic autopsy of its own 153-hour build
- RSigma v0.20.0 release
- The State of RSigma, and Part Two: The Loop
Observations/Thoughts
- How Firecracker microVMs work under the hood to sandbox untrusted code and AI agents
- Faster floating point math with Rust's new API
- Rust MEMS drivers: 3 reasons to try and adopt our new sensor driver
- The Bedrock of Software Design | Alex Fedoseev
- Tail-Call Interpreters in Rust
- How to speed up the Rust compiler in July 2026
- Sovereign Tech Fellowship for Rust maintenance (June-July 2026 report)
- An old-new take on argument parsing in Rust
- Stateless Servers, Stateful Payloads: Sessions vs Continuations, Measured in Rust
- [video] Rust in the age of Generative AI with Niko, Allen & Zeeshan
- [audio] Rust in Production S06 E09: JetBrains with Orhun Parmaksız
- Work-Stealing vs. Executor-Per-Thread: Evaluating different HTTP server workloads with Tokio, Smol and Glommio
- Your
#[target_feature(enable = "avx2")]does nothing onx86_64-unknown-uefi - Three bugs my AI agents couldn't fix
Rust Walkthroughs
- Blinking an LED on STM32 Blue Pill (STM32F103C8T6) with Embedded Rust
- Branchless Rust: Making a Filter 4x Faster by Removing an
if - Why modern font metrics cannot reproduce Word pagination
- Building hooklog on a six-day-old framework
Crate of the Week
This week's crate is index_type, a crate for providing strongly typed indices for collections.
Thanks to Roee Shoshani for the self-suggestion!
Please submit your suggestions and votes for next week!
Calls for Testing
An important step for RFC implementation is for people to experiment with the implementation and give feedback, especially before stabilization.
If you are a feature implementer and would like your RFC to appear in this list, add a call-for-testing label to your RFC along with a comment providing testing instructions and/or guidance on which aspect(s) of the feature need testing.
No calls for testing were issued this week by Rust, Cargo, Rustup or Rust language RFCs.
Let us know if you would like your feature to be tracked as a part of this list.
Call for Participation; projects and speakers
CFP - Projects
Always wanted to contribute to open-source projects but did not know where to start? Every week we highlight some tasks from the Rust community for you to pick and get started!
Some of these tasks may also have mentors available, visit the task page for more information.
- Cordial - Unify the two implementations of the profile lock
- Cordial - Fullscreen clips and letterboxes until the workspace is switched away and back
- Dofigen - Extend Dockerfiles
If you are a Rust project owner and are looking for contributors, please submit tasks here or through a PR to TWiR or by reaching out on Bluesky or Mastodon!
CFP - Events
Are you a new or experienced speaker looking for a place to share something cool? This section highlights events that are being planned and are accepting submissions to join their event as a speaker.
If you are an event organizer hoping to expand the reach of your event, please submit a link to the website through a PR to TWiR or by reaching out on Bluesky or Mastodon!
Updates from the Rust Project
630 pull requests were merged in the last week
Compiler
- improve CFG traversal
- perf: avoid a heap allocation per basic block in MoveData's location maps
- stabilize passing 128-bit integers via vector registers with
asm!on x86
Library
- a bit optimize four-digit chunks in integer formatting
- add NEON support for
is_asciiandeq_ignore_ascii_case - add semver check test command for checking API compatibility of stdlib
- allow only implementing
Read::read_buf - core: implement bounded random sampling
- iter: specialize
Take::countusingadvance_by - iter: specialize
advance_bymethod ofFuse - make atomic operations const
- move
std::io::copytoalloc::io - stabilize
size_of_val_raw, align_of_val_raw, Layout::for_value_raw
Cargo
- add a suggestion when adding
[lints]to a workspace to use[workspace.lints]instead - avoid parsing unchanged lockfiles
- completions: complete paths for cargo run arguments
- fix
manual_readmelint for lower-priority README files - git: make checkout names independent of git config
- make
__CARGO_TEST_FORCE_ARGFILEavailable in distributed builds - pass rustdoc flags to final CCI merge step
- prevent panic when
package.buildis empty - reworked how we enable the new build-dir layout on nightly
- trim-paths: unambiguous and reversible remap rules
Rustdoc
- label badge for notable traits
- rustdoc-json: make
Stabilitycompatible with non-self-describing serde formats - fix ICE when a grapheme cluster joins a Prepend-class character to
_or: - fix crash when trying to list attributes on an opaque type
- only analyze head of self type when deciding impl inlining
Rustfmt
Clippy
manual_div_ceil: avoid suggestions that change evaluation count- fix
no_effect_underscore_bindingfalse positive on proc-macro generated code - add check for image with embedded link to
doc_paragraphs_missing_punctuation - lint for UFCS call in
clone_on_copy - trigger
float_cmp_constforassert_eq!with const floats
Rust-Analyzer
- allow
selfas the last segment of a path - correctly handle unlinked module edge cases
- support
CovariantUnsafeCell - add
-Zjson-target-specon cargo calls where needed - add reference for same name param coerce matches
- allow diverging rhs in destructuring assignments
- avoid panic when checking
Copyfor hrtb closure arguments - detect the rust-analyzer component in a multi-line components array
- do not alloc anon consts for bare paths in blocks
- don't panic on a self-referential
impl Traitfunction - double stack size for threads to 16MiB
- exclude unknown types from term search
- fix lookup
MACRO_CALL@...in this Semantics due to include! - fix
ExprScopeshandling of exprs inside patterns - fix glob import shadowing bug
- make mir debug execution work fot bitflags items
- mark auto traits as coinductive
- no hint with similar name raw-ident arg
- parse postfix range inside closure in access
- recognize format arguments after a backslash in raw strings
- resolve assignment lhs in its expression scope
- show qualified paths when type names collide in E0308
- hir-ty, ide-diagnostics: use E0057/E0061 for arg-count mismatch (was E0107)
- perf: avoid having a separate query for defined opaques
- perf: save an allocation in lifetime handling
- report a config error for postfix snippets with item scope
vfs: use component-based path prefix matching for virtual paths
Rust Compiler Performance Triage
A lot of optimizations landed this week. Some big improvements to rustdoc in #159854, one big improvement in control flow graph traversal for cranelift-codegen, few more improvements to next-solver benchmarks and various other micro-optimizations, bringing the total to a nice round number of 10 improvements this week.
Triage done by @panstromek. Revision range: ad0c9dce..65dd30fb
Summary:
| (instructions:u) | mean | range | count |
|---|---|---|---|
| Regressions ❌ (primary) |
0.3% | [0.2%, 0.5%] | 18 |
| Regressions ❌ (secondary) |
2.1% | [0.1%, 16.8%] | 64 |
| Improvements ✅ (primary) |
-3.3% | [-39.8%, -0.2%] | 97 |
| Improvements ✅ (secondary) |
-6.1% | [-39.6%, -0.1%] | 111 |
| All ❌✅ (primary) | -2.7% | [-39.8%, 0.5%] | 115 |
1 Regression, 5 Improvements, 11 Mixed; 6 of them in rollups 32 artifact comparisons made in total
Approved RFCs
Changes to Rust follow the Rust RFC (request for comments) process. These are the RFCs that were approved for implementation this week:
- No RFCs were approved this week.
Final Comment Period
Every week, the team announces the 'final comment period' for RFCs and key PRs which are reaching a decision. Express your opinions now.
Tracking Issues & PRs
- Tracking Issue for
core_io_borrowed_buf - Tracking Issue for
derive_macro_global_path - stabilize
c_variadic_naked_functions
- Implement a naming convention for lint/diagnostic-only
rustc_attrs - Encode OpenBSD
-currentversion in targets'target_env - Add
target_feature_available_at_call_site - Promote
wasm32-wasip3to Tier 2
No Items entered Final Comment Period this week for Rust RFCs,Language Reference, Cargo, Language Team, Leadership Council or Unsafe Code Guidelines. Let us know if you would like your PRs, Tracking Issues or RFCs to be tracked as a part of this list.
New and Updated RFCs
- No New or Updated RFCs were created this week.
Upcoming Events
Rusty Events between 2026-08-05 - 2026-09-02 🦀
Virtual
- 2026-08-05 | Virtual (Cardiff, UK) | Rust and C++ Cardiff
- 2026-08-05 | Virtual (Indianapolis, IN, US) | Indy Rust
- 2026-08-07 | Virtual (Girona, ES) | Rust Girona
- 2026-08-10 | Hybrid (Kuala Lumpur, Malaysia) | Rust Malaysia Meetup
- 2026-08-11 | Virtual (Dallas, TX, US) | Dallas Rust User Meetup
- 2026-08-13 | Virtual (Berlin, DE) | Rust Berlin
- 2026-08-13 | Virtual (Nürnberg, DE) | Rust Nuremberg
- 2026-08-14 | Virtual (Girona, ES) | Rust Girona
- 2026-08-18 | Virtual (Washington, DC, US) | Rust DC
- 2026-08-19 | Hybrid (Vancouver, BC, CA) | Vancouver Rust
- 2026-08-20 | Hybrid (Seattle, WA, US) | Seattle Rust User Group
- 2026-08-20 | Virtual (Charlottesville, VA, US) | Charlottesville Rust Meetup
- 2026-08-21 | Virtual (Girona, ES) | Rust Girona
- 2026-08-25 | Virtual (Dallas, TX, US) | Dallas Rust User Meetup
- 2026-08-27 | Virtual (Berlin, DE) | Rust Berlin
- 2026-08-21 | Virtual (Girona, ES) | Rust Girona
- 2026-09-02 | Virtual (Indianapolis, IN, US) | Indy Rust
Africa
- 2026-08-11 | Johannesburg, ZA | Johannesburg Rust Meetup
Asia
- 2026-08-10 | Hybrid (Kuala Lumpur, MY) | Rust Malaysia Meetup
- 2026-08-22 | Bangalore, IN | Rust Bangalore
- 2026-08-22 | Delhi, IN | Rust Delhi
- 2026-08-22 | Noida, IN | SciPy India
- 2026-08-29 | Pune, IN | Rust Pune
Europe
- 2026-08-05 | Köln, DE | Rust Cologne
- 2026-08-06 | Berlin, DE | Rust Berlin
- 2026-08-06 | Oxford, UK | Oxford ACCU/Rust Meetup.
- 2026-08-13 | Switzerland, CH | PostTenebrasLab
- 2026-08-18 | Aarhus, DK | Rust Aarhus
- 2026-08-18 | Leipzig, DE | Rust - Modern Systems Programming in Leipzig
- 2026-08-20 | Frankfurt, DE | Rust Rhein-Main
- 2026-08-27 | Manchester, GB | Rust Manchester
North America
- 2026-08-06 | Mountain View, CA, US | Hacker Dojo
- 2026-08-06 | Saint Louis, MO, US | STL Rust
- 2026-08-11 | New York, NY, US | Rust NYC
- 2026-08-13 | Lehi, UT, US | Utah Rust
- 2026-08-13 | San Diego, CA, US | San Diego Rust
- 2026-08-15 | San Francisco, CA, US | Flower
- 2026-08-18 | San Francisco, CA, US | San Francisco Rust Study Group
- 2026-08-19 | Hybrid (Vancouver, BC, CA) | Vancouver Rust
- 2026-08-19 | San Francisco, CA, US | Bay Area Rust
- 2026-08-20 | Hybrid (Seattle, WA, US) | Seattle Rust User Group
- 2026-08-26 | Austin, TX, US | Rust ATX
- 2026-08-26 | Los Angeles, CA, US | Rust Los Angeles
- 2026-08-27 | Atlanta, GA, US | Rust Atlanta
Oceania
- 2026-08-27 | Melbourne, AU | Rust Melbourne
South America
- 2026-08-08 | São Paulo, SP | Rust-SP
If you are running a Rust event please add it to the calendar to get it mentioned here. Please remember to add a link to the event too. Email the Rust Community Team for access.
Jobs
Please see the latest Who's Hiring thread on r/rust
Quote of the Week
… but I gave up on the idea as the macro rules were turning into a turing complete rust syntax parser
Thanks to miro for the suggestion!
Please submit quotes and vote for next week!
This Week in Rust is edited by:
- nellshamrell
- llogiq
- ericseppanen
- extrawurst
- U007D
- mariannegoldin
- bdillo
- opeolluwa
- bnchi
- KannanPalani57
- tzilist
Email list hosting is sponsored by The Rust Foundation
05 Aug 2026 4:00am GMT
04 Aug 2026
Planet Mozilla
The Rust Programming Language Blog: Enabling the next iteration of the borrow checker on nightly
TL;DR We are enabling the next iteration of the borrow checker (coined Polonius Alpha) on nightly in preparation for stabilization in the next few months.
Whaaaaaat?
Yes! You heard it right! The next iteration of the Rust borrow checker is coming! Rust's first borrow checker ("AST borrowck") was very limited and was phased out in 2019 in favor of NLL, other than a "migrate mode" that was used to provide nice error messages. That migrate mode was finally removed in 2022.
The Polonius borrow checker spun out of the NLL effort in 2018. The initial formulation passed the NLL test suite and accepted (sound) code that NLL did not. However, performance was a critically-limiting factor; generally borrow check was slower than NLL, but certain programs were considerably slower than NLL to the extent that using that implementation/formulation of Polonius was a non-starter. Attempts were made over the years to implement the Polonius formulation in a performant manner, without much luck in addressing the core issues.
In 2023, a new formulation of a Polonius-style borrow checker was imagined that required minimal rearchitecture of the existing NLL implementation and could be extended to allow more code to compile. We had hoped, to try to stabilize this new formulation in 2024; but, various things popped up that delayed this.
But! We're nearly there now! At this point, there are no known remaining issues with the subset coined Polonius Alpha that we intend to stabilize. And, performance is generally acceptable for stabilization (will discuss that a bit below).
So, we are enabling the Polonius Alpha borrow checker on nightly for testing until we stabilize fully later in the year. We're doing this in order to help find:
- Any serious performance regressions we're unaware of
- Unsoundness in the formulation that we haven't thought about
- Any weird diagnostic issues that we need to improve
- Note: we have not yet seen any diagnostic changes
You can report any issues on Github or on Zulip.
Okay, what's new?
The key thing that Polonius Alpha enables that NLL does not is flow-sensitive borrow checking of lifetime outlives relationships.
Perhaps the smallest example demonstrating what will pass with Polonius Alpha but not the current NLL is:
fn reborrow(a: &mut u8) -> &mut u8 {
let b = &mut *a;
if true { b } else { a }
}
However, the example you will see more often is:
fn get_mut_or_default<'r, K: Hash + Eq + Copy, V: Default>(
map: &'r mut HashMap<K, V>,
key: K,
) -> &'r mut V {
match map.get_mut(&key) {
Some(value) => value,
None => {
map.insert(key, V::default());
map.get_mut(&key).unwrap()
}
}
}
The issue is that the Some(value) => value branch causes the borrow checker to think that the borrow returned by map.get_mut(&key) lives for the entire function (because of the &'r mut V return type), even though that borrow isn't live in the None branch. NLL's analysis is flow-insensitive.
Polonius Alpha passes this because its analysis is flow-sensitive, and it knows that the borrow isn't live in the None branch.
Now, Polonius Alpha is not perfect; some programs that would compile under legacy Polonius (the slow original implementation) don't compile with Polonius Alpha. (This is of course why we call it "Polonius Alpha"). For example:
struct X { next: Option<Box<X>> }
fn conditional() {
let mut b = Some(Box::new(X { next: None }));
let mut p = &mut b;
while let Some(now) = p {
if true {
p = &mut now.next;
}
}
}
(As a slight note: we have also found programs that compile with Polonius Alpha but not legacy Polonius, so it's not really a full subset.)
So, what about performance?
Polonius Alpha currently does strictly equal or more work compared to NLL, so we have been paying particular attention to potential performance regressions.
From the top ten thousand crates by downloads on crates.io, we have seen relatively few "significant" regressions, and even crates that have a "significant" regression are typically relatively minimal:

Each point represents a crate within the 10,000 most-downloaded crates. The black line is an arbitrary threshold of significance, set to a 1% regression and quadratically scaled below 30 seconds. Red points are crates that pass this arbitrary regression threshold. X-axis is compile time (for the leaf crate only without dependencies) under NLL; Y-axis is the ratio of compile time under Polonius Time compared to NLL.
If you look at the top five crates, they are:

Outside the top ten thousand crates, we have focused mainly on crates with many borrows. The worst case we've seen is a 2-3x regression.
We have done some initial triage of the causes of these regressions and are thinking about the best way to fix them. Though, overall we think these regressions are fairly reasonable even if we can't fix them, given how rare and relatively minimal they are compared to the additional power Polonius Alpha brings over NLL.
I really don't want this. How do I opt-out?
To reiterate: this is only being enabled on nightly. But if you want to disable Polonius Alpha, and only use the stable NLL, you can pass -Zpolonius=off to rustc, use RUSTFLAGS=-Zpolonius=off, or with a project's .cargo/config.toml configuration file:
[target.x86_64-unknown-linux-gnu]
rustflags = ["-Zpolonius=off"]
If you have to do this, for some reason, please do tell us why on Github or on Zulip.
What's next?
Over the next few months, we will be monitoring Github and Zulip for any reported issues about Polonius Alpha. We will also be working to address known performance regressions. Finally, we will be working on internal documentation about the implementation. All prior to stabilization. Then, we are aiming to stabilize prior to the end of the year!
Although some programs that we want to compile don't work with Polonius Alpha (nor NLL today), we don't currently have any concrete plans to continue active feature work on the Polonius implementation after the stabilization of Polonius Alpha. We expect to continue to optimize the implementation and address any performance regressions for a little while. We will likely come back to Polonius feature-work at some point, but given that Polonius Alpha solves the most-encountered borrow-check issues, we are shifting our time to other high-priority work for the near future.
04 Aug 2026 12:00am GMT
03 Aug 2026
Planet Mozilla
Firefox Tooling Announcements: Firefox Profiler Deployment (August 3, 2026)
The latest version of the Firefox Profiler is now live! Check out the full changelog below to see what's changed:
Highlights:
- [Nazım Can Altınova] Add an "apply source map" button to the profile info panel (#6200)
- [Nazım Can Altınova] Show markers that are in the committed range only in
profiler-cli thread markers(#6222) - [Alex Thayer] Allow exporting argument values in profiles (#5914)
Other Changes:
- [nirmaladvani] remove unused collectSourceIndicesFromThreads #6086 (#6219)
- [fatadel] Create the IPC track from the timeline-ipc schema display location (#6213)
- [Markus Stange] Allow specifying the stage reliost symbol server (#6228)
- [Nazım Can Altınova]
Sync: l10n → main (August 3, 2026) (#6234) - [Nazım Can Altınova] Bump profiler-cli version to 0.7.0 (#6235)
Big thanks to our amazing localizers for making this release possible:
- de: Ger
- de: Ralf Duehnfahr
- el: Jim Spentzos
- en-GB: Ian Neal
- fy-NL: Fjoerfoks
- ia: Melo46
- it: Francesco Lodolo [:flod]
- nl: Mark Heijl
- ru: Valery Ledovskoy
- sv-SE: Andreas Pettersson
- sv-SE: Luna Jernberg
- zh-TW: Pin-guang Chen
Find out more about the Firefox Profiler on profiler.firefox.com! If you have any questions, join the discussion on our Matrix channel!
1 post - 1 participant
03 Aug 2026 3:25pm GMT
31 Jul 2026
Planet Mozilla
The Servo Blog: June in Servo: real world compat, media queries, SharedWorker, and more!
Servo 0.4.0 contains all of the changes we landed in June, which came out to yet another record 558 commits (April: 534, May: 391). For security fixes, see § Security.

We've shipped several new web platform features:
- 'attr()', in experimental mode (@Loirooriol, #45041)
- 'image(<color>)', 'closest-corner', and 'farthest-corner' in 'ellipse()' and 'circle()' (@Loirooriol, #45421)
- 'calc()' and other mathematical expressions can now be resolved later than parse time, e.g.
sign(1em - 32px)(@Loirooriol, #45421) - 'font-feature-settings' in '@font-face' (@simonwuelker, #45393)
- '@media (device-width)', '@media (device-height)', '@media (height)', '@media (aspect-ratio)', and their min- and max- variants (@jdm, @mrobinson, @nicoburns, @jschwe, #44978, #45707, #45490)
- '@media (orientation)' (@nicoburns, #45707)
- '@media (pointer)' and '@media (any-pointer)' (@nicoburns, #45681)
- '@media (hover)' and '@media (any-hover)' (@nicoburns, #45681)
Plus a bunch of new DOM APIs:
- SharedWorker (@Taym95, #45786)
- console.dir() (@Taym95, #45109)
- customElementRegistry on Document and ShadowRoot (@shubhamg13, #45872)
- initialize() on CustomElementRegistry (@shubhamg13, @yezhizhen, #45903)
- new CustomElementRegistry() (@shubhamg13, #45791, #45550)
- textStream() on Request, Response, and Blob (@yezhizhen, #45864, #45861)
- setPointerCapture(), releasePointerCapture(), hasPointerCapture() on Element (@webbeef, #45048)
- ontouchstart, ontouchend, ontouchmove, ontouchcancel on Element (@stevennovaryo, #45049)
- crypto.subtle.digest() for KT128 and KT256 (@kkoyung, #45699)
- crypto.subtle.getPublicKey() for ML-KEM and ML-DSA (@kkoyung, #45252)
This is another big update, so here's an outline:
You can help!
Servo is steadily becoming a bigger and busier project every month, and by June 2026, we've been reading through over four times the commits as we did when we started in September 2023.

This is hard work, particularly since there are things we need to know that are often difficult to answer just by reading the changes:
-
Who does the change affect, if anyone? Does it affect users, Servo developers, embedders, or some other group?
-
What observable difference does the change make, if any?
-
Does the feature require any preferences to be enabled, or is it enabled for everyone by default?
-
Are any real-world websites affected by the change?
-
What issue or broader project is the change related to? This question is answered by
Fixes: #xxxxxorPart of: #xxxxxin the PR description.
Thanks to an initiative by @jdm, it's now easier than ever for you to help us answer those questions, using the Servo Highfive bot! If you're working on a pull request that you think might be interesting for the next monthly update, even if you're not 100% sure, tell us about it by following the steps below:
-
You add the monthly update label to your pull request, or comment
@servo-highfive monthly update -
Highfive posts a comment asking you some questions
-
You answer those questions in a comment containing
@servo-highfive monthly update answer
Security
Servo's JS runtime, SpiderMonkey 140.10.1, had several security bugs that have been fixed in Servo 0.4.0 with the update to SpiderMonkey 140.11.0 (@jschwe, #45584). For more details, see CVE-2026-8388, CVE-2026-8391, CVE-2026-8974, CVE-2026-8975, and MFSA 2026-48.
Several more security bugs in Servo's JS runtime have been fixed in Servo 0.4.0 with the update to SpiderMonkey 140.12.0 (@jschwe, #45766). The exact CVEs that apply to us are not yet known, but for more details, see MFSA 2026-58.
RSA operations in SubtleCrypto now do modular exponentiation in constant time (@kkoyung, #45631). Please note that our RSA implementation is currently vulnerable to the Marvin Attack - for more details, see RUSTSEC-2023-0071.
ML-DSA operations in SubtleCrypto now do the Decompose step in constant time, fixing RUSTSEC-2025-0144 (@kkoyung, #45294).
We've fixed an HTML injection bug (XSS) in file:/// directory listings, which affected file names containing </script> (@sahvx655-wq, #45510).
Real world compat
Layout correctness has significantly improved on lichess.org, and many websites have become a lot more readable thanks to our improved handling of variable fonts (@simonwuelker, #45768), including Zulip (servo.zulipchat.com) and Speedtest (speedtest.net).



Many websites worked in Servo even before version 0.4.0, including Google Photos (photos.google.com) and Cash Converters (cashconverters.com.au), and continue to work in version 0.4.0. Other websites, like Google Maps (maps.google.com) and OpenStreetMap (www.openstreetmap.org), render well but have some issues with interactivity.
We're interested to hear how well your favourite websites run in Servo! Report successes in this Zulip thread, and failures in our GitHub issues.
Work in progress
We're implementing the more powerful version of 'attr()' that can be used anywhere, not just in 'content', under --pref layout_css_attr_enabled (@Loirooriol, #45041, #45421, #45495, #45752).
WebGPU support has improved, under --pref dom_webgpu_enabled:
- implemented copyExternalImageToTexture() on GPUQueue (@sagudev, #45646)
- implemented createQuerySet() on GPUDevice and resolveQuerySet() on GPUCommandEncoder (@sagudev, #45644)
- implemented pushDebugGroup(), popDebugGroup(), and insertDebugMarker() on GPUCommandEncoder, GPUComputePassEncoder, and GPURenderPassEncoder (@jschwe, #45489)
- more conformant GPUTexture (@sagudev, #45300)
- more conformant requestAdapter() on GPU (@sagudev, #45424)
- more conformant secure context enforcement (@sagudev, #45279)
All of the features above are enabled in servoshell's experimental mode.
We've made more progress towards accessibility support, under --pref accessibility_enabled (@alice, @delan, #45555, #45554, #44949).
We've started implementing visible and interactive text selection (@mrobinson, @SimonSapin, #46107), one of the most long-awaited features of any web browser. Stay tuned!
We've also started working on Web Animations, under --pref dom_web_animations_enabled (@simonwuelker, #45522, #45983), as well as webkitRelativePath on File, under --pref dom_entries_api_enabled (@yezhizhen, #45666).
Rust doesn't have a stable ABI, so it has generally not been possible to embed Servo in another application without building Servo from source. To make it possible, we've started designing a wrapper C API that will let you consume Servo as a prebuilt shared library using the stable and ubiquitous C ABI (@mukilan, #44984). Eventually the idea is that we'll create a wrapper Rust API around that wrapper C API, so you can have both the ergonomics of Rust and the build simplicity of C.
Embedding API
New in the Servo API:
Breaking changes:
WebView::send_errorhas been removed (@mukilan, #45502) - this method was always meant to be internal, and has become unused after we introduced the new WebView- and WebViewDelegate-based API
We've improved the docs for WebView, WebViewDelegate, JSValue, AlertDialog, AllowOrDenyRequest, AuthenticationResponse, BluetoothDeviceDescription, ConfirmDialog, ConsoleLogLevel, CreateNewWebViewRequest, EmbedderControl, EmbedderControlResponse, FilePicker, Image, JavaScriptErrorInfo, NavigationRequest, PermissionRequest, PixelFormat, PromptDialog, ProtocolHandlerRegistration, ProtocolHandlerUpdateRegistration, Scroll, SelectElement, SelectElementRequest, and WebViewVector (@mukilan, #45282, #45467).
For users and developers
In servoshell:
-
the Android version now requires Android 13+ (@jschwe, #46104)
-
the desktop version now lets you drag and drop files to open them (@simonwuelker, #45454)
-
the desktop version now lets the tab bar scroll horizontally if you have too many tabs open, but from one tab hoarder to another, maybe you should reconsider having so many tabs open (@Nylme, #44884)
-
the desktop version enters fullscreen on the monitor containing the window, even if you've moved it to a different monitor (@rhit-kapilaar, #45556)
-
the desktop UI is more performant, resizes more smoothly, and no longer gets stuck in hovered states (@mrobinson, #45289, #45456, #45290)
-
<select multiple> should now be interactable on all desktop platforms (@alexcat3, #45419)
-
localhost:<port>now implieshttp://in the location bar and on the command line, rather than treatinglocalhost:as an unsupported URL scheme (@SteveSharonSam, #45729, #45832)
When using the Firefox DevTools:
-
in the Console tab, uncaught exceptions are reported correctly (@jdm, #45549)
-
in the Console and Debugger tabs, you can now inspect the elements of nested arrays and the entries of Map objects (@atbrakhi, #45435, #45514, #45767)
-
in the Debugger tab, the Scopes panel now shows any '(uninitialized)' variables, the value of
this, and the global scope (@atbrakhi, @eerii, #45824, #45517)
We've fixed some build issues on riscv32, riscv64, and arm64 (@fxzjshm, @saschanaz, #45285, #45731), and modernised servoshell for Android to use Compose UI and Kotlin (@veyndan, #45923, #45932, #45941, #45982, #45985, #46015, #46035, #46037, #46046, #46053, #46061, #46071, #45641, #45643, #45650, #45665, #45671, #45676, #45679, #45683, #45712, #45713, #45734, #45738).
For developers of Servo itself:
-
mach try --helpnow lists all of the kinds of try jobs you can run (@shubhamg13, #45607) -
mach test-wpt --update-expectationslets you run Web Platform Tests and update expectations in a single command (@TimvdLippe, #45521), rather than having to runmach test-wpt --log-raw <path>followed bymach update-wpt <path>
More on the web platform
To allow for more performant scrolling, 'wheel' events are no longer .cancelable unless there are one or more non-passive event listeners (@kunalmohan, #45667). Note that like in Firefox, 'wheel' events are passive by default.
'dotted', 'dashed', and 'wavy' text decorations are now continuous across element boundaries (@mrobinson, #45726).
We've improved the conformance of <dialog> (@skyz1, @mrobinson, #45825, #45761), <iframe sandbox> (@cychronex-labs, #45880), <input minlength> and <input maxlength> (@skyz1, #45705), CSS gradients (@mrobinson, #43945), 'font-style' and 'unicode-range' in '@font-face' (@Loirooriol, #45821), FontFaceSet (@mrobinson, #45390, #45382), HTMLInputElement (@steigeo, #45416), IntersectionObserver (@jdm, #45655, #45659, #45680), new Response() (@yezhizhen, #45953), URL.createObjectURL() and URL.revokeObjectURL() (@yezhizhen, #45182, #45417), and ECDSA and Ed25519 in SubtleCrypto (@kkoyung, #45833, #46017).
We've fixed bugs related to <input hidden> (@mrobinson, #45750), 'animation-delay' (@yezhizhen, #45013), 'clip-path' (@Loirooriol, #45468, #45373), 'tab-size' (@SimonSapin, @mrobinson, #45309), 'width' and 'height' (@RichardTjokroutomo, #44627), 'box-shadow: inset' (@Loirooriol, #45620), 'animationiteration' events (@Loirooriol, #45990), 'click' events (@mrobinson, #45751), 'load' events (@jdm, #45883), 'error' events in Worker global scopes (@Gae24, #45829), and document.getElementById() (@mrobinson, #45433).
Garbage collection safety
We use a RefCell-based mechanism to store many of our DOM types in other DOM types, enforcing Rust's "aliasing xor mutability" rule at runtime by panicking if the rule is violated. But when garbage collection happens, we need to borrow() each DomRefCell to trace the references, and this is the source of many panic bugs. To fix that whole class of bugs, we initially created CanGc, a marker type that would annotate the code paths where GC can occur, in conjunction with custom static analysis (@jdm, #33140).
With the Rust type system we can do even better, if we flip that around and require any borrow_mut() call to prove that GC can not occur by passing a NoGC marker value. We can then require that a &NoGC must be borrowed from a &JSContext (which blocks GC) and not a &mut JSContext (which allows GC), taking advantage of how Rust references work without needing any custom static analysis.
We have a large codebase that needs to be migrated in parts, so for now we've created the new method safe_borrow_mut() (@sagudev, #46050). We also need to update all of our script-related code to borrow our safe JSContext wrapper, rather than creating an owned JSContext on the spot.
This continues our long-running effort to use the Rust type system to make Servo's integration with SpiderMonkey safer and more reliable (@Gae24, @Keerti707, @Narfinger, @TimvdLippe, @sagudev, @guptapiyush16, @ivomurrell, @kunalmohan, @skyz1, #45230, #45436, #45503, #45617, #45711, #45797, #45800, #45858, #45884, #45937, #45902, #45968, #45977, #45991, #46003, #46005, #46084, #45548, #45552, #45590, #45909, #45912, #45943, #46089, #46117, #46114, #45320, #45324, #45328, #45340, #45381, #45385, #45410, #45392, #45409, #45604, #45616, #45618, #45627, #45636, #45662, #45663, #45675, #45674, #45677, #45684, #45735, #45807, #45810, #45816, #45818, #45828, #45838, #45836, #45837, #45840, #45841, #45857, #45859, #45862, #45875, #45887, #45931, #45964, #45935, #45987, #45988, #46001, #46040, #46051, #46057, #46106, #46125, #45678, #46002, #45845, #45645, #45673, #45259, #45817, #45822, #45876, #45877, #45891).
Performance and stability
NoGC was designed to prevent dynamic borrow failures, but it also enables some performance optimisations! If we can prove that garbage collection is impossible in some part of Servo, we can often avoid rooting JavaScript objects when interacting with them within that region of code. This has allowed us to reduce overheads by over 1% in the layout process and in HTMLCollection (@Narfinger, #46092, #45582).
Our memory usage has improved, with BoxFragment now 17% smaller (288 → 240 bytes on amd64) and ShapeCacheEntry now smaller too (@SimonSapin, @mrobinson, @simonwuelker, #45183, #45496).
We've fixed some nasty memory leaks when reloading and in 2D canvases (@Taym95, @sagudev, @jschwe, #45455, #45261, #45414).
Speaking of which, 2D canvases now use up to 23% less power (@yezhizhen, #45301), and we now avoid rasterising the same SVG more than once (@Narfinger, @jschwe, #44805).
Servo now decodes all images asynchronously and fills image caches asynchronously, leaving script threads (web content processes) more time for other work (@Narfinger, #45542, #44483). On top of that, we've improved incremental layout (@mrobinson, @Loirooriol, #45411) and reduced reflows in IntersectionObserver (@jschwe, #45986).
We've started working on incremental updates for the stacking context tree, and as a side effect, we've made some layout-bound microbenchmarks up to 10% faster (@mrobinson, @Loirooriol, #45208).
We've also reduced allocations, copies, GC rooting steps, and other operations in many parts of Servo (@Narfinger, @SimonSapin, @mrobinson, @Loirooriol, #45506, #45969, #45940, #45760, #46090, #45335, #45413, #45511).
For several months, Frédéric (@fred-wang) has been fuzzing for Servo bugs, and thanks to his work we've fixed sixteen (16) crash bugs in June, affecting <iframe>, <slot>, <link onerror>, 'animation', 'clip-path', 'content', 'rotate', 'transition', 'transform-style', 'display: contents', 'overflow: clip', CSSKeyframesRule, FontFace, stop() on Window, document.elementFromPoint(), and the DOM tree (@mrobinson, @Loirooriol, @fred-wang, #46031, #46027, #46054, #46058, #46016, #46028, #46033, #45287, #45951, #45634, #45629, #46110, #46094, #45799, #45611, #45682, #45788, #45612, #45834).
We've also fixed crash bugs related to IPC failures, HTMLInputElement, Range, the DevTools Debugger tab, and when servoshell is built with --features native-bluetooth (@jschwe, @Taym95, @mrobinson, @atbrakhi, @mukilan, #45311, #45619, #45765, #45513, #45702).
New contributors
A special thanks to the following people for landing their first patch in Servo:
- Deepam Goyal (@Deepam02, #44836)
- Mark (@Mark-Boger, #45486)
- Mr SheerLuck (@MrSheerluck, #45557)
- Psychpsyo (Cameron) (@Psychpsyo, #45494)
- TusharSariya (@TusharSariya, #43663)
- Adam Sharif (@adamsharifc, #45551)
- Akash Ravikumar (@ak4shravikumar, #45736)
- Sean Cunneen (@alexcat3, #45419)
- Abdul Wahab Melethil Shibu (@cychronex-labs, #45880)
- darkdragon-001 (@darkdragon-001, #45267)
- Frédéric Wang Nélar (@fred-wang, #45834)
- fxzjshm (@fxzjshm, #45285)
- Piyush Gupta (@guptapiyush16, #45845)
- Ivo Murrell (@ivomurrell, #45645)
- rhit-kapilaar (@rhit-kapilaar, #45556)
- sahvx655-wq (@sahvx655-wq, #45510)
- Kagami Sascha Rosylight (@saschanaz, #45731)
- shangguanmachine-dot (@shangguanmachine-dot, #45310)
- Glenn Skrzypczak (@skyz1, #45471)
- Oskar Steiger (@steigeo, #45416)
- Veyndan Stuart (@veyndan, #45326)
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 7681 USD/month (+0.2% from May) 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 (same as May) 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 join@servo.org.
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.
31 Jul 2026 12:00am GMT
30 Jul 2026
Planet Mozilla
Thunderbird Blog: Mobile Progress Report: July 2026

Thunderbird Mobile is moving forward with large steps on both platforms we support. On iOS, we're working on the very foundation of a new app-our first built from scratch-and continuing to make progress in bringing the Thunderbird for iOS app to the App Store. For Android, it's a matter of updating what we have in place to make it easier to use, more reliable, and more efficient. Both platforms are rushing forward to deliver exactly what our users expect from us.
iOS
Starting off with iOS, we've focused on a few vital components. This includes the compose screen, account drawer, and OAuth, which allows users to add their accounts using the sign in page of their email provider. For the compose view, our HTML rich text editor is coming along nicely. We forked a WYSIWYG repository, Infomaniak's "swift-rich-html-editor," to create a rich text view for both composing and editing. We also added view headers, fixed a bug where we weren't applying links properly to the DOM, and began porting a proof of concept over to the main app code. This will eventually become the compose view for the final app. We also started the technical design phase for the new account drawer design.
Android
The Android team has been busy looking into drastic changes to the app to make it more user-friendly, faster, and more reliable. We're directly targeting feedback we've received. We're also continuing work on developer-friendly features to make contributing to the project easier and faster.
Database Rewrite
We've started our large database refactor with a tentative selection of Room. We chose this for a number of reasons, including performance, easier writing of data entities, and the ease of introduction for new engineers. Room is common in Android development, which means we can more quickly onboard new contributors with it. We'll have an RFC out by the end of August detailing how we'll implement the new database.
So why are we rewriting the database? It's the source of a number of issues with the app. Everything runs through it, from fetching locally-stored drafts, triggering notifications for new messages, syncing, reliability, and even power consumption. By updating the database, we make it possible to drastically improve everything in the app it touches, which is to say, everything.
Feature Flags
Developers will also be happy to know we're improving the feature flag process. We've completed an RFC for a new schema and began work on the technical documentation. We're looking to develop a local feature flag library that will use OpenFeature and eventually enable remote feature flag management, though that's not our short term goal. For now, we want to make it easier to create and modify feature flags across build types, without needing to edit so many files to do so. In the future, however, this will make it easier for us to roll out releases, updated features, and even rolling back features that may have issues without having to wait for the app release and approval cycle. It allows us to make a more reliable app with faster feature implementations.
Notifications
Finally, we've heard that our users do not like how we handle notifications. We've been investigating reported bugs and working to find a path forward that allows us to use previous work to improve notifications.
We're also looking into a key complaint: setting up notifications and "push" (IMAP Idle) notifications is just too difficult. We don't make it easy enough for users to set up their notifications and ensure they get email notifications when their email server reports updates. Users have made it clear: that has to change.
We're currently discussing options with design to consolidate some settings, bring other settings to the forefront, and will be working next month to activate "push" notifications by default for new accounts that support it.
We know notifications are a cause of headaches, even for those who understand how to use the app's existing features, so we want to address them as quickly as possible. We'll also focus on identifying issues and helping our users report problems with notifications in detail with user-enabled and anonymous logging that can help us see why a notification did not show for a new email if they want to help us work through it.
Bolt Design Library
Android has also begun the work of moving our Bolt design library out of the app to serve as a standalone library. Currently, we've pulled out the foundation layer for mobile that includes fonts, colors, spacing, and other repeated values. Eventually we'll use WebASM to render the design system and allow contributions directly to the design system, without needing to touch the Android app, potentially allowing it to be platform independent.
Community
Two crashes were caught in the beta, including a crash related to relative date formats and another to webviews. We want to thank our amazing community of beta testers who helped us catch these before they made it to a full release. Our community contributors have also directly fixed bugs, like issues scrolling horizontally in message views, fixing a button that couldn't be seen properly in dark mode, fixing an issue with the wrong number of messages in confirmation dialogs, and updates to our historical changelog data to be in a more readable and usable format. We can't thank our community of testers, contributors, and users enough for the work they put in helping us make Thunderbird a better email client.
We couldn't do what we do without you, and, as always, thank you for being part of the Thunderbird community. Here's to another month making the best email client we can, together!
- Danielle G. (she/her), Senior Android Engineer
The post Mobile Progress Report: July 2026 appeared first on The Thunderbird Blog.
30 Jul 2026 7:00pm GMT
29 Jul 2026
Planet Mozilla
About:Community: Community Roundup: Project Nova, Tab Groups & more
Firefox keeps evolving, and the community continues to play a big part in shaping what's next.
In this edition, you can get an early look at Project Nova through our latest foxfooding opportunity, explore Tab Groups on Android, join the conversation on Mozilla's latest browser choice research, and meet an Outreachy contributor whose journey reminds us why open source thrives through collaboration.
Get ready to dive in!
Hot from the oven: Join Project Nova foxfooding
We teased it in the last edition, and now it's here. Project Nova has finally arrived on Firefox Nightly, and you're invited to be an early tester! Get a look at Firefox's refreshed design as we put the finishing touches on the experience ahead of its broader release later this year. If you're curious about what's coming next, this is your chance to try it out, share your feedback, and help shape the final product.
Monthly Community Call today!
Want to ask questions directly to the people working on Firefox? Join us for today's Monthly Community Call, where we'll discuss Project Nova and Firefox performance feature with members of the teams working on these projects. Join the call today, July 29, 2026, at 5:00 PM UTC, and bring your questions!
Tab groups arrives on Android
You've been calling out for tab group functionality on Firefox mobile and now Tab Groups have officially arrived on Firefox for Android! Tab Groups make it easier to organize related tabs into color-coded groups for work, travel, shopping, research, or whatever you're browsing. Give it a try, and if you have ideas for how it could be even better, let us know on Mozilla Connect.
From the Reddit Community
Mozilla recently shared new independent research examining how browser choice is shaped by the design of operating systems. The report explores the obstacles users can encounter when downloading, setting, or continuing to use their preferred browser, and argues that people should be able to choose their browser without unnecessary friction. Read the report, join the discussion, and share your perspective!
And of course, thanks to you for choosing Firefox!
Community spotlight
Every contributor starts somewhere. In a recent blog post, Ananya Shree Sharma reflects on her journey through the Outreachy internship with Firefox. From navigating a large open source codebase for the first time to collaborating with mentors, learning new skills, and shipping meaningful improvements. Her story is a reminder that open source is as much about learning, mentorship, and community as it is about writing code. If you've ever wondered what it feels like to contribute to Firefox, Ananya's reflections offer an inspiring look at the experience and the people who make it possible.
P.S.
Enjoyed these updates? Subscribe to the Mozilla Community Newsletter and get the latest updates delivered straight to your inbox.
29 Jul 2026 9:04am GMT
This Week In Rust: This Week in Rust 662
Hello and welcome to another issue of This Week in Rust! Rust is a programming language empowering everyone to build reliable and efficient software. This is a weekly summary of its progress and community. Want something mentioned? Tag us at @thisweekinrust.bsky.social on Bluesky or @ThisWeekinRust on mastodon.social, or send us a pull request. Want to get involved? We love contributions.
This Week in Rust is openly developed on GitHub and archives can be viewed at this-week-in-rust.org. If you find any errors in this week's issue, please submit a PR.
Want TWIR in your inbox? Subscribe here.
Updates from Rust Community
Newsletters
Project/Tooling Updates
- afrim 0.7.0: a generic input method framework
- Sharing Rust build work across Cargo worktrees with cargo-reapi
- exiftool-rs 0.7.0: localizing ExifTool's PrintConv values, not just its labels
- Announcing SeaORM 2.0
- kobe 0.37.0: easier to deploy and install
- kache 0.12.0: pluggable remotes, smarter GC, sharper diagnostics
- Progress toward compiling Linux with gccrs
- flodl 0.7.0: one dashboard view, repeated at every level
- samkhya 1.2.1 - the join-cardinality ceiling becomes provable
- BrewFS: a Rust and JuiceFS-like distributed filesystem
Observations/Thoughts
- Improving std::simd::swizzle_dyn
- Query cycles: A compiler murder mystery
- GDPatch: a versatile Godot mod loader
- Memory Safety Absolutists
- C++ to Rust Migration
- High-Performance Flat 2D Arrays in Rust with SIMD, L1 Cache
- Building Java-Rust Microservices with TeaQL: Models, Events, and Audit Intent
- How We Cut a Trading Bot's Reaction Time from ~2 Seconds to Milliseconds - by Moving Only the Hot Path to Rust
- ESP32 Server: Distributing HTTP/2 streams over TLS
- [video] Rust Berlin Talks · 23/07/2026
Rust Walkthroughs
- No Tokens Yet Does Not Mean a Rust LLM Stream Is Safe to Retry
- [series] Rama 101.2: Core Concepts
- [video] [series] What's Inside Axum?
Crate of the Week
This week's crate is cargo-efmt, a drop-in replacement for cargo fmt to support .editorconfig.
Thanks to kleines Filmröllchen for the self-suggestion!
Please submit your suggestions and votes for next week!
Calls for Testing
An important step for RFC implementation is for people to experiment with the implementation and give feedback, especially before stabilization.
If you are a feature implementer and would like your RFC to appear in this list, add a call-for-testing label to your RFC along with a comment providing testing instructions and/or guidance on which aspect(s) of the feature need testing.
No calls for testing were issued this week by Rust, Cargo, Rustup or Rust language RFCs.
Let us know if you would like your feature to be tracked as a part of this list.
Call for Participation; projects and speakers
CFP - Projects
Always wanted to contribute to open-source projects but did not know where to start? Every week we highlight some tasks from the Rust community for you to pick and get started!
Some of these tasks may also have mentors available, visit the task page for more information.
- No Calls for participation were submitted this week.
If you are a Rust project owner and are looking for contributors, please submit tasks here or through a PR to TWiR or by reaching out on Bluesky or Mastodon!
CFP - Events
Are you a new or experienced speaker looking for a place to share something cool? This section highlights events that are being planned and are accepting submissions to join their event as a speaker.
- No Calls for papers or presentations were submitted this week.
If you are an event organizer hoping to expand the reach of your event, please submit a link to the website through a PR to TWiR or by reaching out on Bluesky or Mastodon!
Updates from the Rust Project
570 pull requests were merged in the last week
Compiler
- apply RemoveNoopLandingPads post-monomorphization
- closures inherit
#[optimize]from the enclosing function by default - fix
boolcalling convention for aarch64, etc - optimize
escape_string_symbol() proc_macro: Fixcfg_attrinner attrs in file modules- resolve: more preperation work for parallelizing the import resolution loop
- stabilize c-variadic function definitions
Library
- constify
vec![1, 2, 3]macro - core: implement
Rngfor references - define a
Simdtype inminicore - implement
CovariantUnsafeCell - implement
str::copy_from_str - iter: extend
step_byspecialization to coverStepBy<RangeIter<{integer}>> - move
std::io::bufferedtoalloc::io - num: improve error messages for
TryFromIntError - str: add ASCII fast path to
word_to_titlecase - switch implementations of
thread_local!for WASI
Cargo
- add haiku's dylib path
diag: bound transitive unused dependency traversalgit: Hide git fetch output without progressgit: Suggest libgit2 if git-cli failstest: gate trim-paths tests on split debuginfo supporttoml: warn on hyphenated lint names and duplicates- allow setting
-Zembed-metadatavalue from the config - enable build-dir layout v2 on nightly by default
- zsh completion: Add
-pand--packageflags forcargo add
Rustfmt
- allow file not found errors for external mods annotated with
#[my_macro] - discover modules via
cfg_select!
Rustdoc
- add paths for linked associated items
- Retrieve
cfg_attrinformation for derived impls fordoc_cfgfeature - only build extern trait impls if needed
- only inline impls for local primitives
Clippy
- add
EULER_GAMMAandGOLDEN_RATIOtoapprox_constant - add
assert_is_emptylint - apply safety comment to compound assignment statement
blocks_in_conditions: Don't lint if the block creates temporarie…- call
in_external_macroafter running other checks in various places - do not trigger
clippy::exitwhen expression comes from an external macro duration_suboptimal_units: print the complete method name in the suggestion- extend
branches_sharing_codeto match arms with a shared tail min_ident_charslint short idents even if follows trait namingmultiple_unsafe_ops_per_block: false positive in with taking an reference to a static, but not reading/writing it- fix
four_forward_slashesfalse positive on inner doc comments lint-page: add accessible labels to filters- new lint:
nonnull_unchecked_on_box_ptr - perf: avoid per-call type and path work in
unnecessary_mut_passed - perf: find tab groups in doc comments without allocating
- rewrite
EndianByteslint pass
Rust-Analyzer
- add diagnostic for
structpatterns which don't specify sub-patterns for its fields - add parentheses for invert general expression
- attach db on worker threads in parallel analysis-stats inference
- change unsupported toolchain version to match reality
- discover protocol should only parse stdout
- do not detect
#[rust_analyzer]as#[rust_analyzer::rust_fixture] - don't offer
replace_qualified_name_with_useon an unqualified path - don't panic on a qualified path whose trait is not a trait
- don't pick a discriminant type larger than typeck's
- fix stale lock file
- fix
.zip(None)call - give
impl_trait_with_diagnosticsa cycle result - make analysis-stats progress bar Unicode-safe
merge_importspanic on invalid paths- panic on macro-defined structs with unknown fields
- prefer
allocoverstdpaths whenpreferNoStdis set - record obligation chain for unimplemented trait diagnostics and show it
- replace detach with delete for
ast::IdentPat - resolve path on all namespace on
resolve_path - respect
references.exclude[Tests/Imports]in references lens - scoped lazy priming
- support inactive-code diagnostic in macros
- uses bool instead pat ty in guard
Rust Compiler Performance Triage
Several large improvements landed in the past week:
- rustdoc is on average roughly 16% faster across all of our doc benchmarks:
- rustdoc: Only inline impls for local primitives, 7% faster doc builds
- rustdoc: Only synthesize auto/blanket impls for documented items, another 7% faster doc builds
- rustdoc: Only build extern trait impls if needed, another 10% faster doc builds
- Early removal of no-op panic handling in debug builds. This speeds up Cargo by ~4% in cycle count.
- Optimize escape_string_symbol() sped up large
include_bytes!/include_str!through changes to string escaping, avoiding a regression in upcoming LLVM 23 upgrade.
Great to see so many improvements!
Triage done by @simulacrum. Revision range: d527bc9b..ad0c9dce
Approved RFCs
Changes to Rust follow the Rust RFC (request for comments) process. These are the RFCs that were approved for implementation this week:
- No RFCs were approved this week.
Final Comment Period
Every week, the team announces the 'final comment period' for RFCs and key PRs which are reaching a decision. Express your opinions now.
Tracking Issues & PRs
- Shallow resolve ty and const vars to their root vars, attempt 2
- Ensure inferred let pattern types are well-formed
- stabilize
c_variadic_naked_functions - lint against repeated repr attributes
- Stabilize passing 128-bit integers via vector registers with
asm!on x86 - Add new
invalid_markdown_tablerustdoc lint - allocations: document that they can be read-only
- allocations are allowed to grow (but not shrink)
- Tracking Issue for
bool::toggle - Tracking Issue for const_btree_len
- Wasm proc macro support
-
Optimize repr(Rust) enums by omitting tags in more cases involving uninhabited variants.
- Proposal for Adapt Stack Protector for Rust
- feat(profile): Add built-in profile debug
- feat(toml): allow overriding inherited default-features in 2024
No Items entered Final Comment Period this week for Language Reference, Language Team, Leadership Council or Unsafe Code Guidelines. Let us know if you would like your PRs, Tracking Issues or RFCs to be tracked as a part of this list.
New and Updated RFCs
Upcoming Events
Rusty Events between 2026-07-29 - 2026-08-26 🦀
Virtual
- 2026-07-30 | Virtual (Berlin, DE) | Rust Berlin
- 2026-07-31 | Virtual (Girona, ES) | Rust Girona
- 2026-08-01 | Virtual (Kampala, UG) | Rust Circle Meetup
- 2026-08-02 | Virtual (Dallas, TX, US) | Dallas Rust User Meetup
- 2026-08-03 | Virtual (Global) | Rust Maven
- 2026-08-04 | Virtual (London, UK) | Women in Rust
- 2026-08-04 | Virtual (Tel Aviv-yafo, IL) | Rust 🦀 TLV
- 2026-08-05 | Virtual (Cardiff, UK) | Rust and C++ Cardiff
- 2026-08-05 | Virtual (Indianapolis, IN, US) | Indy Rust
- 2026-08-07 | Virtual (Girona, ES) | Rust Girona
- 2026-08-11 | Virtual (Dallas, TX, US) | Dallas Rust User Meetup
- 2026-08-13 | Virtual (Berlin, DE) | Rust Berlin
- 2026-08-13 | Virtual (Nürnberg, DE) | Rust Nuremberg
- 2026-08-14 | Virtual (Girona, ES) | Rust Girona
- 2026-08-18 | Virtual (Washington, DC, US) | Rust DC
- 2026-08-19 | Hybrid (Vancouver, BC, CA) | Vancouver Rust
- 2026-08-20 | Hybrid (Seattle, WA, US) | Seattle Rust User Group
- 2026-08-20 | Virtual (Charlottesville, VA, US) | Charlottesville Rust Meetup
- 2026-08-21 | Virtual (Girona, ES) | Rust Girona
- 2026-08-25 | Virtual (Dallas, TX, US) | Dallas Rust User Meetup
Africa
- 2026-08-11 | Johannesburg, ZA | Johannesburg Rust Meetup
Asia
- 2026-08-22 | Bangalore, IN | Rust Bangalore
- 2026-08-22 | Delhi, IN | Rust Delhi
- 2026-08-22 | Noida, IN | SciPy India
Europe
- 2026-07-29 | Poland, PL | Rust Poland
- 2026-07-30 | Copenhagen, DK | Copenhagen Rust Community
- 2026-07-30 | Manchester, UK | Rust Manchester
- 2026-08-06 | Oxford, UK | Oxford ACCU/Rust Meetup.
- 2026-08-18 | Aarhus, DK | Rust Aarhus
- 2026-08-18 | Leipzig, DE | Rust - Modern Systems Programming in Leipzig
- 2026-08-20 | Frankfurt, DE | Rust Rhein-Main
North America
- 2026-07-30 | Atlanta, GA, US | Rust Atlanta
- 2026-08-01 | Boston, MA, US | Boston Rust Meetup
- 2026-08-04 | Boston, MA, US | Boston Rust Meetup
- 2026-08-06 | Mountain View, CA, US | Hacker Dojo
- 2026-08-06 | Saint Louis, MO, US | STL Rust
- 2026-08-13 | Lehi, UT, US | Utah Rust
- 2026-08-13 | San Diego, CA, US | San Diego Rust
- 2026-08-15 | San Francisco, CA, US | Flower
- 2026-08-18 | San Francisco, CA, US | San Francisco Rust Study Group
- 2026-08-19 | Hybrid (Vancouver, BC, CA) | Vancouver Rust
- 2026-08-19 | San Francisco, CA, US | Rust Bay Area
- 2026-08-20 | Hybrid (Seattle, WA, US) | Seattle Rust User Group
- 2026-08-26 | Austin, TX, US | Rust ATX
Oceania
- 2026-07-30 | Melbourne, AU | Rust Melbourne
South America
- 2026-08-08 | São Paulo, SP | Rust-SP
If you are running a Rust event please add it to the calendar to get it mentioned here. Please remember to add a link to the event too. Email the Rust Community Team for access.
Jobs
Please see the latest Who's Hiring thread on r/rust
Quote of the Week
So let's talk about what the process has looked like for Netstack3. For 11 months, the team has been ramping up a dogfooding program. At peak, that program has seen about 60 devices running nearly 24/7 in developers' homes.
Again, if this were any other netstack, we would have expected to uncover a giant mountain of bugs in that time. So, over the past year, how many bugs did the team uncover in the field?
Three.
- Josh Liebow-Feeser on his blog
llogiq again has no one to thank for a suggestion, so he is thankful to himself for finding this quote instead.
Please submit quotes and vote for next week!
This Week in Rust is edited by:
- nellshamrell
- llogiq
- ericseppanen
- extrawurst
- U007D
- mariannegoldin
- bdillo
- opeolluwa
- bnchi
- KannanPalani57
- tzilist
Email list hosting is sponsored by The Rust Foundation
29 Jul 2026 4:00am GMT
27 Jul 2026
Planet Mozilla
Firefox Tooling Announcements: MozPhab 2.15.4 Released
Bugs resolved in Moz-Phab 2.15.4:
- bug 2058150
moz-phab patchcrashes withKeyErrorwhen a stack relative is not visible to the user
Discuss these changes in #engineering-workflow on Slack or #Conduit Matrix.
1 post - 1 participant
27 Jul 2026 4:15pm GMT
Firefox Nightly: Try the New Firefox Design in Nightly
This past May, we shared our vision for the future of Firefox. Starting today, you can try out the next design evolution of Firefox in Nightly.
It's still Firefox, now with a more cohesive look and feel across tabs, menus, panels, and other browser surfaces. You'll notice softer tab shapes, a warmer color palette, updated icons, and - after hearing from many of you - the return of Compact Mode and new theme options to make Firefox your own.
Many of you have already spotted pieces of the new design in Nightly over the past few months. Now they're coming together into one complete experience.
You'll continue to see updates over the coming weeks as we polish the new Firefox design before it reaches Firefox users more broadly later this year. As you browse, we're especially interested in any visual or functional issues you encounter.
Keep an eye out for things like:
- Icons, spacing, and alignment
- Themes and personalization
- Different window sizes and display scaling
- Keyboard navigation
- Screen readers and other accessibility features
- Different languages and layouts
Found a bug?
If something doesn't look or behave as expected, please file a bug in Bugzilla.
When possible, include:
- Steps to reproduce the issue
- Screenshots or screen recordings
- Your operating system and Nightly version
If you have broader thoughts or questions about your experience, join the discussion on Mozilla Connect.
Thanks for using Nightly and helping us improve Firefox. Every bug report helps us identify issues and continue refining the new Firefox design before it reaches Firefox users more broadly later this year.
27 Jul 2026 3:00pm GMT








