21 Jul 2026
Planet Mozilla
Firefox Developer Experience: Firefox WebDriver Newsletter 153
WebDriver is a remote control interface that enables introspection and control of user agents. As such, it can help developers to verify that their websites are working and performing well with all major browsers. The protocol is standardized by the W3C and consists of two separate specifications: WebDriver classic (HTTP) and the new WebDriver BiDi (Bi-Directional).
This newsletter gives an overview of the work we've done as part of the Firefox 153 release cycle.
Contributions
Firefox is an open source project, and we are always happy to receive external code contributions to our WebDriver implementation. We want to give special thanks to everyone who filed issues, bugs and submitted patches.
Firefox 153, multiple WebDriver bugs were fixed by contributors:
- Khalid AlHaddad updated our codebase to use constants instead of hard-coded strings for all our session data types.
- Khalid AlHaddad improved the window manipulation commands in Marionette and WebDriver BiDi to allow individual window geometry properties, such as x, y, width, and height, to be adjusted independently.
- Sameem updated the "Take Element Screenshot" command from WebDriver Classic to crop screenshots of elements which exceed the viewport. This aligns with the specification and avoids errors when attempting to capture huge elements.
WebDriver code is written in JavaScript, Python, and Rust so any web developer can contribute! Read how to setup the work environment and check the list of mentored issues for Marionette, or the list of mentored JavaScript bugs for WebDriver BiDi. Join our chatroom if you need any help to get started!
All Changes
A complete list of developer-facing changes included in this Firefox release is available in the MDN Firefox 153 Release Notes.
21 Jul 2026 8:18pm GMT
The Mozilla Blog: Your Android tabs just got a lot more organized with Firefox
Tabs pile up fast on mobile. Imagine you're planning a summer barbecue, and you start by searching for the best rib recipe. Twenty minutes later, you're 17 tabs deep: comparing marinades, debating side dishes, checking the weather, making a grocery list and adding songs to a playlist.
None of those tabs are organized. They're mixed in with everything else you've been browsing, making it hard to keep track of what you're saving for later.
Now you can group related tabs in Firefox for Android, keeping them together in labeled, colored groups so you can actually find what you need when you need it.

How it works
Drag one tab onto another, or select a few and tap "Add to group." Name it, pick a color, and you're done.
Each group appears as a single card in the tab tray rather than a dozen separate tabs. You can open it, rename it, recolor it, or delete it whenever you want. Search still finds tabs inside a group, too.

So when you're standing in the produce aisle looking for that rib recipe, you won't have to scroll past dozens of unrelated tabs just to find it. Everything for your barbecue is organized together in one place, ready when you need it.
Finally sorted, as it should be
Tab grouping was the most requested feature from Firefox mobile users in 2025. And we get it: your tabs shouldn't get harder to manage the more you use your browser. Download the latest version of Firefox for Android now to try Tab Groups, with iOS support on the way.
The post Your Android tabs just got a lot more organized with Firefox appeared first on The Mozilla Blog.
21 Jul 2026 4:00pm GMT
The Mozilla Blog: Quick Answers: For the questions in between
You're planning a trip. Reading an article. Following a recipe.
Then a question pops into your head. Sometimes it leads down a rabbit hole - with more searches, more tabs and plenty to explore. Other times, you just need a little context so you can get back to what you were doing.
That's why we're introducing Quick Answers for Firefox on iOS.
With Quick Answers, you can ask a question using your voice and get a concise answer. Just open a new tab, long-press the voice button and ask.
For example:
- "What does mellifluous mean?"
- "What is 95 degrees Fahrenheit in Celsius?"
- "What's the difference between suede and nubuck?"
If a quick answer is all you need, you're done.
If you want to dig in deeper, the links to supporting sources are there for exploration.
Built with transparency and privacy in mind
We've built Quick Answers to be transparent about how it works and what data is shared.
Voice is processed on your device using Apple's speech recognition technology. No raw audio is stored or sent to the server, and Firefox doesn't share your browsing history or personal context with the AI model. Only the transcribed text of your question is sent to generate an answer. You can turn the feature off at any time in Settings → AI Controls.
Quick Answers is starting to roll out today to Firefox for iOS users in the U.S. using English.
Oh, and if you're wondering…
- Mellifluous means pleasant and musical to hear.
- 95 degrees Fahrenheit is 35 degrees Celsius.
- Suede is made from the underside of the hide, while nubuck is made from the outer side and buffed to create a soft, velvety texture.

Take control of your internet
Download FirefoxThe post Quick Answers: For the questions in between appeared first on The Mozilla Blog.
21 Jul 2026 4:00pm GMT
The Mozilla Blog: Experience Better Browsing: Introducing Native Containers in Firefox 153
Today, we're excited to announce the Preview of Containers in Firefox version 153, which lets you keep separate parts of your online life (work, shopping, personal, banking) logged into different accounts in the same browser window, but keeps your cookies and ad tracking isolated inside each container.
This means that stuff you do in one container isn't seen by other containers. No longer will you search for a new hat to wear to a party, only to be inundated with ads for hats at every twist and turn on the internet for weeks to come.
For almost a decade, many of you have relied on our Multi-Account Containers extension to keep work, personal, and privacy-sensitive browsing separate without needing multiple browsers or profiles.
We've heard your feedback and understood the value you find in that separation. Now, we're bringing the power of the Multi-Account Containers extension directly into the heart of Firefox for all to benefit from.
Why bring Containers into Firefox?
Whether you're managing multiple social media accounts, separating work projects from personal shopping, or simply keeping your banking activity distinct, Containers are designed to help you organize your digital space. By making Containers a native, first-party feature in Firefox 153, we are:
- Making it visible by default: You no longer need to hunt for an add-on to get started. Containers are built right into your browser, ready to help you manage your context from day one.
- Simplifying your workflow: We've focused on making it easier to open, create, and manage your containers from the places you already browse.
- Preserving what you love: For our long-time users who have relied on the add-on, the native experience is designed to maintain the core functionality, flexibility, and visual identity you depend on.
- Driving continued investment into the future of this feature, ensuring it lives on as a first party citizen of Firefox.
What to expect in the Preview
In this preview release, you can:
- Open tabs in specific containers: Keep your browsing activity isolated by context.
- Customize your workspace: Create and manage containers with your own names, colors, and icons.
- Manage settings easily: Control your container setup directly from the Firefox settings surface.
- Get Started: Right-click any tab or long-press the new tab (+) button to open a container tab - or head to Firefox Settings to create your first container.
If you're already using the Multi-Account Containers, there's nothing special you need to do. Not all of the features of the add-on are available in the first-party version of containers just yet, we're still building them out. You can continue to use the add-on alongside the built in containers, no need to uninstall the add-on.
This release represents our first step in making Firefox more adaptable to how you actually live and work online. While this is just the beginning, we have plans to refine this experience and build a foundation for future features that make context separation even more seamless.
Join the Conversation
We're eager to hear how this native experience fits into your daily routine. As you explore the new Containers Preview in Firefox 153, please let us know what you think by posting your feedback in this Mozilla Connect thread. Your feedback helps us shape the future of these tools and ensures we're building features that truly matter to you.

Take control of your internet
Download FirefoxThe post Experience Better Browsing: Introducing Native Containers in Firefox 153 appeared first on The Mozilla Blog.
21 Jul 2026 4:00pm GMT
Firefox Tooling Announcements: Firefox Profiler Deployment (July 21, 2026)
The latest version of the Firefox Profiler is now live! Check out the full changelog below to see what's changed:
Highlights:
- [fatadel] Show counter values over time in profiler-cli (#6136)
- [Markus Stange] More typed arrays: sample + counter times, some frametable columns (#6139)
- [Nazım Can Altınova] Add marker handles to
profiler-cli thread network(#6172) - [Nazım Can Altınova] Surface network activity across profiler-cli (#6175)
- [Nazım Can Altınova] Add
profile metacommand to profiler-cli (#6177) - [Markus Stange] Allow raw marker table's
startTimeandendTimecolumns to be Float64Array (#6169)
Other Changes:
- [Sky Ning] Skip preview links for non-main PRs (#6161)
- [spokodev] fix(gecko-upgrade): don't crash on a counter with empty sample_groups (#6160)
- [Markus Stange] Make profile-conversion snapshots more compact and meaningful (#6152)
- [Nazım Can Altınova] Only render a marker url field as a link when the whole value is a URL (#6163)
- [fatadel] Show each counter's owning process in profiler-cli (#6164)
- [Nazım Can Altınova] Document the pre-existing thread info and network JSON schemas in the cli (#6171)
- [Markus Stange] Copy column contents in getRawSamplesTableBuilderFromExisting for consistency (#6168)
- [Markus Stange] Convert eligible columns to typed arrays when outputting from profiler-edit (#6167)
- [Markus Stange] Remove unused samples.thread column (#6151)
- [Markus Stange] Fixed botched merge which broke 'yarn ts' (#6174)
- [Markus Stange] Update json-slabs 0.3.0 → 0.4.0 (major) (#6176)
- [nightcityblade] Fix light theme text selection colors (#6186)
- [Nazım Can Altınova] Import source map URLs from Chrome DevTools traces (#6190)
- [Nazım Can Altınova] Rename yarn
build-profiler-cliscript tobuild-cli(#6191) - [Nazım Can Altınova] Migrate husky to version 9 (#6201)
- [Nazım Can Altınova] Fix horizontal overflow when the transform navigator is long (#6199)
- [fatadel] Add a 'hexadecimal' marker schema field format (#6197)
- [Nazım Can Altınova] Bump source-map to 0.8.0 and remove the old type workaround (#6202)
- [Nazım Can Altınova]
Sync: l10n → main (July 21, 2026) (#6209)
Big thanks to our amazing localizers for making this release possible:
- fr: parmegiani.thomas
- fr: Théo Chevalier
- sr: Марко Костић (Marko Kostić)
- sv-SE: Luna Jernberg
- tr: Grk
- zh-CN: Ariel
- zh-CN: Olvcpr423
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
21 Jul 2026 12:44pm GMT
Martin Thompson: Why in Building Protocols, Like Code, Starting Over Is Dumb
Today, the IETF held the CURRENT BoF, where the goal was to develop a new protocol. That protocol would be substantially like TLS, reusing its record layer and basic structure, but it would drop in MLS for key exchange.
This is somewhere between a pretty bad idea and a horrible idea.
The wholesale replacement of a huge chunk of protocol architectures is a hallmark of a lot of the AI-generated protocol proposals that have flooded the IETF. A small blemish is identified, then the fix is a whole new protocol, or a major piece of surgery. No regard for the wisdom of Chesterton's Fence or the accumulated knowledge and usefulness embodied in what exists.
Experienced engineers know that rewriting a code module is not something you do lightly. There's lots of literature out there about why this is a bad idea generally, and some emerging discussion about how AI might just change that.
The reasons not to rewrite a software component still largely apply to a protocol component. The reasons that AI might make it easier to do that safely, less so. Protocols are different.
Wholesale Change Will Miss Use Cases
Just like with a code change, a protocol component that changes will miss use cases that people really care about.
The usual concerns with code apply:
- The existing features you know about and can test for can be handled.
- The existing problems you know and care about can be fixed.
- You inevitably introduce brand-new problems.
- The existing features you don't know about get lost.
Unlike code changes, you probably don't have a test case for existing features that you didn't know about. We found that with HTTP/2, where a number of use cases got lost in the process of "upgrading" HTTP.
In HTTP/1.1, performing client authentication in the middle of request was possible. Losing that capability in HTTP/2 affected few enough people that it was not badly damaging for the ecosystem. It still sucked.
A lot of work was done to try to find these issues, but we did not learn about these problems until fairly late in the process.
Proposing a protocol change means asking a whole lot of other people, many of whom are not invested in your goals, to do that work.
Changing a protocol by replacing a chunk of it, no matter how much care is taken, either asks the entire ecosystem to change with you.
That means asking everyone to move with you. If they don't, you are not changing the protocol, you are forking it.
Forking A Protocol Destroys Interoperability
The real value of having a protocol like TLS is that a great many things can all talk to each other.
Forking a protocol - and sometimes profiling a protocol, a subject for another post - destroys that. You now have two ways to achieve the same goal, and a choice to join one of two clubs. You can join both, but that means constantly translating back and forth, something that can only get harder over time as protocol semantics diverge.
And yes, in case you were asking, this applies to the entirety of the IETF IoT sphere, which has parallel HTTP, TLS, and other analogues. Ostensibly, these address the needs of highly constrained hardware, but the cost is an ecosystem cut off from the mainstream.
But Fixing Protocols Is Hard
Yes, existing protocols come with baggage or technical debt. Maybe they aren't perfectly optimized for your use.
The value that an existing protocol carries is that you are sharing the burden of its maintenance with a great many more people. Fixing it, maybe by adding extensions to support your needs, comes with opportunities to improve the protocol even beyond that immediate need. Every change is a chance to work off some of the accumulated cruft.
Major refreshes, like the TLS 1.3 reworking, cleared out a ton of cruft in the process. You get to benefit from the work that others do to improve that protocol too.
Do the Work
It is hard to be a responsible steward for the fabric of the Internet. We do it because it is worthwhile. Ignoring the lessons of the past is not helpful.
21 Jul 2026 12:00am GMT
17 Jul 2026
Planet Mozilla
Mozilla Open Policy & Advocacy Blog: Beyond technical fixes: Protecting kids online without breaking the internet
This is part one of a two-part series in which we explore approaches to protecting children online while safeguarding privacy, security and the open web. Part one covers our concerns regarding age gates, and alternative policy proposals that address the root causes of online harms.
Young people today have unprecedented opportunities to learn, connect, and explore - not just the web and the world, but also themselves. With the increased ubiquity of digital technologies and devices, worries around the relationship between these technologies and young people's well-being have grown, too. While concerns about the societal implications of new technologies is not a new phenomenon, experts argue that the accelerating speed of deployment of new technologies has outpaced scientists' capacity to feed into policy recommendations addressing risks. A growing body of research documents the harms experienced by young people online and the challenges reported by parents attempting to mediate their kids' technology use. At the same time, experts highlight the importance of contextual factors like existing mental health conditions, socio-economic circumstances and parental mediation to understand the real-world effects of digital technologies.
Faced with this complexity, and mounting public pressure, policymakers around the world are urgently seeking ways to improve child safety online. Driven by a sense of time running out and promises of new technical solutions to difficult questions, this has led, across jurisdictions, to proposals to restrict young people's access to certain technologies or platforms by introducing age assurance mandates.
Privacy and user empowerment have always formed a core part of Mozilla's mission. As we have said before, we support safer spaces for minors, but we caution against approaches that rely on identity checks, surveillance-based enforcement, or exclusionary defaults. Such interventions rely on the collection of personal and sensitive data and, thus, introduce major new privacy and security risks.
While many technologies exist to verify, estimate, or infer users' ages, fundamental tensions around accessibility, their effectiveness and effects on user's privacy, security and free expression remain. Technological approaches must be part of wider efforts to address the root causes of online harms. However, the deployment of age assurance technologies will not solve the complex challenge of preparing young people to navigate an increasingly online world and ensure their wellbeing. That will require more holistic approaches: offering education and support to navigate the web safely, addressing harmful business practices and acknowledging the offline factors shaping children's lives including social inequality, poverty or disparate access to (mental) health care services.
Ineffective age-gating mandates and the dangerous shift toward VPN restrictions
As jurisdictions around the world gain experience with government-mandated age gates for certain services, evidence is mounting that age restrictions are not an effective policy tool. Avoiding age gates is widespread and trivially easy: In Australia, where minors under 16 year of age have been banned from certain social media platforms since December 2025, the government's Compliance Update reports that seven out of ten young Australians remain online, often skirting age checks by simply entering a fake birthdate. A recent study on the implementation of the UK's Online Safety Act found that a third of children have bypassed age gates with fairly trivial steps like faking their birthdate, borrowing someone else's login credentials, or even drawing on facial hair, and that a quarter of parents have helped their children to bypass age assurance systems. In the US, studies indicate that as far back as 2011, 64% of parents who were aware their child under 13 had a social media account were also ones who helped them create that account.
Confronted with the apparent ineffectiveness of age gates, policymakers around the world seem to be shifting their attention to alleged circumvention tools. While research shows that many young people bypass age barriers by using other people's devices and accounts or tricking age estimation tools by making themselves look older, virtual private networks (VPNs) are increasingly framed as primarily a "loophole" to age gates. VPNs create encrypted "tunnels" between a user's device and the internet, protecting all internet traffic from that device and concealing users' IP addresses. VPNs are an essential privacy and security resource for millions of users worldwide, including young people.
Utah's recent age verification law holds websites hosting age-restricted content liable for verifying the age of anyone physically located in Utah, including individuals using VPNs or proxies. While the law does not ban VPNs outright, it forces websites to either block known VPN IP addresses or verify the age of every visitor globally. In the UK, policymakers debated age gates for VPNs extensively, but stopped short of restricting VPNs after new evidence confirmed that VPNs are not a relevant pathway for children seeking to bypass age checks. In Brazil, the ECA Digital law empowers the regulatory authority to order technical countermeasures against circumvention tools such as VPNs. These developments suggest a worrying trend: well-meaning but ineffective attempts to protect children risk undermining the fundamental rights to privacy, security, and free expression of all users, as well as the health and openness of the web itself.
We are convinced, however, that there are rights-respecting alternatives policymakers can pursue to empower young people online and improve their safety and well-being.
Moving beyond access bans
We strongly believe that online safety frameworks should be grounded in children's rights, striking a balance between their right to protection and their right to participate in society, express themselves freely, and access media and information. Such frameworks must also be proportionate and should not undermine the fundamental rights and access to tools like VPNs for all users.
Rather than focusing on limiting access, we believe that policymakers should prioritize interventions that tackle the root causes of online harm. Before considering new instruments, this work starts with ensuring that independent regulatory authorities have the necessary resources to enforce existing online safety frameworks. In Europe, preliminary findings against Meta and TikTok find these companies' addictive design features to be in breach of the Digital Services Act, underlining the potential of frameworks like the DSA to address key concerns.
The design of online interfaces, and the affordances and constraints they offer, significantly influences users' interactions, decisions and overall wellbeing. 'Dark patterns' or deceptive interfaces are key drivers of harms experienced by users, and especially young people: they can compel people to consent to extensive data collection and processing, resulting in hyper-personalized feeds, personalized ads that may exploit cognitive vulnerabilities and promote unhealthy or excessive consumer choices, and an overall erosion of privacy.
This is why we support proposals like EU Digital Fairness Act (DFA) and the American Innovation and Choice Online Act (AICOA) that could fill regulatory gaps. Specifically, we advocate for the prohibition of harmful design, guided by harmonized definitions of core concepts like "dark patterns", "deceptive design," and "addictive design" and anti-circumvention clauses to prevent companies from avoiding regulation through small tweaks. Platforms should be responsible for demonstrating that their design choices are fair, non-manipulative and non-exploitative. And services that are likely to be accessed by children should be required to refrain from enabling certain design features, including excessive notifications, endless feeds and gambling-like features by default, and only with parental consent.
Further, we urge policymakers to adopt a privacy-first approach to online harms. Many of the risks encountered by young people online are related to the collection and processing of personal data. Platforms collect enormous amounts of personal data, including sensitive data, to personalize and target services, ranging from algorithmic recommender systems to online ads. While the systems that target and display ads and curate online content are distinct, both are based on the surveillance and profiling of users.
Such profiling is the basis for young people being targeted with personalized ads and content recommendations, which can segment, exclude, or steer people into inequitable options and towards harmful content. Providers should thus be prohibited from using sensitive personal data (e.g. ethnicity, religious belief, health status, sexual orientation, political affiliation) to personalize content recommendations or ads, and they should be mandated to enable privacy-protective settings by default, including restricting access to users' location, camera, microphone, contacts, and camera roll. Policymakers should also extend the fairness and transparency obligations to personalization systems and advertising actors, including intermediaries and data brokers.
Additionally, everyone online, including families and young people, should be fully in control of their online experiences and navigate the web according to their preferences and needs. There is a significant opportunity to empower users with easy, effective opt-out rights and granular user controls. In practice, users should have the right to opt out of personalized content and targeting without being penalized with a downgraded version of the service. Some frameworks already strengthen choice - in those cases, we advocate for their robust enforcement.
Across jurisdictions, choice can be strengthened by ensuring that preferences explicitly expressed (e.g. settings selected, feedback signals, customization choices made, survey responses) are respected and "sticky", so do not get reset without being explicitly requested by the user. Interoperability mandates should let people integrate third-party content moderation systems or recommendation algorithms that better match their preferences and help them break out of the walled gardens of a few dominant companies. Parental controls are another important lever to operationalize user controls: Providers should deploy easy-to-use and effective parental controls that allow families to tailor online experiences to their preferences, across platforms.
We appreciate that this is a long list of complex policy recommendations which are also impacted by broader (geo)political developments. The fact remains that current age assurance approaches are not a silver bullet, and will create more, rather than solve, problems in the long term.
Where policymakers consider age signals as necessary to ensure age-appropriate online experiences, we believe that there are technical approaches better suited to balance users' rights than those currently pursued. We will explore these developments and approaches in the second part of this series.
The post Beyond technical fixes: Protecting kids online without breaking the internet appeared first on Open Policy & Advocacy.
17 Jul 2026 9:05am GMT
16 Jul 2026
Planet Mozilla
The Rust Programming Language Blog: Announcing Rust 1.97.1
The Rust team has published a new point release of Rust, 1.97.1. Rust is a programming language that is empowering everyone to build reliable and efficient software.
If you have a previous version of Rust installed via rustup, getting Rust 1.97.1 is as easy as:
rustup update stable
If you don't have it already, you can get rustup from the appropriate page on our website.
What's in 1.97.1
Rust 1.97.1 fixes a miscompilation in an LLVM optimization.
We have backported both an LLVM fix and a disable of the underlying change in Rust 1.97.0 of Rust's generated IR that increased the likelihood of this happening. However, note that the underlying miscompilation has been present since at least Rust 1.87.
If you'd like to help us out by testing future releases, you might consider running your code's CI or locally using the beta channel (rustup default beta) or the nightly channel (rustup default nightly). Please report any bugs you might come across!
Contributors to 1.97.1
Many people came together to create Rust 1.97.1. We couldn't have done it without all of you. Thanks!
16 Jul 2026 12:00am GMT
15 Jul 2026
Planet Mozilla
Niko Matsakis: Battery packs: Let's talk about crates, baby

This blog post describes an idea I've been kicking around called battery packs. Battery packs are a curated set of crates arranged around a common theme. For example, there's a CLI battery pack that has everything you need to build a great CLI, an opinionated pack for creating a backend web service, and one for embedded development (based on the Embedded Working Group's Awesome Rust repository). We've also got some smaller ones, such as the error-handling battery pack that shows how to handle errors in Rust. But this is just the beginning - a key part of the battery pack design is that anybody can create one.
Battery packs are meant to address one of the most common things I hear from new Rust adopters. Everyone loves the wealth of high-quality crates available on crates.io. And everyone hates having to spend a bunch of time researching and comparing alternatives. Battery packs can serve as a good set of default choices. And they don't lock you in. At heart, they're basically just a list of recommended crates, so you can always swap something out if you find an alternative.
We've got a prototype of the battery pack tool working today, so you can try it out if you're curious. Just run cargo install cargo-bp and then try a few commands! For example,
> cargo bp list
will show you the set of available battery packs, based on a crates.io search (as I'll explain below, a battery pack is itself packaged and distributed as a crate, but not one that you take a direct dependency on). And cargo bp add will add batteries from a battery pack into your crate, so e.g.
> cargo bp add cli
would let you select and add common CLI libraries. If you want to see a more involved demo, try out cargo bp add embedded, which is derived from the Awesome Embedded Rust repository.
Let's talk about you and me
One of the key ideas from battery packs is that anybody can publish one. They are just a crate named X-battery-pack; the dependencies of that crate are your recommendations. Features are designations of common sets of crates frequently used together. The examples are your templates. And so forth.
Letting anybody create a battery pack is in contrast to the previous ideas for an "extended standard library for Rust"1, and it is intended to address some of Rust's unique challenges. For one thing, it lets people publish battery packs that are tailored to specific requirements. For example, the CLI and backend service battery packs are targeting a "typical computer". But I could imagine the Rust embedded working group publishing a battery pack with libraries focused on no-std and binary size optimization.
Being open-ended also addresses the "who decides?" question. To my mind, the best people to recommend what libraries you ought to use are other people building systems like yours. This is why I mentioned the Embedded Working Group publishing an Embedded battery pack, for example, as I think they are clearly a set of people who know their space well. But even within the embedded space there are yet smaller groups, and I imagine that sometimes it'll make sense to get narrower. For example, perhaps a battery pack targeted embassy and its associated ecosystem? Unclear.
Creating a battery pack
If you wanted to create a battery pack, how do you do it? One answer is that you just create a new crate. But a better approach is to use the "battery-pack battery pack"2, which bundles a template:
cargo bp new battery-pack
This will prompt you for the name of the battery pack you want to create and a few other things and make your crate. Then you can just use cargo add dependencies to represent the libraries you want to recommend and publish.
"Batteries" are more than dependencies
The "batteries" that you can add to your project aren't always dependencies. They can also be "recipes" or templates. For example, the CI battery pack3 can configure your project with the kind of "super neat-o" github actions you've always wanted but never wanted to bother configuring. To use it, select one or more of the templates to install:
cargo bp add ci
I expect this kind of "actions to improve your crate" to become a rich source of things. Right now we're using a relatively lightweight template system built on minijinja, but I think we're going to want to expand on this.
Giving it some structure
Battery Packs also support more than just a flat listing of dependencies/features/templates. You can group dependencies and features into categories and then, for each category, distinguish between "pick at most one" or "pick any number". For a fun example, try cargo bp add embedded, which is derived from the Awesome Embedded Rust repository. If you run it, you'll see something like this, which groups the choices thematically and, in some areas like "concurrency framework", makes it clear that you want to pick one:
──────────────────────────────────────────────────────────────────
▼ Concurrency Framework (pick at most one)
> ○ ✦ embassy [embassy-executor, embassy-sync, embassy-time]
○ ✦ rtic [cortex-m, rtic] RTIC - interrupt-driven real-time
▼ Display & Graphics (pick any number)
[ ] ✦ display-ssd1306 [embedded-graphics, ssd1306] SSD1306
[ ] ✦ display-st7789 [embedded-graphics, st7789] ST7789 col
▼ Popular Drivers (pick any number)
[ ] ✦ display-ssd1306 [embedded-graphics, ssd1306] SSD1306
[ ] ✦ display-st7789 [embedded-graphics, st7789] ST7789 col
[ ] ✦ sensor-bme280 [bme280] BME280 temperature/humidity/pr
[ ] ✦ sensor-lis3dh [lis3dh] LIS3DH 3-axis accelerometer (I
[ ] ✦ usb-device [usb-device, usbd-serial] USB device stack
▼ Hardware Abstraction Layer (pick at most one)
○ ✦ atsamd [atsamd-hal, cortex-m-rt, critical-section-impl, co
○ ✦ esp32 [embedded-hal, esp-hal] ESP32 (Xtensa, WiFi + BT,
○ ✦ esp32c3 [embedded-hal, esp-hal] ESP32-C3 (RISC-V, WiFi
○ ✦ esp32s3 [embedded-hal, esp-hal] ESP32-S3 (Xtensa, WiFi
○ ✦ nrf52832 [cortex-m-rt, critical-section-impl, cortex-m, em
○ ✦ nrf52840 [cortex-m-rt, critical-section-impl, cortex-m, em
○ ✦ nrf9160 [cortex-m-rt, critical-section-impl, cortex-m, emb
○ ✦ rp2040 [cortex-m-rt, critical-section-impl, cortex-m, embe
○ ✦ stm32f0 [cortex-m-rt, critical-section-impl, cortex-m, emb
embedded-battery-pack v0.1.0 ↑↓/jk Navigate | Space Toggle | ←/→
Let's talk about all the good things…
So why am I so keen on battery packs? It's largely because I've heard so many would-be or recent Rust adopters talk about picking crates as a challenge. But I feel they would help with some other problems as well.
What I really want to see is working groups in the Rust Commercial Network banding together to publish battery packs and recommendations. These would cover the dependencies that they're actually using.
Supporting maintainers
One of the reasons I want to have RCN-recognized battery packs is that they are a natural focal point to then prompt RCN members to fund the maintenance of those crates. I am imagining that for each sponsored battery pack vended within the RCN, there is an associated "ecosystem fund". Companies or individuals could sponsor this fund to get access to early patches, security disclosures, etc or other perks. The money would be used to support the maintainers of those crates, to implement missing features, and so forth.
Fostering interoperability
Another value-add from battery packs is the ability to drive interop efforts. I think that as soon as we start talking about standardizing, we're also going to recognize that there are some places where standardization is hard. For example, early conversations within the network service working group (unsurprisingly) immediately identified that while most people are using tokio, some major companies are using their own runtimes internally. It's not like the need for "async runtime interop" is news. But right now, every crate winds up effectively implementing their own set of little traits to make it work. Sponsored battery packs offer the possibility of a neutral home for that sort of thing.
…and the bad things that could be
There are some risks to people using battery packs. The most obvious is that the fact that anybody can publish a battery pack may mean that you just get a ton of battery packs, which doesn't really help anybody! I'm not so worried about this because I think that there will be a few obvious places that most people go first, and then I think once people are oriented, they'll get excited to explore what crates.io has to offer and start discovering more niche battery packs.
Avoiding stagnation
Battery packs are designed to evolve. I've seen it happen a number of times that there is a dominant crate for something, often taking a "traditional approach", but then somebody else comes along and presents an interesting alternative that gradually takes off. I love that and I don't want to put it at risk.
One example of evolution around CLI argument parsing. For a time, docopt was a popular way to parse command-line options. Then clap came along and presented a more structured alternative; that was nice, but then structopt came along and connected clap to an auto-derive, so you could just write your data structure and be done. And that was awesome. (That is now the standard in clap.) I want to be sure that, even if there is a CLI battery pack, there's room for the next clap to come along.
There are a few things about battery pack that I think will help us deal with this. First, they are a "thin abstraction". You don't "depend on" a battery pack, you depend on the crates within it. So if a new version comes out that uses clap instead of docopt, that doesn't impact you at all. Your code keeps working same as it ever did. And of course it helps that anybody can publish a battery pack. You can now have variations on battery packs that are focused around a new approach to help it get started.
Done right, I think that standardized battery packs can also help the ecosystem evolve and pivot. As it is now, knowledge of new crates has to spread by word-of-mouth. But if everybody is aligned around a new approach, adopting that new approach within a battery packs sends a clear signal that your group is aligned that something is the new hotness.
…Let's talk about crates4
"Always bet on the ecosystem"
I see always bet on the ecosystem as a key Rust design axiom. It's the reason we chose a small standard library and a package manager in the first place. It's also why battery packs are designed to be published by anyone.
But just like plants sometimes need a trellis to grow taller, any successful ecosystem reaches a point where it needs another layer of structure to help it keep growing. Without that, you have this "layer of tacic knowledge" (in the words of a Rust Vision Doc interviewee) that becomes an obstacle for folks. And I think we've reached that point with crates.io.
I am hopeful that battery packs can provide that next layer of structure. But at the end of the day, if there's a better approach, that's fine too, so long as we find a way to help people find (and fund!) the crates they need. So let's talk about it!
-
My first recollection of it was the Rust Platform idea we floated in 2016! ↩︎
-
Yo dawg… ↩︎
-
Hat tip to Jess Izen, who proposed and developed the CI battery pack. Neat idea. ↩︎
-
Oh, and: my apologies to Salt-N-Peppa. ↩︎
15 Jul 2026 3:24pm GMT
This Week In Rust: This Week in Rust 660
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
Project/Tooling Updates
- Rewriting Bun in Rust
- Announcing BullMQ for Rust
- prost-protovalidate 0.6 - buf.validate (protovalidate) for prost and buffa: compile-time codegen + runtime CEL, 2872/2872 conformance
- plaza 1.0: a ratatui package-manager TUI that searches pacman, the AUR, apt, dnf, and Flatpak at once
- Danube v0.15.1: native Apache Iceberg integration for streaming-to-lakehouse export
- Guardian Sentinel. The Terminal User Interface for Guardian Decentralized Database - P2P
- kobe 0.33.0: a Rust operator for instant CI Kubernetes clusters
- Elara Mesh: what the black box for AI agents actually does
-
cochlea 0.1.0: a headless, deterministic audio engine for AI agents
Observations/Thoughts
- Open Source Security Podcast: Rust Foundation Maintainers Fund with Lori and Niko
- Moving a Rust WebRTC SFU to thread-per-core
- Faster Rust tests in CI with parallel steps
- [video] The Only Diagram You Need to Understand Rust Ownership
- We compiled our TypeScript parser to WASM
- Understanding the Rust hype for the busy developer
- I red-teamed my own LLM security gateway (Rust) in four passes - every detection gap and how I closed it
Rust Walkthroughs
- [video] Backend Concepts in Rust: HTTP Servers
- Fearless Embedded Rust: A FPV Lego car
- What I learned building a self-corrupting file format in Rust
- Come Async You Are
Miscellaneous
Crate of the Week
This week's crate is dashu, a pure Rust set of libraries of arbitrary precision numbers.
Thanks to JacobZ 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.
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
550 pull requests were merged in the last week
Compiler
- inline some
Symbolfunctions - predicate/clause cleanups
- remove some AST
tokensfields - resolver: wrap arenas in
WorkerLocal - rework read deduplication with pooled read recorders
- shrink
mir::Statementto 40 bytes - shrink no-op drop elaboration
- specialize common
(1, 1)case for arg unification - use SmallVec for return places in MIR
Library
- add explicit
Iterator::countimpl forChunkBy - allow
Allocators to be used as#[global_allocator]s - fix multiple logic bugs in
Arc::make_mut - implement feature
char_to_u32 - make volatile operations const
- move
std::io::Writetocore::io - stabilize
String::from_utf8_lossy_owned - stabilize
VecDeque::retain_backfromtruncate_front
Cargo
install: Move --debug to Compilation optionssource: incorrect duplicate package warning- fix manifest schema generation:
TomlDebugInfoenum-variants doesn't renamed - dont apply host-config gating to stable behavior
- reduce library search path length in new build dir layout
- reduce rustc
-Largs used in the newbuild-dirlayout - rename
-Zno-embed-metadatato-Zembed-metadata=no - test: fix race in
cargo_compile_with_invalid_code_in_deps
Clippy
- add new lints:
rest_pattern_accessible_fieldandunnecessary_rest_pattern - new lint:
definition_in_module_root arbitrary_source_item_ordering: add configurable trait impl item ordering modestests_outside_test_module: put code in backticks in the lint message- count length of the first paragraph by its text
- fix
suboptimal_flopsfalse negative with ambiguous float literals - partly disable
unneeded_wildcard_patternwhenrest_pattern_accessible_fieldis enabled - respect the configured MSRV in
implicit_saturating_sub'sif x != 0 { x -= 1 }rewrite - trigger
single_element_loopif the block contains only a final expression - optimize
nonstandard_macro_bracesby 99.9683% (1.1b → 351K) - perf: bail out of the
disallowed_methodsrule if the disallowed list is empty
Rust-Analyzer
- ask for disclosure in AI contributions
- add fixes for array length for
type_mismatch - add parens in transformed dyn type in ref type
- avoid panic in merge imports on trailing path separator
- change some things for
#[doc = macro!()]expansion - clamp cttz const-eval result to type width
- correctly handled cfg'ed tail expr, take 2
- crash on code actions when an unresolved module is present
- crash when computing diagnostics with MIR and error types
- don't complete default in default impl
- early late classification of lifetimes
- fix
render_const_using_debug_implconstructing outdated std layouts - fix proc macros
TokenStream::from_str()for doc comments - hide private fields on hover depending on context
- make lsp-server
Responsetype closer aligned to JSON-RPC - pretty assoc const when trait in macro
- reimplement
crate_supports_no_stdsyntactic heuristic - resolve non-plain paths in blocks correctly
- support Cargo 1.97.0 lockfile path setting
- hir-ty: walk container exprs for
unused_must_use - fix onEnter erroneously deleting/interpreting
$foo - suggest code action fixes produced from diagnostics under cursor, even if they have effects elsewhere
- treat library files as truly client immutable
- turn
BlockLocinto a tracked struct, take 3
Rust Compiler Performance Triage
This week many new optimizations landed, making this a very good week for performance. The only real regression was a fix for a miscompile that will likely be re-landed in the future.
Triage done by @JonathanBrouwer. Revision range: 3659db0d..5503df87
Summary:
| (instructions:u) | mean | range | count |
|---|---|---|---|
| Regressions ❌ (primary) |
0.3% | [0.2%, 0.4%] | 3 |
| Regressions ❌ (secondary) |
0.9% | [0.1%, 2.5%] | 25 |
| Improvements ✅ (primary) |
-1.2% | [-9.9%, -0.2%] | 195 |
| Improvements ✅ (secondary) |
-3.4% | [-92.1%, -0.1%] | 174 |
| All ❌✅ (primary) | -1.2% | [-9.9%, 0.4%] | 198 |
2 Regressions, 10 Improvements, 10 Mixed; 7 of them in rollups 36 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:
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
- enable
unreachable_cfg_select_predicateslint as part ofunusedlint group - Stabilize
dyn Allocator - Tracking Issue for vec_try_remove
- Partially stabilize
box_vec_non_null - Never break between empty parens
- Enable
-Zpolonius=nexton nightly - Enable
-Znext-solveron nightly by default for testing - Stabilizing the state of the debuginfo test suite
- Optimize
repr(Rust)enums by omitting tags in more cases involving uninhabited variants. - Proposal for Adapt Stack Protector for Rust
No Items entered Final Comment Period this week for Cargo, Language Reference, Language Team, Leadership Council, Rust RFCs 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-15 - 2026-08-12 🦀
Virtual
- 2026-07-15 | Virtual (Girona, ES) | Rust Girona
- 2026-07-15 | Hybrid (Vancouver, BC, CA) | Vancouver Rust
- 2026-07-16 | Hybrid (Seattle, WA, US) | Seattle Rust User Group
- 2026-07-16 | Virtual (Berlin, DE) | Rust Berlin
- 2026-07-19 | Virtual (Dallas, TX, US) | Dallas Rust User Meetup
- 2026-07-21 | Virtual (London, UK) | Women in Rust
- 2026-07-21 | Virtual (Tel Aviv-yafo, IL) | Rust 🦀 TLV
- 2026-07-21 | Virtual (Washington, DC, US) | Rust DC
- 2026-07-22 | Virtual (Girona, ES) | Rust Girona
- 2026-07-23 | Mountain View, CA, US | Hacker Dojo
- 2026-07-28 | Virtual (Dallas, TX, US) | Dallas Rust User Meetup
- 2026-07-29 | Virtual (Girona, ES) | Rust Girona
- 2026-07-30 | Virtual (Berlin, DE) | Rust Berlin
- 2026-08-02 | Virtual (Dallas, TX, US) | Dallas Rust User Meetup
- 2026-08-04 | Virtual (London, GB) | Women in Rust
- 2026-08-05 | Virtual (Girona, ES) | Rust Girona
- 2026-08-05 | Virtual (Indianapolis, IN, US) | Indy Rust
- 2026-08-11 | Virtual (Dallas, TX, US) | Dallas Rust User Meetup
- 2026-08-12 | Virtual (Girona, ES) | Rust Girona
- 2026-07-19 | Virtual (Bangalore, IN) | Embedded Rust Discord
Asia
- 2026-07-18 | Bangalore, IN | Rust Bangalore
- 2026-07-19 | Virtual (Bangalore, IN) | Embedded Rust Discord
- 2026-07-25 | Mumbai, IN | Rust Mumbai
- 2026-07-26 | Pune, MA, IN | Rust Pune
Europe
- 2026-07-15 | Dortmund, DE | Rust Dortmund
- 2026-07-21 | Leipzig, DE | Rust - Modern Systems Programming in Leipzig
- 2026-07-23 | Berlin, DE | Rust Berlin
- 2026-07-23 | London, UK | London Rust Project Group
- 2026-07-23 | London, UK | Rust London User Group
- 2026-07-23 | Paris, FR | Rust Paris
- 2026-07-29 | Poland, PL | Rust Poland
- 2026-07-30 | Manchester, GB | Rust Manchester
North America
- 2026-07-15 | Hybrid (Vancouver, BC, CA) | Vancouver Rust
- 2026-07-16 | Hybrid (Seattle, WA, US) | Seattle Rust User Group
- 2026-07-18 | Boston, MA, US | Boston Rust Meetup
- 2026-07-21 | San Francisco, CA, US | San Francisco Rust Study Group
- 2026-07-22 | Austin, TX, US | Rust ATX
- 2026-07-22 | Los Angeles, CA, US | Rust Los Angeles
- 2026-07-22 | New York, NY, US | Rust NYC
- 2026-07-25 | Boston, MA, US | Boston Rust Meetup
- 2026-07-25 | Brooklyn, NY, US | Flower
- 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 | Saint Louis, MO, US | STL Rust
South America
- 2026-08-08 | São Paulo, SP | Rust-SP
Oceania
- 2026-07-21 | Barton, AU | Canberra Rust User Group
- 2026-07-23 | Perth, AU | Rust Perth Meetup Group
- 2026-07-30 | Melbourne, AU | Rust Melbourne
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
Thank you for your PR, but please edit the description like you are a chainsaw-wielding maniac that just discovered the sentences are young adults who came to the lake at summer camp after sunset.
- workingjubilee on Rust github
Thanks to Theemathas 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
15 Jul 2026 4:00am GMT
14 Jul 2026
Planet Mozilla
Thunderbird Blog: Community Office Hours: A Thundermail Update

Our Community Office Hours series is all about connecting with the people behind Thunderbird and our products, and sharing the work that's happening behind the scenes. These conversations are a chance to learn more about the direction of our projects and to hear directly from the people making it happen.
In this episode, we are talking about Thundermail!
Since we first shared our plans for Thundermail, we have seen an incredible amount of excitement, curiosity, and thoughtful feedback from the community of early bird testers. In this Community Office Hours session, members of the Thunderbird team sit down to talk about the project's vision, share where things stand today, and answer some of the questions we've been getting along the way.
In this conversation, you'll hear about:
- Progress since the initial announcement of Thunderbird Pro and Thundermail
- Many of the community's questions submitted via Reddit.
- What we're working on next and what you can expect in the months ahead.
One of the best parts of Community Office Hours is the opportunity to have open conversations with our community. Your questions, ideas, and feedback help shape Thunderbird and its products, and we are excited to keep sharing updates as Thundermail continues to evolve.
Resources
Resources for Suggesting Features:
Thunderbird on Desktop and Mobile - https://connect.mozilla.org
Thundermail and Thunderbird Pro - https://ideas.tb.pro
Resources for diving into Thundermail:
Thundermail (and other services) roadmap: https://roadmaps.thunderbird.net/en-US/services/
Subreddit: https://www.reddit.com/r/ThunderbirdPro/
Thunderbird Pro addon repo that is now shipped natively in Thunderbird: https://github.com/thunderbird/tbpro-add-on
Thunderbird Accounts repo: https://github.com/thunderbird/thunderbird-accounts
Webmail client repo: https://github.com/thunderbird/stormbox
Appointment repo: https://github.com/thunderbird/appointment
Thundermail deployment repo: https://github.com/thunderbird/thundermail-deploy
SieveConnect repo: https://github.com/philpennock/sieve-connect
Resources for Getting Help with Thunderbird:
Thunderbird for Android Support Channel (Matrix) - https://matrix.to/#/#tb-android:mozilla.org
Thunderbird Desktop Support Channel (Matrix) - https://matrix.to/#/#thunderbird:mozilla.org
The post Community Office Hours: A Thundermail Update appeared first on The Thunderbird Blog.
14 Jul 2026 7:36pm GMT
Firefox Tooling Announcements: Happy BMO Push Day! (20260713.1)
The following changes have been pushed to bugzilla.mozilla.org:
- Bug 2053330 - "Close and move to invalid bugs" button jumps way to the left (possibly under your mouse, asking for a mis-click) when you close a bug with another resolution.
- Bug 2052048 - Make the "Close as invalid" button a bit more targeted
- Bug 2053269 - BMO API bugzilla.login helper needs to support Bugzilla_api_token + cookie for authenication support
- Bug 2051396 - Make form.web.bounty stop adding the bounty flag and more strongly push people to HackerOne
- Bug 1355999 - Autocomplete on https://bugzilla.mozilla.org/form.web.bounty
- Bug 2049554 - Cloned security bugs should default to being secure even if they aren't in the default security group
- Bug 2036191 - Crash Signature Field Mismatch in Bugzilla REST API
- Bug 2043733 - Live Github Status for Pull Requests
- Bug 1619459 - Updated QA test to stop testing XMLRPC/JSONRPC and only test REST
- Bug 2052429 - "Show: Open/Closed/All" selects "All" incorrectly
- Bug 2052188 - "Close as Invalid" button is too close to the Attach New File button so can be confusing
Discuss these changes in the BMO Matrix Room
1 post - 1 participant
14 Jul 2026 6:44pm GMT
The Mozilla Blog: Over The Edge 2.0: what independent researchers found about browser choice on Windows
Two years ago Mozilla asked two leading experts on deceptive design, Dr. Harry Brignull and Cennydd Bowles, to look at how Microsoft was treating people who tried to use a different browser on Windows. Their report, Over The Edge, documented a pattern of design choices in Windows, Edge, and Bing that nudged, pressured, and at times tricked people into using Edge.
This morning, the same researchers are publishing Over The Edge 2.0. They retested the same questions across Windows 10 and Windows 11, and added two new dimensions. First, how does Microsoft's approach change from one jurisdiction to another? They assessed Microsoft's tactics across four regions: the USA, India, the UK, and Germany, as a representative country in the European Economic Area. Second, they examined how AI features, specifically Copilot, are being used to shape the same outcomes the original report identified.
Their conclusion is short. Microsoft still does not allow users to download, set as the default, or keep using alternative browsers without harmful interference. The patterns are documented, and they meet established definitions of coercion, deception, and manipulation.
There is one bright spot. In Europe, where the Digital Markets Act applies, some harmful design tactics are gone. The Bing 'All you need is right here' panel and its trick wording. The nagging Windows 10 'You're almost done setting up your PC' journey. The Copilot data toggles that default to "On" in the US and India, by contrast default to "Off" in the EEA and the UK. Same Windows. Same Edge. Same Copilot. Different design choices, because the law required them.

That is the heart of the report. Although the EEA product still has obvious harmful design patterns, Microsoft has built a fairer user experience for browser choice. It has shipped that experience to one region. Everywhere else, including the US, the UK, India, and Brazil, harmful design patterns continue. This is an active choice - and one that can be made differently.
The findings are the researchers' own. Mozilla commissioned the work, and the report discloses that role, but the methodology, the screenshots, and the public journey database at edge.brignull.com let anyone check the evidence for themselves.
We make Firefox because we believe the web should serve people, not platforms. Firefox is independent, built by Mozilla, and designed around what is best for users, not what increases lock-in.
Read the full report here.
The post Over The Edge 2.0: what independent researchers found about browser choice on Windows appeared first on The Mozilla Blog.
14 Jul 2026 12:30pm GMT
The Mozilla Blog: Mozilla’s Inaugural ‘State of Open Source AI’ Report Is Here
Open source AI has crossed a threshold. For years the debate has centered around whether open models could ever compete with closed ones. This is no longer a debate we should be having. Today Mozilla is publishing its inaugural State of Open Source AI report, built on new analysis and a global survey of 950+ developers, showing that open models are no longer playing catch-up. The performance gap with top proprietary systems like ChatGPT and Claude has narrowed to just 3%, while costs have fallen up to 50x in three years.
But the report also surfaces a harder truth. Open models now power roughly a third of real-world AI usage, but capture only 4% of the revenue. So while the value is there, it just isn't flowing back into the open ecosystem that made it possible. Meanwhile, the geopolitical picture is shifting fast.
Asia is racing ahead
China and East Asia now lead the world in open source AI adoption, at 89%, far ahead of the West, treating open source as a cornerstone of national strategy. Governments elsewhere are responding, with 12 new national AI strategies launched last year, and 47 countries now restrict foreign processing for critical workloads. The EU, Canada, and India are backing open ecosystems with real public investment, treating AI infrastructure as a strategic asset.
Developers want open models, but they can't always ship them.
For developers, the appetite for open source is there, and cost and privacy rank as developers' top reasons for choosing models. But wanting to use open models and running them in production are different things. 79% of developers use open models, yet only 51% have deployed them in production, versus 63% for closed models.
As Álvaro Ruiz Cubero of SlashData, which fielded the survey for Mozilla, put it: "this gap indicates that there is not an issue purely of model quality, but of missing infrastructure. Deployment rates for open models barely increase with company size, highlighting a lack of mature tooling and support. At the same time, buyers are prioritising licensing terms (31%) and ownership (26%), signalling a clear shift toward control and flexibility over raw capability."
The real battle has moved beyond the model
Perhaps the most important finding may be the least obvious. The layer that matters most isn't the model. It's the agentic harness: the software between people and models that decides what an AI system can see, remember, and do. Changing the surrounding software can affect performance more than switching the model itself. Whoever controls that layer controls how AI behaves in the world.
Right now, that layer is being built with very few guardrails. Users approve AI agent requests by default up to 93% of the time, with so-called "consent fatigue" going largely unnoticed.
"Open source AI has reached a turning point," said Raffi Krikorian, Mozilla's Chief Technology Officer. "It's no longer about expanding access to models; it's about who has the power to shape, audit, and improve them. Without investment in the infrastructure, tooling, and governance around open models, we risk locking in a system where only restrictive, closed AI can scale - and that doesn't serve the public interest, or sovereignty over tech policy decisions."
Be owners, not renters
Open models offer what a subscription never can: owning your infrastructure instead of renting someone else's. Companies like Microsoft and Uber are already rethinking their reliance on paid, closed AI tools as the bills add up. The economics are shifting and so is the thinking.
If you're a CTO, a policymaker, a developer or an investor, this is the report for you. Read it, share it, and help build the infrastructure to make openness usable, not just possible.
Read the full Mozilla State of Open Source AI report here.
The post Mozilla's Inaugural 'State of Open Source AI' Report Is Here appeared first on The Mozilla Blog.
14 Jul 2026 12:00pm GMT
Mozilla GFX: HDR video in Firefox for Windows tech retrospective
HDR video is coming to Firefox for Windows users (and has been available for some time on macOS). This blog post explains how we developed the feature and gives a retrospective on the technical choices we made.
A primer on video playback for the web:
- Video file demux and decode: A video stream generally consists of parallel image and audio streams, along with captions, HDR scene metadata, and the like. "Container" formats like MP4 or MKV specify how these streams are combined, or multiplexed, into a single byte stream for transmission. On receipt, Firefox needs to divide that byte stream back into the individual media streams; this is de-multiplexing or "demuxing". Then Firefox must uncompress the data to get images, audio samples, and so on. Firefox's media team provides the demuxers, and pulls in appropriate codecs to decode them. We prefer using hardware video decoders if they work reasonably well. Video decompression usually produces roughly a YUV 4:2:0 image in NV12 for SDR or P010 for HDR. (If you visit about:support in Firefox, and search for Codec Support Information (or one of the codec names like AV1), you can see a whole feature matrix of support details for which codecs are hardware and software on your system.)
- Gecko displaylist building: Given a demultiplexed, uncompressed frame of video, Gecko displaylist building incorporates it into a video element in the displaylist being sent to WebRender. If the frame was decoded in hardware, it is generally represented by a texture in GPU memory. Or, if it was decoded in software, then it is represented by a memory mapping holding some raw pixel data in system memory shared with Firefox's media decoder process.
- WebRender: Given the video element in the displaylist, WebRender decides whether to promote it to a desktop compositor overlay, or whether it must instead be rendered using a pathway more like an ordinary HTML element. A compositor overlay is faster and uses less power; on Windows this uses DWM with the DirectComposition API, which manages a graph of visuals. But if complex CSS is involved (rounded corners, blur filters, or similar features), Firefox must use WebRender's ordinary rendering pathway. Currently the latter is not HDR capable, so Firefox favors the desktop compositor overlay for animated elements such as video and canvas.
As we began designing Firefox's HDR support, we had to lay out some assumptions and found many complications:
- Initially, we had hoped that on a modern system, BT2100 HDR videos could be displayed on Windows by simply sending them to DirectComposition.
- In theory, the Desktop Window Manager (DWM) honors the DXGISwapChain3::SetColorSpace1 method which should let us request either DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_LEFT_P2020 or DXGI_COLOR_SPACE_YCBCR_STUDIO_GHLG_LEFT_P2020. The former refers to SMPTE 2084, more commonly called PQ, the Perceptual Quantizer function and the latter is ARIB-STD-B67 also known as HLG, the Hybrid Log Gamma function, most commonly used on HDR TV broadcasts.
- Unfortunately, this was a dead end. In testing with a mocked up compositor test app, calling SetColorSpace1 with this value seems to be ignored on P010 (at least in testing on AMD), so it incorrectly displays BT2100 PQ video as if it were BT709, which makes the video dull and muddy, since BT709 is a narrower gamut than BT2020, and the BT1886 transfer function used by BT709 is very different from PQ defined by BT2100. SetColorSpace1 may work on other vendors with P010, so it may be a valid optimization, but we were looking for a universal solution.
- For the future, Windows 11 23H2 has added a new interface called IDCompositionTexture which may serve our purposes better; from what we have been told, it is universally supported for all formats and color spaces. We haven't used it for video so far, but it's an interesting future direction.
- As noted above, HDR videos must use a desktop compositor overlay. HDR video uses the BT2100 PQ colorspace with an RGB10A2 format, while WebRender can only work with images in the sRGB colorspace (appropriate for standard-dynamic-range BT709 video).
- Until HDR came along, Gecko and WebRender only used desktop compositor overlays as a power/performance optimization. With HDR, overlays become a necessity as the pixel format and color space differ from classic sRGB.
- Fortunately, HDR videos tend to be shown without particularly fancy CSS rendering such as clip masks and rounded corners, which would require WebRender to perform further copies. Technically, DirectComposition does support all of those features, but Firefox doesn't use that functionality much.
- In the future, we expect to upgrade WebRender for HDR rendering, allowing us to deal with complex cases like clip masks or blur filters on video elements.
- We considered whether we could use VideoProcessorBlt, or whether we should write our own shader instead.
- In favor of VideoProcessorBlt:
- It uses less power on GPUs that have a video processor unit.
- We discovered in testing (using CheckVideoProcessorFormatConversion) that while many modern GPUs support one of the needed conversions (P010 PQ -> RGB10 PQ), few support the ones we need for HLG videos (P010 HLG -> RGB10 PQ).
- The 'video-dynamic-range' query used on the web is not fine-grained enough to be able to say "the web browser can display PQ video but not HLG video", so if we went with VideoProcessorBlt as a required feature, only about 20% of HDR desktop users would be able to use the feature.
- In the future, we could explore using VideoProcessorBlit to save power on hardware that supports the conversions we need. But other web browsers are not using this functionality, so there may be more issues we haven't found yet.
- In favor of writing our own shader with all of the features:
- This would work consistently on all vendors - nothing special here.
- This would look the same on all vendors, regardless of hardware capabilities. This is generally the aim of web standards.
- This would support anything we want it to. HDR tonemapping can be implemented. Video orientation can be implemented (for videos recorded on phones which may be rotated 90, 180 or 270 degrees). We can support any kind of YUV->RGB conversion with a color matrix (even weird legacy formats like GBR 4:2:0). We can support conversion between color primaries (e.g. BT2020->BT709). We can convert to linear color (for scRGB using RGBA16F) or any EOTF we want (notably BT2100 PQ with RGB10A2, for our use-case).
- In the end we went with the shader after a significant period of time experimenting with VideoProcessorBlt in our Nightly releases.
- In favor of VideoProcessorBlt:
- There is a very large amount of graphics code in Gecko and WebRender that needs to be upgraded for HDR.
- We decided that the most important code paths to upgrade first are the ones for regular video playback and DRM-protected video playback, and later canvas video import (Canvas2D, WebGL, WebGPU) which will require upgrading canvas for HDR first - another big project.
- We had to upgrade several dozen structs to carry the transfer function for video data, as previously all code assumed video used BT1886 EOTF.
- We hope we can avoid tone mapping HDR content when viewed on HDR displays.
- It's reasonable to expect that most displays going forward will be HDR displays (partly because of marketing momentum, partly because displays are made by a very finite set of manufacturers who are all making HDR display panels), and eventually tone mapping may become unnecessary on the web.
- For the short-term we will have to apply a tone mapping effect when HDR content is viewed on SDR displays, likely using 'Reinhard tonemapping' which refers to the widely available paper Photographic Tone Reproduction for Digital Images by Erik Reinhard et al, and configuring it for a fixed brightness ratio of 400 cd/m^2 -> 100 cd/m^2 when used on SDR displays, and see if that fits all HDR content on the web well enough for a good user experience - and if it does not, we will iterate based on feedback from users on Firefox Nightly.
- We are hoping that we will never have to apply tonemapping for HDR content on HDR displays, there are multiple factors in this decision:
- Varying the brightness limit would make it a significant fingerprinting vector if not handled very carefully if the script can inspect pixels or parameters related to that. There are ways to mitigate this but they are all awkward restrictions to impose, and queries would have to get a different answer than what the rendering is using.
- Phones and laptops with light sensors may vary the reference brightness in real time, and this changes the maximum displayable ratio (aka HDR headroom) every refresh, which is also a major battery drain if we keep redrawing all of the time.
- Documents composed of multiple images (a gallery or some form of art composition) would apply different tonemapping to each image if the brightest pixel in each image is different brightness. We'd have to do something about that to make it controllable via CSS.
- In general the detailed parts of an image are within a certain brightness band - see Debunking HDR for a detailed lecture on film grading and why you would not have significant difference in brightness between scene elements.
- User feedback so far has indicated that not applying tonemapping has given them a better viewing experience on some videos.
- WebRTC is implemented using a library, common to all web browsers, which has limited support for HDR.
- While we didn't prioritize this for an initial feature launch, we are looking at how to implement HDR support properly in libwebrtc. This is in the early assessment phase but we know this is wanted for a couple of use-cases, like video calls for meetings, or game streaming with friends watching.
In general, one of the biggest challenges in working on graphics code in a web browser is a lack of documentation for how to best use features like video playback and desktop compositing in the context of a web browser (e.g. multiple processes, sandboxing, shared memory, sharing external textures, etc). This parallels the rarity of graphics engineers with such experience. Building new features in this space requires a lot of research (and a lot of trial and error). The solution you end up with may not look at all like the one you initially imagined.
On behalf of the graphics team at Mozilla, I want to thank the people who use Firefox Nightly regularly and file bug reports when things aren't working the way they want. Comments on Experimental High Dynamic Range video playback on Windows in Firefox Nightly 148, Mozilla Connect, and Bugzilla bug reports have guided us to focus on the use-cases that matter to people using Firefox. When we succeed, it's a great feeling.
We're working on extending HDR support to photos, apps/games and general web content.
14 Jul 2026 4:15am GMT
13 Jul 2026
Planet Mozilla
The Rust Programming Language Blog: crates.io: development update
Another six months have passed since our last development update, and the crates.io team has been busy. Here's a summary of the most notable changes and improvements made to crates.io since then.
Source Code Viewer
Crate pages now have a "Code" tab that lets you browse the contents of published crate versions directly on crates.io. This shows you the exact files that cargo downloads when you add a crate as a dependency, which might differ from the linked repository. This makes it much easier to audit your dependencies, including files that never appear in the repository, like the normalized Cargo.toml files that cargo generates.

The viewer comes with a file tree sidebar with search functionality, syntax highlighting, and GitHub-style line selection, where clicking or dragging line numbers produces shareable #L10-L20 URLs.
Under the hood, the server now builds a zip file for every published version. Since the .crate files that cargo consumes are gzipped tarballs without random access support, a background job re-packs each of them into a seekable zip archive plus a JSON manifest describing the contained files. Both are served from our static CDN. The frontend then fetches only the manifest and loads each file on demand with an HTTP range request. Because of this architecture, browsing crate sources essentially adds no load on the crates.io API servers. Existing crate versions have been backfilled, so this works for old releases too.
The rendering library behind the code viewer is a diff renderer at heart, and that's no accident: a version-to-version diff viewer built on the same infrastructure is currently in the works. This will allow you to review exactly what changed between two published versions, right on crates.io. Stay tuned!
Untangling crates.io Accounts from GitHub
At the end of May, the crates.io team accepted RFC #3946. Crates.io accounts always have been tightly coupled to GitHub: signing in means "Log in with GitHub", and your crates.io identity is your GitHub username. The RFC changes that. It introduces usernames that are native to crates.io and independent of linked GitHub accounts, as a prerequisite for eventually supporting login via other identity providers.
The implementation of crates.io usernames has started, but there is still a lot left to do, most visibly the ability to change your crates.io username. After that is complete, there will be future RFCs and implementation for signing in with identity providers other than GitHub. Since all of this touches authentication and account security, we are deliberately taking it slow and rolling these changes out in small, carefully reviewed steps.
Advisories and Suggestions
In our January update we introduced the "Security" tab, which shows security advisories from the RustSec database. We have since taken this integration one step further: crates that RustSec has flagged as unmaintained now show a warning banner directly on their crate pages, linking to the corresponding advisory for details and possible alternatives. Thanks to Dirkjan Ochtman for implementing this feature!

Related to this, some popular crates have been largely absorbed into the Rust standard library over the years, like lazy_static, which has been superseded by std::sync::LazyLock since Rust 1.80. Crate pages of such crates now show a friendly "You might not need this dependency" banner describing the standard library replacement, and superseded crates in dependency lists get a small light bulb icon with a similar hint.

The dataset behind this feature lives in the new rust-lang/std-replacement-data repository, together with a documented inclusion policy: standard library replacements only, every entry must cite the stable std, core, or alloc API and Rust version, and crate maintainers get a notice-and-comment window before an entry is added. New entries can be proposed upstream and can benefit other tools too.
Ferris
The most delightful change of this cycle: the Ferris on our error pages now follows your mouse cursor with its eyes:

Getting a 404 error on crates.io is now slightly less sad.
Svelte Frontend Migration Completed
In our January update, we announced that we were experimenting with porting the crates.io frontend from Ember.js to Svelte. This experiment has concluded successfully: the new frontend reached feature parity, went through a public testing phase in April, became the default at the beginning of May, and the Ember.js app has been removed from our repository.
We designed this change to be invisible for our users, since the new frontend is a 1:1 port of the previous design and functionality. For the team and our contributors, however, it is a big deal: the frontend is now built on a more modern framework, which should make it easier for new contributors to get started. It also allows us to iterate faster, as the source code viewer above demonstrates.
We want to thank the Ember.js team for a framework that served crates.io well for many years, and the Svelte team for making the transition so enjoyable.
Miscellaneous
These were some of the more visible changes to crates.io over the past six months, but a lot has happened "under the hood" as well:
-
Search performance: Relevance-sorted search queries previously ranked every crate matching the query, which could take 1-2 seconds for short or common search terms. Ranking is now bounded to the 1,000 matching crates with the highest recent download counts.
-
Reverse dependencies performance: The reverse dependencies endpoint no longer recomputes the full dependent set on every request. It is now served from a precomputed table kept in sync by database triggers, turning an expensive join into a bounded index scan and greatly reducing the chance of getting a timeout error.
-
New ARCHITECTURE.md: If you've ever wondered how crates.io actually works, our
ARCHITECTURE.mddocument got a complete rewrite. It is now organized around the high-level systems that make up crates.io and how they fit together, and includes walkthroughs of what happens when you runcargo publish, why a typical crate download never touches our API servers, and how download counts are derived from CDN access logs. -
Definition lists: READMEs now render Markdown definition lists, a widely used Markdown extension. Our markdown renderer comrak already supported them, the extension just wasn't enabled yet. Thanks to @mistaste for this contribution!
-
CDN cache tags: Files uploaded to our static CDN now carry cache-tag metadata, allowing us to invalidate all cached files of a crate or a specific release in a single operation, instead of issuing one invalidation per file URL.
-
Caching improvements: We removed a global
Vary: Cookieresponse header that was preventing our CDNs from caching public API responses and frontend assets effectively. Per-user responses now useCache-Control: no-storeinstead, resulting in better cache hit rates at the CDN edge. -
Accessibility: We have made crates.io friendlier to screen readers: decorative icons are now hidden from the accessibility tree, heading hierarchies have been fixed, and lists are marked up as proper lists. ARIA snapshot tests now ensure that regressions can't slip in unnoticed. We plan to continue to improve crates.io accessibility over the coming months.
-
Git index performance: The background worker's local clone of the git index is now a bare and shallow repository, eliminating roughly 250,000 checked-out files and the full commit history from its disk, improving its performance as we see increased rates of crate publication. The periodic index squashing now goes through the GitHub API instead of generating large git packs locally, which had previously caused out-of-memory failures on the production worker.
Feedback
We hope you enjoyed this update on the development of crates.io. If you have any feedback or questions, please let us know on Zulip or GitHub. We are always happy to hear from you and are looking forward to your feedback!
13 Jul 2026 12:00am GMT