16 Jun 2026
Planet Mozilla
Firefox Developer Experience: Firefox WebDriver Newsletter 152
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 152 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.
In Firefox 152, multiple WebDriver bugs were fixed by contributors:
- Khalid AlHaddad extended the webExtension.install command to support installing web extensions enabled in Private Browsing mode.
- Sameem improved the Marionette and WebDriver BiDi screenshot commands to enforce maximum allowed dimensions.
- Amin Amir fixed a bug in browsingContext.sys.mjs where a private field was incorrectly assigned without the # prefix.
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!
General
- Improved the Marionette and WebDriver BiDi screenshot commands to enforce maximum allowed dimensions.
WebDriver BiDi
- Extended the
webExtension.installcommand to support installing web extensions in Firefox enabled in Private Browsing mode. - Improved the
browser.setDownloadBehaviorcommand to allow overriding the download target folder before the temporary file is created. - Fixed network events to only forward in-memory cached JavaScript responses when there is a matching network event collector, avoiding unnecessary data forwarding.
Marionette
- Improved the
WebDriver:NavigateandWebDriver:Refreshcommands to properly report errors when triggering the navigation fails, instead of silently ignoring them.
16 Jun 2026 2:00pm GMT
Firefox Tooling Announcements: Firefox Profiler Deployment (June 16, 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 source map symbolication and source view support (#6018)
- It requires Firefox changes that will land in Firefox 154, but after these changes, you will be able to see the source mapped function names as well as the source contents!
- [fatadel] Upgrade to React 19 (#6067)
- [fatadel] Drive counter tooltips from a tooltipRows schema (#6023)
- [Markus Stange] Support reading profiles from JsonSlabs files (#6037)
- [fatadel] Replace the footer-links overlay with a settings menu (#6042)
Other Changes:
- [Nazım Can Altınova] Fix call node context menu being hidden behind source view bottom box (#6045)
- [Nazım Can Altınova] Pass
--use-env-proxyonly when the node version is >= 24 (#6064) - [fatadel] Upgrade @firefox-devtools/react-contextmenu to 5.2.4 (#6066)
- [Markus Stange] Switch profiler-edit from minimist to commander (#6065)
- [Florian Quèze] Don't fail profile processing when a marker's stack field is not a backtrace (#6069)
- [fatadel] Remove unused undici-types package (#6074)
- [cathaysia] Update isLocalURL to include LAN addresses, .local domains, and hostn… (#5973)
- [Markus Stange] Fix from-url with binary profiles (#6072)
- [Markus Stange] Add an insertStackLabels helper. (#6076)
- [fatadel] Add TrackPower-tooltip-average-power-microwatt (#6080)
- [Markus Stange] Downgrade to React 19.1 to fix unusable dev build performance. (#6082)
- [spokodev] fix(FilterNavigatorBar): clip overflow so many breadcrumbs do not expand the parent (#6085)
- [Markus Stange] Move paddings inside the tree header cells. (#6002)
- [Markus Stange] Add an --insert-label-frames argument to the profiler-edit tool (#5966)
- [Markus Stange] Stop printing "error: too many arguments" during tests. (#6088)
- [Markus Stange] More additions to profiler-edit, for sp3 profiles (#6009)
- [Nazım Can Altınova] Do not rely on localized texts in the settings menu tests (#6101)
Big thanks to our amazing localizers for making this release possible:
- be: Andrei Mukamolau
- de: Ger
- de: Michael Köhler
- de: Ralf Duehnfahr
- el: Jim Spentzos
- en-CA: chutten
- en-GB: Ian Neal
- es-CL: ravmn
- fr: Théo Chevalier
- fr: wy
- fur: Fabio Tomat
- fy-NL: Fjoerfoks
- ia: Melo46
- it: Francesco Lodolo [:flod]
- nl: Mark Heijl
- ru: Valery Ledovskoy
- sr: Марко Костић (Marko Kostić)
- sv-SE: Andreas Pettersson
- tr: Grk
- tr: Selim Şumlu
- zh-CN: Olvcpr423
- 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
16 Jun 2026 1:38pm GMT
The Mozilla Blog: Firefox is easier than ever to customize

Firefox gives you many ways to make the browser your own, from privacy settings and AI controls to tab management, custom colors, and more. As we continue to improve Firefox, you get more control over how it works for you.
Today, we're introducing a redesigned settings experience that makes your options easier to find, understand, and manage.
Over time, some settings pages became crowded, related preferences were spread across different sections, and it wasn't always obvious where to look for a particular option. The redesign makes settings easier to navigate while preserving existing preferences and the flexibility and control that Firefox is known for.
The new settings feature a cleaner layout, modern visual design, improved labels and descriptions, and updated navigation, bringing related categories together. One of the most noticeable updates is the retirement of the long-standing "General" page. Many of the options that were previously there have now moved into more specific areas, including "Appearance," "Accessibility," "Languages," and "Tabs and browsing."
Some options may have moved, but your existing preferences haven't changed. The customization options you rely on are still available. If you're not sure where to find something, the search bar can help you locate it quickly. You can also visit Mozilla Support for more detailed guidance.
This redesign reflects extensive user research, including interviews, usability testing, card-sorting exercises, and analysis of usage data. It was also shaped by feedback from the Firefox community through Mozilla Connect, Reddit, and other channels, along with collaboration across Mozilla teams.
Thank you to everyone who shared their feedback along the way. Your insights helped shape the redesigned settings experience, and they'll continue to guide future improvements as Firefox evolves.

Take control of your internet
Download FirefoxThe post Firefox is easier than ever to customize appeared first on The Mozilla Blog.
16 Jun 2026 12:58pm GMT
The Mozilla Blog: What’s new in Firefox this June, and what’s next on the Firefox roadmap

Firefox has been busy introducing updates across productivity, privacy and AI. From Project Nova and browser-wide AI controls to expanded privacy protections and new ways to stay organized, the goal is simple: help you spend less time managing your browser and more time getting things done online.
But building the best browser isn't just about shipping new features. It's also about building them alongside the people who use Firefox every day.
Introducing the Firefox roadmap
Today, we're introducing the Firefox roadmap to give people a closer look at what we're building and a preview of where Firefox is heading next.

We've always built Firefox in the open and our new roadmap is an extension of that.
"Some of the best ideas in Firefox come directly from the people who use it," said Ajit Varma, head of Firefox. "The roadmap gives our community a new way to see what's taking shape, share feedback earlier and help guide where we're heading next."
The roadmap highlights what we're working on across Firefox, including productivity, privacy, performance, AI and the technologies that help make the web better for everyone.
Some items on the roadmap will be things we've already shared; others we'll be sharing publicly for the first time. Together, it'll provide a clearer picture of where Firefox is headed and the areas we're investing in to build a better browser.
Here's a look at what's rolling out now in Firefox 152, and what we're building next.
New in Firefox 152
- Tab Groups are now on Android: When "just a few" turns into dozens of tabs, it's hard to tell what's important or which tab had the thing you were actually looking for. Tab Groups have been helping Firefox desktop users bring order to the chaos. Now, they're starting to roll out on Firefox for Android, turning related mobile tabs into clear threads you can name, color and come back to when you're ready. iOS support will follow later this year.
- Simpler way to manage Firefox settings: We've redesigned Firefox settings to make it easier to find what you're looking for, discover controls you might not have known existed, and truly make Firefox your own. Don't worry: Your existing preferences aren't changing; just better organized. Get the details here and visit Mozilla Support for answers to all your settings questions.
- Privacy protections you can actually see: You shouldn't have to worry about trackers every time you browse. Firefox blocks many of them automatically so you can focus on what you came to do. The new Blocked Tracker Widget brings that protection into view, showing how many trackers Firefox has blocked over time, what kinds of tracking activity it stopped and how Firefox is working behind the scenes.
What's next on the Firefox roadmap
- Power users know that even small efficiency improvements add up over time. One of Firefox's most requested customization features, customizable keyboard shortcuts give you more control over how Firefox fits into your workflow, whether you're streamlining a routine task, adapting Firefox to your accessibility needs or simply prefer your own shortcuts.
- Designed to help people handle everyday PDF tasks without leaving the browser, upcoming PDF editing improvements will include the ability to split, merge and reorganize documents directly in Firefox.
- Multi-Account Containers, one of Firefox's most-loved browser extensions, helps people carve out a separate space for each part of their online life and keep work, personal and other online activities from bleeding into one another. We're now bringing Containers into the native Firefox experience, so more people can take advantage of one of Firefox's most distinctive tools without needing to install an add-on first.
- Firefox's free built-in VPN is coming to mobile devices, helping people stay protected across more of the devices they use every day. Whether you're traveling, connecting from public Wi-Fi or simply browsing away from home, bringing VPN to mobile is part of a broader effort to make Firefox privacy protections available wherever you go.
- Sometimes the fastest way to get information is simply to ask. With Quick Answers, people will be able to ask Firefox a question using their voice and receive a concise AI-generated answer right in the browser, with sources available when they want to learn more.
- We're continuing to build Smart Window, our optional and private AI browsing experience designed to help people get answers, compare information and make sense of what they're already reading online. You can now try it without joining a waitlist.
- We're adding Power Saving Mode to help identify tabs that consume the most resources on your phone and automatically reduce their impact, extending battery life without constantly managing what's running in the background.
Join the conversation
Try out the latest features, explore what's coming next and tell us what you think on Mozilla Connect.
We're also hosting a Reddit AMA on June 24 with Firefox product leaders, so bring your questions.
Talk soon.

Take control of your internet
Download FirefoxThe post What's new in Firefox this June, and what's next on the Firefox roadmap appeared first on The Mozilla Blog.
16 Jun 2026 12:57pm GMT
Thunderbird Blog: Mobile Progress Report: June 2026

The past month was busy; the theme was evolution. We went into this quarter with our own ideas for what we wanted to accomplish. However, our users had better ideas. With the release of Thunderbird's own mail service, Thundermail, the need for a better account settings import process across our services and apps became vital.
We have also heard from our users about issues they had with syncing, notifications, bugs, and more. As such, we refined our roadmap, because the goal is always a better, safer, more private email client, and delivering that experience is more important than any foregone projects. Our roadmap can change, but our goal to deliver the best cannot.
Android
On Android, our focus turned to our import function through a QR code. This helps transfer settings from Thunderbird desktop to mobile. We also ensured that it would work for our new Thundermail project. This allows our early Thundermail users to quickly move their accounts to the Thunderbird mobile app. Additionally, we merged fixes for importing accounts, getting the avatar monogram to match the account immediately after setup, and new translations.
We also began some exploratory work on one of our biggest upcoming projects. Our users have been clear about a recurring issue that they want resolved. Notifications. Notifications on an email client are tricky, especially one like ours, where we support so many different services. Users report not receiving notifications for newly delivered emails, even when polling or push are enabled, notifications appearing improperly in the notification shade, and many others.
We broke this up into two projects. The first priority will be to work on the quick fixes. These are bugs discovered through reports or our own testing. These fixes won't require an entire refactor of our sync, notification, or database features, allowing us to address user concerns without launching a big project. But we are intending to launch a big project. We'll do whatever we have to in order to make notifications work as expected. That's the second planned project, to consider larger performance improvements, even a full refactor of sync, notifications, and the app database if we have to. Prompt email delivery is essential. We're going to ensure Thunderbird becomes a trusted client for rapid email syncing and notification.
We've also begun investigating potential feature flag options. While we currently have internal feature flags for our debug builds, we're looking into options that we could host ourselves to ensure privacy, while also allowing us to enable features more quickly, without a full update. This would also allow us to roll back any changes that introduce issues without an app update. We hope it can allow us to launch products more quickly, and potentially even give end users more control over the features they have enabled.
iOS
The iOS app is coming along nicely, with the core libraries (IMAP, SMTP, and MIME) set up. We're working on how to store account data in the local database, as well as starting the email compose functionality. iOS will have a WYSIWYG editor for new messages, just as you've come to expect from other email clients. Also, this week has been busy with WWDC and understanding how the new tools and operating system will affect and improve our roadmap, mostly in the user interface.
Our Open Source Community
We wouldn't be who we are without the open source community at our core. Open source isn't just how we build software, it's how we plan, make, and grow. Our community has a say in what we do, which includes making changes, bug fixes, suggesting new features, and voicing complaints - this insight from you is our greatest strength. Over the past month, we've heard requests for new features, bug fixes, and changes, and we've adapted our plans for the rest of the year to focus on this. And hopefully deliver them in more bite-sized pieces.
First, the community has helped drive our upcoming projects. From notifications to investigations into spam filters, our community is helping drive our objectives. Our priorities and our roadmap have shifted thanks to that feedback. With our community having our back, we're making the best email client available on iOS and Android, and can't wait to deliver these improvements. We're listening and working on these highly requested changes.
A notable contribution from our community came in the form of a fix for our notification widget. The text wasn't scaling for users with different font size settings. This is a serious accessibility issue. Fortunately, a contributor pushed a fix which ensures the font size scales with the system. We're grateful for this help, and it's a perfect example of how we build better together.
Becoming a Contributor
Interested in contributing yourself? It can be tough to figure out where to start or how to go about it. Soon starting development on the Thunderbird for Android app will be easier than ever. We're moving our documentation around and adding templates and examples to make everything from requesting new features to working on bug fixes, and even documenting your changes easier. We've also added a new pull request template to help you write a detailed message explaining your pull request. This includes letting us know if you've used AI in the development and to what level it was used.
One note to say with contributions, given our limited team size and resources, we are focusing our efforts on the top items on the roadmap first and foremost. Second, we will spend a couple of weeks solving the largest impact bugs. Then we will spend a week or two supporting what contributions help resolve bug reports or align with our roadmap. We are intrigued about how AI can help us in these efforts, but we are also vigilant about the quality of the code. Potential contributors need a strong understanding of what they are contributing. This means being able to change, improve, and support the code they contribute in the future.
We have just three engineers on each of our iOS and Android teams. We're supported by wonderful designers and product folks, but we also couldn't do it without your support. So, thank you. We're doing our best to make a great product, and with your help, contributions, donations, bug reports, feature requests, and enthusiasm, we're able to do it better than ever. Thanks for checking in with us!
- Danielle G. (she/her), Senior Android Engineer
The post Mobile Progress Report: June 2026 appeared first on The Thunderbird Blog.
16 Jun 2026 11:00am GMT
15 Jun 2026
Planet Mozilla
Firefox Nightly: Giving You More Control – These Weeks in Firefox: Issue 204
Highlights
- Maxx Crawford added a pref to hide the New Tab logo so users can opt out of branding without altering page layout or resorting to CSS overrides.
- Harshit enabled video overlay detection in Nightly 153, allowing you to use the context menu to control videos on more pages! We plan on letting this ride out in Firefox 153.
- You can try it out on this Instagram reel in Nightly

- A note to WebExtension authors - as part of a planned deprecation announced last month, executeScript and insertCSS are now restricted from moz-extension pages starting in Firefox 152 - Bug 2015559
- Nicolas Chevobbe [:nchevobbe] added support and debugging for modern attr()(which is enabled on Nightly) (#2014751)

Friends of the Firefox team
Resolved bugs (excluding employees)
Script to find new contributors from bug list
Volunteers that fixed more than one bug
- Sam Johnson
- Sebastian Zartner [:sebo]
New contributors (🌟 = first patch)
- Immaculate Atim: Switch to using an array instead of an object string for browser.backup.enabled_on.profiles
- liz: Screenshots overlay visible on both splitview browsers
- 🌟 Rahman Mahmutović [:r_m]: Can't change content in box model in inspector for box-sizing:border-box elements
- Takeru Mitsumori: Fix typo in ID name about-translations-swap-langauges-icon in about-translations.html
- 🌟 Freya Arbjerg [:freyacodes]: Blackboxed columns are ignored
- tom.passarelli: tab-preview-panel emits unpaired popupshown/popuphidden events, breaking sidebar autohide
Project Updates
Add-ons / Web Extensions
Addon Manager & about:addons
- As part of the work for the Project Nova about:addons page restyling, the about:addons sidebar has been migrated to the moz-page-nav and moz-page-nav-button reusable components, improving accessibility and visual consistency with the Firefox Desktop about:settings page - Bug 1881767
WebExtensions Framework
- Implemented WebExtensions negative permissions infrastructure, providing the foundations for enterprise policy "blocked host permissions" features - Bug 1745823
- Restricted host permission changes for MV3 extensions force-installed via enterprise policy (matching similar behaviors provided by Chrome enterprise policy behaviors) - Bug 1904054
- Thanks to Mike Kaply for the implementation of this enterprise policy enforcement feature.
WebExtension APIs
- Fixed handling of <all_urls> as an API permission in Manifest V3, ensuring the permission is correctly initialized on extension install - Bug 1758306
DevTools
- Rahman Mahmutović [:r_m] made it possible to edit width/height in the box model section of the Layout panel (#1717176)
- Sebastian Zartner [:sebo] improved toggling tools driving in-page highlighters (e.g. the Measuring) (#1262773)
- Sebastian Zartner [:sebo] added a setting to control visibility of HTML comments in the markup view (#1455294)
- Freya Arbjerg [:freyacodes] fixed an issue in script blackboxing (#2036767)
- Alexandre Poirot [:ochameau] replaced custom preference to log RDP messages with MOZ_LOG (#1622857)
- Alexandre Poirot [:ochameau] fixed retrieval of garbage collected script text content (#1758454)
WebDriver
- 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.
- Alexandra Borovova updated the events for new top-level browsing contexts: we will not send anymore "browsingContext.domContentLoaded" and "browsingContext.load" events for them, instead the "browsingContext.contextCreated" event will be sent when a tab is ready to be used. This is required to align with the expected per-spec behavior.
- Henrik Skupin landed a patch allowing geckodriver to gracefully shut down Firefox when geckodriver itself is terminated.
- Hiroyuki Ikezoe disabled Firefox's "scroll axis lock" feature so WebDriver actions for wheel input devices can scroll in arbitrary directions when using pan gestures.
Lint, Docs and Workflow
- Added a rule to prevent new uses of Preferences.sys.mjs.
- The browser environment globals within ESLint have now been updated. These include Sanitizer, VideoFrame and a few other new ones.
- Temporal, and some other definitions have been added to TypeScript.
New Tab Page
- Much has happened in the last 2 weeks! Here's a full bug list, and here are some highlights.
- Dre fixed the List widget that was creating a new list too eagerly on the New Tab Page (2033592) - prevents accidental list creation and improves the Lists UI reliability.
- Maxx Crawford fixed Weather widget small card layout issues with opt-in location options and an error message displayed, resolving card overflow and removing the spurious opt-in error so users see a compact Weather card and correct location prompts on New Tab.
- Reem Hamoui added key dates state to the Sports widget, enabling the Sports card to surface event deadlines/key-date highlights on New Tab so sports users see timely date info.
- Scott Downe added a manage widgets option to the New Tab nova widgets context menu, giving users a direct context-menu entry to open the widget management flow from any widget with Nova enabled.
- Scott Downe added a reusable Newtab widget base component to centralize lifecycle, focus/keyboard handling, DOM templates, and telemetry hooks, reducing duplication and making widget behavior more consistent; see Newtab widget base component.
- Dre converted per-widget expansion handling to a shared widget expansion handler to unify expand/collapse state management and prevent widgets from incorrectly retaining or losing expanded state; see Convert widget expansion handling to shared widget expansion.
- Nina Pypchenko [:nina-py] updated the Sports widget to populate the "follow teams" state from the /teams endpoint, so follow/unfollow toggles now reflect server-side subscriptions and reduce incorrect follow states.
- Scott Downe moved widget menu items within New Tab widgets to standardize menu ordering and action grouping, so users find Add/Remove/Configure entries in expected positions across platforms.
- Dre fixed a World Clock city search bug for the word clocks widget, restoring expected search filtering/matching so city lookups return correct results.
- Scott Downe fixed an issue where the New Tab small weather widget size change didn't always apply by correcting the widget size update path (JS/CSS layout interactions), improving consistent rendering for small-tile weather across responsive breakpoints and platforms; see Newtab small weather widget size change doesn't always work.
- Nina Pypchenko [:nina-py] added a group stage section to match highlights in the sports widget on New Tab so users now see stage-aware grouping and stage labels on match highlight cards, making tournament context (group vs knockout) visible while browsing highlights.
- Dre fixed the small world clock widget not expanding to large while editing clocks so users can enter edit mode and expand the widget as expected; the change wires the edit-mode resize handler to update widget size/class during edits.
- Maxx Crawford added WCW OMC message strings so World Cup widget messaging flows on New Tab now display the correct copy (localized where available) instead of falling back to missing-text behavior.
- Reem Hamoui added a "View all" button and a list view for the results tab at medium widget size so Sports widget users on medium New Tab tiles can expand results and scroll full lists without resizing the widget.
- Maxx Crawford added WCW "Watch Live" stream strings to the Sports widget strings bundle so the widget can surface a localized "Watch Live" CTA for applicable events.
- Dre restored VoiceOver reachability for Edit/Remove in World Clock on macOS so macOS VoiceOver users can now focus and activate clock Edit/Remove controls thanks to accessibility role/label and focus-order fixes.
- Maxx Crawford removed the persistent browser logo when all new-tab features (Top Sites, widgets, content feed) are disabled by adding a conditional render guard in the New Tab component, preventing an orphaned logo (2041033).
- Mike Conley added New Tab jest tests to the node tests Tier 1 CI job Run newtab jest tests as part of node tests Tier 1 job to catch regressions earlier in CI
- Irene Ni shipped multiple visual fixes for the Sports widget Sports widget - various visual fixes (spacing, truncation, icon alignment, clipping) to improve readability and layout on constrained viewports.
Picture-in-Picture
- kpatenio adjusted our YouTube site specific wrapper so that the URL bar toggle appears more reliably, especially when selecting videos from the YouTube search page.
- Thanks to Sylvestre for patching some bugs to prevent some spurious console errors!
- Niklas fixed captions on autopip videos failing to sync with the origin videos.
Performance Tools (aka Firefox Profiler)
- Firefox Profiler now has a CLI! We also added a profiler-analysis skill to the Firefox codebase. Once you capture a performance profile, you can ask Claude or an AI to analyze it by providing a link or local path. You can use it to analyze a performance regression or debug an issue if you have a profile at hand.
- https://www.npmjs.com/package/@firefox-devtools/profiler-cli
- You can install it with npm install -g @firefox-devtools/profiler-cli@latest
Search and Urlbar
Nova UI refresh
- Drew and Daisuke continued working on reorganizing styles and updating the urlbar for Nova.
- 2019154, 2019152, 2041501, 2040532
Suggest
- Drew landed several Suggest improvements: realtime suggestions colors, sports suggestions received World Cup tweaks, and online Suggest via OHTTP was enabled for eligible users in Firefox 153.
- 2040561, 2039753, 2035614, 2038843
Adaptive autofill
- James fixed soft-block counting to track autofill dismisses, rather than consecutive backspaces on the same autofill, and added telemetry to measure URLs reintegration after blocking.
- 2040819, 2037177
Quick actions
- Dharma created a new Firefox Labs quick action, fixed the Update action button, and re-enabled ScotchBonnet in some tests that were not updated yet.
- Caleb added Calculator support for certain unicode operators.
- 2023169, 1928635, 1923383, 2033861
Multi Context Address Bar
- Moritz continued refactoring the urlbar code: converted some of the js modules to not be system modules, fixed dynamic results templates, incorrect reuse of result rows, and keyboard shortcuts on the unified search button panel.
- 2039297, 2036095, 2039844, 2037933, 2030050
Other
- Marco, Drew and Daisuke fixed several intermittent test failures.
- 2038510, 2023908, 2011584, 1938142, 1971091
Search
- Mark removed old WebExtension-based search engines from the source tree, removed loading of search add-ons from resource://search-extensions/.
- Caleb fixed multiple documentation issues and added a test covering searches from a private window.
- 1904613, 2035878, 2037942, 2033545, 2005724
Places
- Marco removed some unnecessary database transactions, fixed the bookmarks panel folder dropdown on Windows, and resolved several intermittent test failures.
- Thanks to Sam Johnson who fixed the bookmark edit panel showing "mobile" instead of "Mobile Bookmarks".
- 2039534, 1505800, 2008829, 2029541, 2035084
15 Jun 2026 5:26pm GMT
12 Jun 2026
Planet Mozilla
About:Community: May highlights: Contributor spotlight, Web Serial support, and more
Hi Mozillians,
For years, the Mozilla Community Newsletter has served as a monthly touchpoint for contributors and community members across the Mozilla ecosystem. Coordinated by the Customer Experience (CX) team, it helps keep our global contributor and product communities informed, connected, and engaged through updates, contributor stories, announcements, and opportunities to get involved.
While the newsletter has traditionally been distributed directly to community members, we recognize that many of these updates are valuable to a broader audience as well. That's why we're bringing our content into a blog post format, making it easier for anyone interested in Mozilla's mission, products, and community work to stay informed.
Whether you're a longtime contributor, a Firefox enthusiast, or simply curious about what's happening across Mozilla, we hope these updates provide useful insights into the people, projects, and initiatives shaping our community.
In this edition, we're sharing our latest updates from May 2026. It's packed with the latest community news, contributor highlights, project updates, and opportunities to get involved in Mozilla's work around the world.
So, without further ado, let's dive in!
From localizing to Firefox Enterprise
Long-time Mozillian Valery recently shared an open-source project he built to help Firefox Enterprise administrators manage Firefox deployments more easily called Browser Policy Manager or BPM. Beyond the tool itself, this story is a proof of the long-term value of investing in the community. Stories like Valery's show how community contributions evolve over time and why fostering a strong, engaged contributor community continues to pay dividends across the Mozilla ecosystem.
Firefox Referrals: We want to hear from you
Could Firefox users help grow the community by recommending Firefox to friends and family? That's the question being explored in a recent Mozilla Connect discussion about potential referral programs. Join the conversation to share your thoughts on what would motivate you to recommend Firefox, and what a referral experience should (or shouldn't) look like.
Web Serial finally arrives in Firefox 151
After years of community interest and requests dating back more than a decade, Firefox 151 now includes support for the Web Serial API. Developers can use Firefox to communicate with and manage serial-connected devices such as ESP boards, Raspberry Pi Picos, 3D printers, CNC machines, and other microcontrollers directly from the web. It's a long-awaited milestone for the maker and hardware community, and we're excited to finally see it land in Firefox.
Community spotlight
In this community spotlight, we feature Baurzhan Muftakhidinov, whose work has helped bring Firefox and many other open source projects to Kazakh users. His story is a testament to the power of persistence, community, and the importance of keeping smaller languages visible online.
P.S.
Enjoyed these updates? Subscribe to the Mozilla Community Newsletter and get the latest updates delivered straight to your inbox.
12 Jun 2026 11:28am GMT
11 Jun 2026
Planet Mozilla
Mozilla Privacy Blog: A Handful of Companies Control the Web. AICOA Can Change That.
Mozilla Champions the Reintroduction of the American Innovation and Choice Online Act (AICOA)
Today, only a handful of tech companies shape the online experience for the more than 300 million internet users in America. This concentration of power is exactly why we need legislation that advances competition and user choice. It's all the more urgent as AI transforms not just the tools that people use, but also magnifies the competitive inequities underlying the web itself.
The American Innovation and Choice Online Act (AICOA) is bipartisan legislation designed to curb harmful gatekeeper behaviors of the biggest tech platforms. The bill does so by prohibiting dominant platforms from unfairly preferencing their own products, discriminating against tech competitors, and preventing interoperability - all practices that stop the best product winning and stifle consumer control. The goal is straightforward: companies should compete based on the quality of their products, not by leveraging anticompetitive tactics.
As the builder and operator of the Firefox browser and the browser engine Gecko, Mozilla has firsthand experience with the impact of the exclusionary practices AICOA seeks to prevent. For example, deceptive design tactics deployed by operating systems make it difficult for people to install and keep Firefox as their preferred browser. Browsers are the portal through which people access the open web, and users should define that interaction. AICOA would help limit the ability of operating systems to steer users toward affiliated products through deceptive design choices. Ensuring meaningful user choice online is not just about variety; it reflects values and individual preferences. Openness and innovation thrives when the web is built around platforms that serve people, not the other way round.
Browser engines, while lesser-known, are among the most complex and consequential pieces of infrastructure on the modern internet, impacting user-focused innovations in privacy, security, speed, and more. Gecko is one of only three widely used engines and the only independent browser engine. The importance of that competitive counterweight cannot be underestimated. When platform owners favor their own vertically integrated products, independent challengers face barriers that have nothing to do with product quality and everything to do with a monopolized market.
It's important to recognize that antitrust reform can make the internet more private and secure than it is today, as we've consistently emphasized. For example, in 2021, Firefox was at the forefront of developing technology against cross-site tracking, but could not release the technology to Firefox users on iOS because of app store rules preferring Apple's own browser engine, blocking alternatives like Gecko.
We're champions of AICOA and look forward to working with members of Congress to push this legislation forward and tackle longstanding anticompetitive practices. Mozilla thanks Senators Grassley and Klobuchar for their leadership in advancing competition. A thriving tech ecosystem requires an open, fair, and competitive market where innovative services can compete on merit and people can control their own experiences online.
The post A Handful of Companies Control the Web. AICOA Can Change That. appeared first on Open Policy & Advocacy.
11 Jun 2026 2:05pm GMT
Pascal Chevrel: Spell-checking for more Firefox users — a community effort
A while back, I stumbled onto something that turned into a rewarding side-project at Mozilla.
Firefox ships with a built-in spellchecker, but it only activates if a dictionary for your language is bundled with the browser. Coverage had grown organically over the years - driven largely by localizers and community members adding support for their own languages. Dictionary work was actually very active in the early years of the Mozilla project, but like many things in a large open-source codebase with a lot to manage, it had quietly received less attention over time, for no particularly good reason. So I decided to change that.
Taking stock
I put together a full inventory dashboard of every third-party dictionary shipped in Firefox Desktop, cataloguing sources, upstream health, and - critically - licensing.
Licensing turns out to be the main bottleneck. Firefox is open-source software, so any dictionary we ship has to carry a licence compatible with the Mozilla codebase. Some excellent dictionaries exist for languages Firefox supports, but their licences don't allow direct inclusion. In those cases, the dictionary can still reach users - but only as a Firefox extension they have to find and install manually, rather than something that just works out of the box.
The goal of the inventory wasn't to point fingers at anything. It was to make the full picture visible, so that anyone who wanted to help would know exactly where to start.
Plugging into the community
Once the inventory existed, the work was really about connecting the right people. Mozilla's localizer community already had the expertise and motivation - what was sometimes missing was a clear entry point. I took care of all the patches myself, so that localizers wouldn't have to deal with the technical side of things. This work was done in coordination with Mozilla's Localization drivers team, who own the dictionary infrastructure and reviewed and merged the changes.
The results
We expanded the number of locales shipping with a built-in dictionary from 30 to 41. This shipped last week with Firefox 151.0.3, and these improvements also benefit Thunderbird users, since both applications share the same dictionary infrastructure.
New dictionaries added: Croatian, English (UK), Georgian, Persian, Slovenian, Tajik, Tamil, Tibetan, Turkish, Welsh, and Xhosa.
Updated dictionaries: Bulgarian, Danish, French, Hungarian, Indonesian, Latvian, Polish, Romansh, and Swedish.
Stirring the pot
Part of the reason for doing this work publicly - building the inventory, filing the bugs, making the gaps visible - was to give people with the right expertise a reason to step in themselves. That's exactly what happened.
For Turkish and Russian, the existing open-source Hunspell dictionaries had become outdated - vocabulary and linguistic rules that hadn't kept pace with how the languages are actually used today. Selim (our Turkish l10n lead) and Valentin (our Russian l10n lead) each decided to take matters into their own hands.
Selim forked the TDD Turkish dictionary and updated it with modern vocabulary, better circumflex support, and performance improvements - the result is hunspell-tr-moz, now shipping in Firefox 151.0.3. Valentin built a new modern Russian dictionary from scratch, ru-spelling-dictionary, released under MPL-2.0. It's currently available as a Firefox extension - if you use Russian, Valentin would appreciate feedback on the quality before it's integrated directly into Firefox.
Both projects are public and open-source.
What's still in the pipeline
The licence question is also quietly resolving itself for a couple more locales. The maintainers of the Kabyle and Asturian dictionaries have agreed to relicense their work to allow direct inclusion in Firefox. Once that's done, those communities will join the list too.
There are still gaps in the inventory. Some are licence issues that may resolve over time. But for many of the remaining locales, the honest answer is that we simply haven't looked hard enough yet. Dictionaries are often individual passion projects or work coming out of linguistics circles - they exist, but finding them takes investigation. If you know of a dictionary for a language Firefox doesn't currently support, that's exactly the kind of lead worth following up on.
An open invitation
Mozilla is still a place where a motivated contributor can find a corner of the project, do meaningful work, and have a real impact - without needing to be a browser engineer or a Mozilla insider.
The inventory dashboard is public. If you're a localizer, a linguist, or a dictionary maintainer and you want to help bring spellchecking to more Firefox users, the gaps are clearly documented. And if you maintain a dictionary that could be included but licensing is an obstacle, that's a conversation worth having.
See you in May 2027 for the next update.
11 Jun 2026 1:59pm GMT
10 Jun 2026
Planet Mozilla
This Week In Rust: This Week in Rust 655
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
- How Josh helps Rust manage code across multiple repositories
- Maintainer spotlight: Tiffany Pek Yuan (@tiif)
Newsletters
Project/Tooling Updates
- Announcing stdx, Rust's extended standard library
- OmniScope 0.2.0 released:FFI static detection tool based on LLVM IR
- Announcing Asterinas 0.18.0
- Oryxis SSH 0.8: split panes
- Ratatui 0.30.1 is released - a Rust library for cooking up terminal user interfaces
- @utoo/pack: A Next-Generation Build Tool Based on Turbopack
- Pico de Gallo - a USB-attached protocol bridge for developing embedded-hal drivers on your laptop
- kache 0.5.0: designing a correct compile-cache key
- Announcing smb2: a very fast pure-Rust SMB2/3 client
Observations/Thoughts
- Only Bounds
- Porting our Django backend to Rust improved the infra usage by 90%
- Decimal Crates Comparison and Benchmark | Chinese version
- TeaQL Robot Task Board: a Rust TUI showcase for auditable business workflows
- [video] Rayon is NOT for games - use this instead
- [audio] Veo with Anders Hellerup Madsen and Gorm Casper
Rust Walkthroughs
- [series] Who Runs Your Rust Future? Hands-On Intro to Async Rust
- Extend MySQL Using Rust
- Learn Rust Smart Pointers and Interior Mutability by Building Git Commit Graph Viewer
- heap underflow: classic algorithm solutions in idiomatic Rust, runnable in the browser
Crate of the Week
This week's crate is rustion, a SSH bastion server.
Thanks to handewo 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.
- cuda-oxide Windows fork - test the Windows MSVC release on more CUDA/Windows setups
- openslate - add unit tests for slugify() in api/src/notes.rs
- openslate - add integration tests for notes CRUD in api/src/notes.rs
- openslate - add integration tests for auth flow in api/src/users.rs
- openslate - add unit tests for build_fts_query() in api/src/search.rs
- openslate - add integration tests for auth middleware and logout in api/src/auth.rs
- openslate - add integration tests for media endpoints (DB layer) in api/src/media.rs
- openslate - add unit tests for ext_from_mime() and filename_from_url() in api/src/media.rs
- reliakit - add a typed_csv example to the umbrella crate
- reliakit - implement CsvField for char
- reliakit - implement CsvField for the core::net address types
- reliakit - write a short "which resilience block do I use?" guide
- reliakit - extract a reusable rolling-window counter from RollingBreaker
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
526 pull requests were merged in the last week
Compiler
- add
extern "tail"calling convention - add very basic "comptime" fn implementation
- avoid
unreachable_codeon required return values - cleanup and optimize
render_impls - macros: report unbound metavariables directly
- rewrite
rustc_span::symbol::Internerto avoid double hashing - staticlib hide internal symbols
Library
- add APIs for case folding to the standard library
- add
_valueAPI for number literals in proc-macro - further optimize
SliceIndex<str>impl forRange<usize> - improve TLS codegen by marking the panic/init path as cold
- perf: use
get_uncheckedforTwoWaySearcher - stabilize
PathBuf::into_string - stabilize
Result::map_or_defaultandOption::map_or_default
Cargo
Rustdoc
- IXCRE: preserve sizedness bounds on type params belonging to the parent item
- don't link
doc(hidden)associated type projections - fix trait impl ordering
- render
implrestriction
Clippy
- support
iter_mutinITER_NEXT_SLICE borrowed_box: clean-up, improve suggestion messagedouble_must_use: make the lint machine-applicable in single-attribute caseiter_cloned_collect: split off the suggestion from the main message- add
manual_isolate_lowest_onelint - detect more ranges in
single_range_in_vec_init - do not trigger
inline_trait_boundson auto-derived code - extend
extra_unused_lifetimesfor spuriousfor<'a> large_const_arrays: check nested large arrays- fix
explicit_counter_loopfalse positive when the counter is only modified inside theelseblock oflet...elsebinding - fix
result_large_errandresult_unit_errnot triggering on async functions - fix
unused_async_trait_implsuggestions with return statements - fix lints duplications in
unknown_attributeandrenamed_builtin_attr - obtaining the metadata of a const pointer is a const operation
- perf: avoid cloning associated items in
empty_line_after - perf: skip the
boxed_localwalk for functions without a Box parameter - perf: skip the
inline_alwaysrelevance walk for items without the attribute
Rust-Analyzer
feat(diagnostics): emit error for infer vars in non-inference contexts- adopt uv's AI policy
- distribute windows builts with mimalloc
- lower field defaults to
rustc_type_ir::Consts RunnableKind::Testshould map toproject_json::RunnableKind::TestOneextract_functionmisses&mutforcontainer[i].mut_method()- do not emit a "type annotations needed" error on
include_bytes!()where the array length cannot be inferred - no generate unused generic params in trait sign
- parse OR pattern types
- rename schema subItems with
sub_items - implement
rust-analyzer/evaluatePredicatelsp extension - parse unnamed
enumvariants
Rust Compiler Performance Triage
A fairly noisy week, with a bunch of small regressions contained within, leading to a slight increase on average in instruction counts. This week had a lot of large rollups, likely due to some CI problems, but thankfully many of those came with pre-triaged perf results by the time (thank you to those triagers!). Roughly similar slight regressions for cycles and wall times across the week.
Triage done by @simulacrum. Revision range: 4804ad7e..f3ef3bd8
2 Regressions, 0 Improvements, 10 Mixed; 5 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:
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
- Document panic in
RangeInclusive::from(legacy::RangeInclusive) - Tracking Issue for explicit-endian String::from_utf16
- Tracking Issue for
substr_rangeand related methods - Decide and document where stdarch intrinsics are allowed to diverge from asm behavior
- Document that
ManuallyDrop's Box interaction has been fixed - Add temporary scope to assert_eq and assert_ne
- Clean up crate type names to fix dylib vs staticlib confusion
- Add
T: PartialEqbounds to derivedStructuralPartialEqimpls. - stabilize feature
float_algebraic
No Items entered Final Comment Period this week for Rust RFCs, Cargo, Language Team, Language Reference 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-06-10 - 2026-07-08 🦀
Virtual
- 2026-06-10 | Virtual (Girona, ES) | Rust Girona
- 2026-06-12 | Virtual (Kenya, KE) | RustaceansKenya
- 2026-06-16 | Virtual (Washington, DC, US) | Rust DC
- 2026-06-17 | Hybrid (Vancouver, BC, CA) | Vancouver Rust
- 2026-06-17 | Virtual (Girona, ES) | Rust Girona
- 2026-06-18 | Hybrid (Seattle, WA, US) | Seattle Rust User Group
- 2026-06-18 | Virtual (Berlin, DE) | Rust Berlin
- 2026-06-21 | Virtual (Dallas, TX, US) | Dallas Rust User Meetup
- 2026-06-23 | Virtual (Dallas, TX, US) | Dallas Rust User Meetup
- 2026-06-23 | Virtual (London, UK) | Women in Rust
- 2026-07-01 | Virtual (Indianapolis, IN, US) | Indy Rust
- 2026-07-02 | Virtual (Berlin, DE) | Rust Berlin
- 2026-07-02 | Virtual (Nürnberg, DE) | Rust Nuremberg
- 2026-07-05 | Virtual (Dallas, TX, US) | Dallas Rust User Meetup
- 2026-07-07 | Virtual (London, GB) | Women in Rust
Europe
- 2026-06-10 | Köln, DE | Rust Cologne
- 2026-06-10 | München, DE | Rust Munich
- 2026-06-11 | Berlin, DE | Rust Berlin
- 2026-06-11 | Switzerland, CH | PostTenebrasLab
- 2026-06-12 - 2026-06-14 | Kraków, PL | Rustmeet
- 2026-06-16 | Leipzig, DE | Rust - Modern Systems Programming in Leipzig
- 2026-06-16 | Milano, IT | Rust Language Milan
- 2026-06-18 | Aarhus, DK | Rust Aarhus
- 2026-06-18 | Barcelona, ES | BcnRust
- 2026-06-19 | Dresden, DE | Rust Dresden
- 2026-06-23 | Paris, FR | Rust Paris
- 2026-06-23 | Warsaw, PL | Rust Warsaw
- 2026-06-25 | Berlin, DE | Rust Berlin
- 2026-07-02 | Edinburgh, GB | Rust and Friends
- 2026-07-02 | Enschede, OV, NL | Baseflow Tech Meetups
- 2026-07-08 | Dublin, IE | Rust Dublin
North America
- 2026-06-11 | Lehi, UT, US | Utah Rust
- 2026-06-11 | Mountain View, CA, US | Hacker Dojo
- 2026-06-11 | San Diego, CA, US | San Diego Rust
- 2026-06-16 | San Francisco, CA, US | San Francisco Rust Study Group
- 2026-06-16 | San Francisco, CA, US | San Francisco Rust Study Group
- 2026-06-17 | Hybrid (Vancouver, BC, CA) | Vancouver Rust
- 2026-06-18 | Hybrid (Seattle, WA, US) | Seattle Rust User Group
- 2026-06-24 | Austin, TX, US | Rust ATX
- 2026-06-24 | Los Angeles, CA, US | Rust Los Angeles
- 2026-06-25 | Atlanta, GA, US | Rust Atlanta
- 2026-06-26 | New York, NY, US | Rust NYC
- 2026-07-02 | Saint Louis, MO, US | STL Rust
Oceania
- 2026-06-11 | Brisbane City, QL, AU | Rust Brisbane
- 2026-06-25 | Melbourne, AU | Rust Melbourne
South America
- 2026-06-18 | Florianópolis, BR | Rust SC
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
It's a footgun, yes, but it's a sound footgun.
- Prof. Dr. Ralf Jung on 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
10 Jun 2026 4:00am GMT
09 Jun 2026
Planet Mozilla
Firefox Tooling Announcements: Happy BMO Push Day! (20260609.1)
The following changes have been pushed to bugzilla.mozilla.org:
- Bug 2043429 - Selenium test 1_test_bug_edit.t intermittently fails when attemtping to click on comment reactions
- Bug 1995467 - Show dependency tree on meta bugs by default
- Bug 2043322 - text/html attachments are downloaded instead of viewing in-browser
- Bug 2038298 - Render Phabricator revisions stack fork in the parent's row
- Bug 2045855 - phab-bot attempts to set approval flags for disabled flags
- Bug 2044471 - Add loading indicator to embedded dependency tree
- Bug 2034051 - Update Bugzilla Etiquette with guidance about AI usage
- Bug 2033409 - Pasting a link from the clipboard after using the Link button inserts additional markdown into the link
Discuss these changes in the BMO Matrix Room
1 post - 1 participant
09 Jun 2026 5:28pm GMT
The Mozilla Blog: Browse more privately all summer with Firefox’s free built-in VPN

For a limited time, where the VPN is available, users can get unlimited VPN bandwidth in Firefox - up from the 50 gigabytes monthly limit - plus access to over 25 country locations to browse from. Don't have Firefox yet? Try it now.
Firefox's free built-in VPN usually gives eligible users 50 GB of free bandwidth each month. From now through Aug. 31, we're making that unlimited, so you have more room to browse privately while you travel, work from public Wi-Fi or connect from somewhere new. Not only will users get unlimited bandwidth, but we're also unlocking access to 28 country locations to browse from during this period. The VPN returns to its standard 50 GB monthly limit and a standard location set on Sept. 1.
Whether you're using the airport Wi-Fi, booking a last-minute flight or trying to access websites away from home, here are a few ways Firefox's VPN can help while you travel:
Stay protected on public Wi-Fi at the airport, train station or hotel
When you're traveling, public Wi-Fi is often part of the deal. But those networks can make it easier for others to spy on your traffic and see which websites you're visiting. Firefox's built-in VPN adds another layer of privacy by helping mask your IP address and makes it harder for others on the network to see your browsing activity.
Browse like you're back home
The web can feel a little funky when you go abroad. Sites may load in another language, show a different local version or have trouble recognizing where you usually browse from. Maybe you need to schedule your monthly pharmacy prescription, but the site isn't loading the way it normally does from home. Or maybe you're trying to order a new dress to your apartment but the address isn't registering properly.
With Firefox's built-in VPN, you can switch your browsing location back to your home country so the sites and services you rely on feel a little more familiar while you're away.
Or choose where you browse from
Firefox can recommend a VPN location based on what's fastest and most convenient. But you can also choose from more available locations, whether you want to browse closer to home or see how the web looks somewhere else.
The full set of countries available during this summer period include: Australia, Austria, Belgium, Bulgaria, Canada, Chile, Colombia, Denmark, Finland, France, Germany, Ireland, Italy, Malaysia, Mexico, Netherlands, New Zealand, Portugal, Singapore, Spain, Sweden, Thailand, Norway, South Africa, United Kingdom and United States.
Turn off VPN for specific sites
Some sites don't always work smoothly with VPNs. If one is giving you trouble, you can turn the VPN off for that website right from the panel. You can also add sites to a list in advanced settings if you don't want them to connect through the VPN.
Free VPN for wherever summer takes you
Wherever you're logging on this summer, Firefox's built-in VPN gives you an easy way to add another layer of protection while you browse. More control for summer browsing, right where you need it. As it should be.

Take control of your internet
Download FirefoxThe post Browse more privately all summer with Firefox's free built-in VPN appeared first on The Mozilla Blog.
09 Jun 2026 3:58pm GMT
Niko Matsakis: Only Bounds
only bounds are going to be the most impactful change to Rust that you've never heard of. They are currently being designed and developed by the Arm team (David Wood, Rémy Rakic, et al.) as part of the Sized Hierarchy and Scalable Vector Extension project goal. This post explores the feature and aims to answer a particular question about the design (the scope of bounds, I'll explain). But before I dive in, I want to give a bit of context.
Rust generics have a Sized bound by default today
In today's Rust, every type parameter (except for Self) has a default bound called Sized:
// So this function...
fn identity<T>(t: T) -> T {
t
}
// ...is actually short for
fn identity<T>(t: T) -> T
where
T: Sized, // <-- Added by default!
{
t
}
A type T implements Sized if the compiler can compute the size of a T value at compilation time. This is true for almost every type, with a few notable exceptions. Consider [u32], which refers to "some number of u32 instances". We know that a single u32 is 4 bytes, but without knowing how many u32 there are, you can't know the size of [u32]. This means you can't have a value of type [u32] on the stack (how big should the stack frame be?).
You opt out with ?Sized
However, if you have a function like by_ref, that just takes the value by reference (i.e., by pointer), you shouldn't need to know how big the [u32] value is, because you're not manipulating it directly. You can have a type parameter U that doesn't require Sized, but you have to explicitly "opt out" from the default bound:
fn by_ref<U>(t: &U)
where
U: ?Sized, // <-- Opt out from the default
{ }
As a fun bit of historical trivia, this system was introduced way back in 2014 to accommodate Dynamically Sized Types. Before that, &[u32] was actually a built-in, indivisible type; we even wrote it like [u32]/& for a time.1
But Sized vs ?Sized isn't enough for everything we need
The Sized vs ?Sized design has served us reasonably well but it is also showing its limits. It turns out that "value has a statically computable size" vs "each value has a distinct size computable at runtime" doesn't cover all the things you might want. For example, extern types are types whose values have no known size, even at runtime. And then Arm's Scalable Vector Extension want to describe SIMD types where every value of the type has the same size (unlike str and [T], where each value can have a different length) but where that size is not known until runtime.
A richer Sized hierarchy
Rather than just Sized or ?Sized, what we really want is to have a richer hierarchy. The current plans look something like this:
flowchart TD
subgraph S["Sizedness traits"]
Sized[["Sized (default)"]] -- extends --> MetadataSized
MetadataSized -- extends --> MaybeSized
end
where
trait Sizedmeans that all values have the same size and that size can be computed knowing only the type.trait MetadataSizedmeans that values can have different sizes and that size can be computed given the metadata attached to a reference to the value. Examples include[T]ordyn Trait.trait MaybeSizedis implemented for all values and tells you nothing about the value's size.
Two caveats:
- I'm excluding the way that Arm's Scalable Vector Extension fit into this, because it's orthogonal.
- The trait names aren't settled. I'm using the names I understand the libs-api team to prefer; they're not my favorites, but that's ultimately the team who owns stdlib bikesheds, so I defer to them.2
Problem: ?Sized notation doesn't scale to this hierarchy
But now we have a kind of problem. The ?Sized notation was predicated3 on the idea that users should specify the default bound they are opting out of - i.e., the ? is meant to say "I don't know if this is Sized or not" (unlike the default, where you know it is Sized). But "opting out" from a bound doesn't work so well with a multi-level hierarchy. When you write ?Sized, does that correspond to T: MetadataSized (but not T: Sized)? And what if we want to insert another level in between T: MetadataSized and T: Sized later? Then we either have to change what T: ?Sized means (to refer to the new bound) or we have to have T: ?Sized drop two levels down the hierarchy. Even more annoying, what do we do while that middle rung is unstable? Surely T: ?Sized shouldn't refer to an unstable trait… what if we decide to remove it
Solution: only bounds
The new proposal is to write T: only MetadataSized or T: only UnknownSized instead of T: ?Sized. An only bound combines two things:
- Like any bound, it includes a "minimum requirement" - i.e.,
T: only MetadataSizedmeans thatTmust implement at leastMetadataSized. - It additionally disables some default bounds - i.e., we will not add the default
T: Sizedbound.
The name only comes from the fact that T: Sized implies T: MetadataSized. So the default of T: Sized already means that T: MetadataSized for free; but when you write only MetadataSized, you are saying "I don't need the full hierarchy, just MetadataSized will do".
only bounds work like normal bounds: ask for what you need
A nice feature of only bounds is that they work more like a regular bound. Whereas a ? bound is saying "I don't need this", an only bound is saying what you do need. So e.g. if you are writing a function that just has references to values of type T does not care what their size is, you can write
fn by_ref<U>(u: &U)
where
U: only MaybeSized,
{}
If you are writing a function that does need to compute the size of values of type V, you can ask for that capability:
fn checks_size<V>(v: &V)
where
V: only MetadataSized,
{
std::mem::size_of_val(v)
}
only bounds allow for new levels to be added later
A nice feature of only bounds is that, later on, we can add new levels to the hierarchy, and they work normally. For example, suppose we wish to add something like Aligned where the size is not known at compilation time but the alignment is. We could change the hierarchy to
trait Sized: Aligned
trait Aligned: MetadataSized // <-- new!
trait MetadataSized: MaybeSized
trait MaybeSized
and functions with U: only MaybeSized (like by_ref) and with V: only MetadataSized (with checks_size) would continue to have the same requirements. But new functions could be written with T: only Aligned that would use the new bound. And there is no conflict with stabilization; code that writes T: only Aligned can be considered unstable until that middle hierarchy is finalized.
only bounds compose normally
Like any other bound, only bounds are combined with other bounds to form the overall requirements. So it is possible to write e.g. T: only MetadataSized + Sized. This is equivalent to T: Sized and therefore equivalent to the default and therefore kind of pointless, but you can write it. Similarly, given that trait Clone: Sized, if you write T: only MetadataSized + Clone, that is kind of pointless too: you might as well write T: Clone, which would be equivalent. We plan to have a warn-by-default lint for that.
Scaling only to other "default bound families" (speculative)
The final strength of only bounds is that they allow us to introduce whole new families of default bounds. One example is the idea of introducing a Move bound. Note that this is a distinct feature and is not covered under the current RFC.
All types in Rust today are "movable" and "forgettable", meaning that you can memcpy the value from place to place so long as you stop using the previous location and you can recycle the memory where it is stored without running the value's destructor. There is one notable exception - when you pin a value, you it can no longer be moved, and you must run its destructor before its memory is reused - but otherwise this is a hard-and-fast rule. And that's annoying!
The problem is that not being able to guarantee that a destructor runs blocks a lot of unsafe code patterns. For example, scoped tasks a la rayon depend on a destructor for safety. In sync code, this works because we've decided it's UB to unwind a stack frame without running the destructors of values stored there, and so if you put a local variable on the stack, you can be sure its destructor will run. But that doesn't work in async code! And there are times when unwinding without running destructors would be nice.
The solution is to introduce a second family of default traits. Unlike the Sized family we saw before, this family defines fine-grained capabilities about how values of that type can be used:
flowchart TD
subgraph A["Accessability traits"]
Forget[["Forget (default)"]] -- extends --> Leak
Leak -- extends --> Destruct
Destruct -- extends --> Access
Move[["Move (default)"]] -- extends --> Access
end
Copy -- extends --> Move
The meaning of the traits are as follows:
Forget, the default, says that you can recycle the memory for a value without running its destructor.Leaksays that you can skip running a destructor for a value, but only if you never reuse the memory where the value resides.Destructsays that if you have a value of this type, you can reuse the memory where it resides by running its destructor.Copy, which already exists, says that you can memcpy the place and keep using the original place; it's not really a default, but I included it because it is relevant.Move, another default, says that you can memcpy the value to a new place if you stop using the original.Accessis the root of this family. It indicates a value that can be "accessed in place" (basically, any value at all).
This introduces new checks into the compiler:
- When you move a value (i.e.,
a = bwherebis not used later), we will check that the type implementsMove(whereas today, it is always allowed). - When you exit a scope, we will check that the values in each local variables have either been moved or have a type that implements
Destruct.
Some implications:
- If your function owns a value of type
T: only Destruct, then you must destruct it before your function returns. You can't move it (because you don't know if it implementsMove) and you can't leak or forget it either. - If your function owns a value of type
T: only Move, then the only thing you can do with it is move it somewhere else. You can't drop it (because you don't know if it implementsDestruct). - No function can own a value of type
T: only Access, because you wouldn't be able to move it nor drop it, and hence you could not return. But you could have such a value (say) in astatic.
How only bounds could work in the presence of multiple families
The spur for writing this blog post was a question in a lang team meeting on how only bounds ought to work given the existence of multiple "families" of default traits, as I described above. Although the current RFC is looking only at the Sized traits, we expect to look at the "access family" in a future RFC, so we want to be sure we are not making any decisions that won't scale to cover both.
The way I imagine it working is like this. Each default traits is associated with one or more "families". When you have an only bound, it "opts out" from all default traits in each family that the trait is associated with:
T: only Moveopts out fromForget,Leak,Destruct- but notSized.T: only Destructopts out fromForget,Leak, andMove- but notSized.T: only MetadataSizedopts out fromSized- but notForgetorMove.T: only MaybeSizedopts out fromSized- but notForgetorMove.
You may also want to "opt back in" to some defaults. For example, T: only Move + Destruct is a sensible thing to do. It means values that can be moved and destructed but not leaked or forgotten.
Examples
Option::map requires only Move
map is an example of a function that only needs Move. You need to be able to destructure self (which moves the optional value out into a local variable v and then invoke the closure op, which again moves the wrapped value v:
impl<T: only Move> Option<T> {
fn map<U: only Move>(
self,
op: impl FnOnce(T) -> U,
) -> Option<U> {
match self {
Some(v) => Some(op(v)),
None => None,
}
}
}
One interesting thing is the result type U. Using only the stuff I wrote in this blog post, it needs to be only Move, because the result will be moved into the Some value and so forth. But in-place-init would allow for this definition to omit the U: only Move bound because we could statically guarantee that the Option will be constructed in place and never moved after that.
Option::or requires only Move + Destruct
The a.or(b) method on Option returns a if it is Some and otherwise returns b. This is an interesting one because the value b may not be used and therefore requires only Move + Destruct bounds.
impl<T: only Move> Option<T> {
fn or(
self,
alternate: Option<T>,
) -> Option<T>
where
T: Destruct, // <-- because it may be dropped
{
match self {
Some(v) => Some(v), // drops `alternate`
None => alternate, // moves `alternate`
}
}
}
Rc requires MaybeSized + Leak
The Rc type is an example where we would want to relax bounds from both families:
struct Rc<T: only MaybeSized + only Leak> {}
I believe the proper minimum bounds for Rc are:
only MaybeSizedbecause while it can storeMetadataSizedorSizedthings, it doesn't have to, it can also store things of an non-computable size (although it does raise the question of how they would be freed, but that's an allocator concern).only LeakbecauseRcvalues can form cycles and thus we can't ever guarantee the destructor will be run. Interestingly,Rc<T>can implementForgeteven its contents don't.
Frequently asked questions
What is actually under RFC today?
The post may be a bit confusing here. The current RFC is looking only at the proposed "Sized" traits. The Access family is a speculative future extension that we are exploring but at a much earlier stage.
Can I use only with any trait?
In the beginning, the plan would be that only can only be used for well-known, default traits (e.g., Move, Sized, etc). In the future though there are some thoughts to generalizing it.
Why not opt out from all defaults at once?
An alternative that was proposed is to have the opt-out be per-type-parameter. So you might write something like
fn foo<T: MetadataSized + ?default>
which would "opt out" from all defaulted bounds. Obviously we'd have to bikeshed the syntax, but ignore that for now. The question is whether opting out of all defaults is better than opting out of a single family. I prefer the per-family option for two reasons:
- First, things like
T: only Movedemonstrate that you might very reasonably which to opt out from a single family but retain the defaultSizedbound. I think it's likely that there will be many functions that want to opt out ofSizedorForgetbut not both.- You might think that we could make
Move: Sizedto get the same effect, but I think that would be a mistake. The fact that a value's size must be computed dynamically doesn't inherently mean it can't be moved.
- You might think that we could make
- Second, it makes it harder to introduce new families later, if we decide there are other orthogonal properties of values that we'd like to relax.
Why do you think it's likely that people want to opt out of being Sized xor Forget but not both?
Because the Forget, Move, and similar traits mostly apply to owned values. The examples we saw with Option<T> were quite typical. And when you are moving values of type T around, you need that T to be Sized.
But we saw that Rc wanted to opt out of both families with only Leak + only MetadataSized, right?
Yes, that's true, and I think that particular combo will be common. I don't think that's an argument for the ?default approach on its own, though, particularly since that case would not be much cleaner or shorter…
impl<T: ?default + Leak + MetadataSized> Rc<T> {}
…what I think that argues for is actually trait aliases and shorthands.
Wait, trait aliases and shorthands? Can you elaborate?
Yes! I think that a future RFC could extend only bounds to allow you to define trait aliases with "only bounds" as supertraits:
trait RefCountable = only Leak + only MetadataSized;
// Equivalent to:
// trait RefCountable: only Leak + only MetadataSized {}
// impl<T> RefCountable for T where T: only Leak + only MetadataSized {}
You could then use an only RefCountable bound to define Rc<T>:
impl<T: only Refcountable> Rc<T>
Without the only, T: Refcountable would just be a regular trait bound and would not opt-out from any defaults.
Can we use a "root" trait to opt out of all defaults?
Yes, we could! You could define an alias like Value:
trait Value = only Access + only MaybeSized;
Since Access and MaybeSized are both implemented for all types, this effectively becomes part of both families:
flowchart TD
subgraph All["All default families"]
subgraph A["Access family"]
Forget[["Forget (default)"]] -- extends --> Leak
Leak -- extends --> Destruct
Destruct -- extends --> Access
Move[["Move (default)"]] -- extends --> Access
end
subgraph S["MaybeSized family"]
Sized[["Sized (default)"]] -- extends --> MetadataSized
MetadataSized -- extends --> MaybeSized
end
Access -- extends --> Value
MaybeSized -- extends --> Value
end
Then you can do T: only Value and opt out from both families at once.
If we did that, what would happen if we wanted to add a new family in the future?
Ay, there's the rub. If we wish to add a new family in the future, let's say for values that don't live in the same memory space (T: only Distributed…?), then Value would be "out of date" because code written against Value would still be assuming uni-memory-space values. But we could make Value into an edition-dependent alias or something like that, as has been discussed.
Can we decide whether we want Value later?
Yes! We can introduce a root trait at any time. So we can add the Sized-ness family first, then the Access family, and then see how we feel. Maybe we find people are very commonly opting out of both- in which case, some aliases are useful, or perhaps a Value variant.
The only way we might "regret" it is if, in practice, people usually just opted out of both and then opted back in to what they want specifically. But we already know that T: only Move will be common and clearly T: only Value + Move + Sized is more awkward in that case, so I don't consider that very likely.
Why the name Destruct and not Drop?
That name comes from the const trait RFC. There are a few reasons to move away from Drop. The first is that it is possible to have a destructor even if you don't implement Drop: Drop really refers to user-provided logic in the destructor, but the compiler adds its own logic ("drop glue", it's sometimes called) to drop all the fields in the value. The second reason is that the Drop trait itself needs some revision, so moving away from that name lets us have other ways to specify custom logic (e.g., pinned self, or by-value, etc etc).
How does this interact with const traits anyway?
Quite beautifully! In fact, the proposal from Arm for SVE is to introduce the idea of T: const Sized being "a type whose size can be computed at compilation time", which I find quite elegant. Similarly T: const Destruct was proposed by the const RFC as a way to say that a value has a constant destructor.
It's annoying to write T: only Move + Destruct. Couldn't we have Destruct imply Move so that I can just write T: only Destruct?
My original proposal for introducing linear types had Destruct extending Move. This would mean that the Option::or proposal could simply do U: only Destruct and not U: only Move + Destruct. However, Alice Ryhl and others pointed out that there are immovable types that must nonetheless be destructed, so it doesn't make sense to combine those.
Where can I learn more?
The Project Goal has a lot of details. The latest updates are available on the tracking issue. If you like watching videos, I recommend David Wood's Rust Nation talk.
Conclusion
I want to close with a meta-observation and a big shout-out to the Arm team. I think they are showing how awesome open-source can be. The Arm team's primary motivation is adding support for Scalable Vector Extension. This helps Rust make full use of Arm processors. This is, in and of itself, a laudable goal, and valuable to Rust: One of Rust's assets, in my view, is that it gives you access to all the power your processor has to provide, and that should include unique extensions.
But rather than add the feature as a kind of special-case extension to Rust, the Arm team is going further and driving a general purpose improvement, one that will unlock a bunch of other features (extern types and, to some extent, guaranteed destructors; guaranteed destructores themselves unlock scoped async threads and better Wasm integration). I love that.
-
In fact, I recall that in one of my blog posts I proposed writing
""as the way to spell&str. I kinda wish we had done that just for the sheer wackiness of it (fn foo(name: "")). ↩︎ -
I prefer names that refer to the operations that can be performed on the values, so e.g. instead of
MetadataSizedI would preferSizeOfVal, since it means that you can invoke thestd::mem::size_of_valfunction on it. ↩︎ -
Little logic pun there for you. ↩︎
09 Jun 2026 9:04am GMT
08 Jun 2026
Planet Mozilla
Firefox Tooling Announcements: MozPhab 2.15.2 Released
Bugs resolved in Moz-Phab 2.15.2:
- bug 2004368 moz-phab patch -a here with jj says there is no source tree if jj config is broken
- bug 2035900 Investigate setting up CodSpeed.io for
moz-phab - bug 2044857
patch --rawleaks a global logger level, causing order-dependent test failures
Discuss these changes in #engineering-workflow on Slack or #Conduit Matrix.
1 post - 1 participant
08 Jun 2026 6:41pm GMT
The Mozilla Blog: Make Firefox your World Cup sidekick this summer

Your browser tabs say a lot about your life: work projects, vacation plans, shopping carts and all the rabbit holes in between.
Add the world's biggest soccer tournament to the mix, and your browser is suddenly juggling scores to check, streams to watch, lineups to scan and group chats to keep up with. And since many matches kick off during the workday, there will be lots of temptation to just sneak a peek at the action between meetings.
Firefox is built to be your ultimate second screen. When the tournament is on, keep Firefox open to follow the action, keep up with the conversation, and stay on top of everything else happening online - whether you're watching from the couch or checking in on your mobile device on the go.
You'll find a World Cup widget, custom wallpapers, and game-day multitasking tools. Plus, Firefox is teaming up with Trevor Noah, a soccer superfan, as he hosts live watch parties for the tournament moments everyone will be talking about.
Your second screen for every match

When the action is happening fast, keeping up should be as easy as opening a new tab.
Firefox's World Cup widget gives you the latest tournament updates every time you open a new tab (and you can turn it off anytime). With key match information always within easy reach, it's easy to stay on top of the action without bouncing between apps or having to browse around.
You can follow your favorite teams and even customize Firefox with wallpapers that bring big fan vibes to every new tab. To get started, open a new tab and click the Customize icon at the bottom of the page.
Game-day pro moves
Pin the picture

With picture-in-picture in Firefox, you can detach a video from its tab and pin it anywhere on your screen so you can keep watching while working on other stuff.
Split the view

Open two tabs side by side in one window with split view. That way, you can keep live updates on one half and stats, searches or chats on the other.
Calm the chaos

Remember what we said about your tabs representing your life? While 99 tabs of fandom can make it feel more chaotic, your browser doesn't have to.
With tab groups in Firefox, you can create separate groups for:
- soccer matches and live scores
- travel plans and itineraries
- work or school projects
- summer shopping and event planning
- weekend inspiration and future adventures
Hang out with Trevor Noah - World Cup and Firefox superfan
Match days are better with good company. This summer, Firefox is teaming up with Trevor Noah to be his second screen sidekick for his World Cup watch party on YouTube.
Hosted live throughout the tournament, the series will feature Trevor alongside some of his best friends plus celebrity guests as they react to matches, highlights and the internet moments coming out of each day's games.
Trevor is a longtime Firefox user whose comedy and commentary have explored how technology shapes everyday life. That makes this collaboration feel especially fitting for Mozilla, a company built around the idea that the internet should work better for everyone.
"I'm grateful to our incredible brand partner Firefox for helping make this series possible and for believing in the power of sport to bring people together," said Noah.
"Events like this are some of the biggest shared experiences on the internet," said John Solomon, Chief Marketing Officer at Mozilla. "While many people stop their lives for the World Cup, those that can't follow them while working, traveling, connecting with friends and family, and doing everything else they need to do online. Firefox is built for moments like this, and Trevor is a fitting partner. He's a longtime Firefox user who believes, like we do, that technology should work for people, helping them stay connected to the moments, information and communities they care about most."
Make Firefox your World Cup sidekick this summer. Follow the tournament with the World Cup widget, multitask like a pro with picture-in-picture, split view and tab groups, and get into the spirit with custom wallpapers, all in the browser that helps you get more out of every match.

Are you game-day ready?
Download Firefox nowThe post Make Firefox your World Cup sidekick this summer appeared first on The Mozilla Blog.
08 Jun 2026 3:59pm GMT
05 Jun 2026
Planet Mozilla
Will Kahn-Greene: Bleach 6.4.0 releases -- final release
What is it?
Bleach is a Python library for sanitizing and linkifying text from untrusted sources for safe usage in HTML.
Bleach v6.4.0 released!
Bleach 6.4.0 includes two security fixes, a fix to tinycss2 dependency requirements, and some other things.
See the changes here:
https://bleach.readthedocs.io/en/latest/changes.html#version-6-4-0-june-5th-2026
Bleach v6.4.0 is the final release
I haven't used Bleach on a project in years, but I still had some time to maintain it. That changed about a year ago when I got re-orged into a new role and I haven't had time to do any Bleach work since then.
To recap, Bleach sits on top of html5lib which hasn't been actively maintained in years. It is dangerous to maintain Bleach in that context.
We vendored html5lib so we could make adjustments to the library to keep Bleach going. This is not a sustainable approach, but it was ok for the short term.
Over the years, we've talked about other options:
-
find another library to switch to
-
take over html5lib development
-
fork html5lib and vendor and maintain our fork
-
write a new HTML parser
-
etc
None of those are feasible for me.
Bleach has been a solo-maintained project for a while now. The world is crazy and it's much harder to build a team of trusted maintainers now than it was (or at least, it sure feels that way). I don't see any possibility of increasing the maintenance team or passing it to someone else responsibly.
Switching contexts from my regular work to Bleach is really hard. Bleach is complicated, the problem domain is complicated, and there's a lot of nuanced context. I can't just switch gears, spend 15 minutes on Bleach to do something, and then switch back to the rest of my day. I periodically get nag messages about this which are entirely valid, but there's nothing I can do about it. It doesn't feel great.
Then in 2025, Emil, a long-time Bleach contributor, built justhtml which gives us an easy migration path off of Bleach. He even took the time to write a migration guide.
Thoughts and statistics
In 2019, when I stepped down the first time, I wrote a post on stepping down.
In 2023, when I deprecated the project, I wrote a post on Bleach 6.0.0 and deprecation.
-
From the first commit on 2010-02-18 to today's final commit on 2026-06-05, the Bleach project lasted 16 years, 3 months - 5,951 days, or about 16.29 years.
-
There were 64 releases.
-
There were roughly 960 commits.
-
From 80 roughly contributors
-
Top 3:
-
Will Kahn-Greene: 462
-
James Socol: 182
-
Greg Guthe: 133
-
-
-
Roughly 5,040 lines of Python code excluding the vendored html5lib.
-
I was maintainer from October 2015 to now--that's a little under 11 years.
It feels weird to end a project that's outlived many of the Mozilla sites and Python web frameworks it was designed to protect.
What happens now?
This is the end of the project.
Bleach. Last release.
If you're still using Bleach, I think you have three options:
-
End your project. Maybe you don't need to be maintaining your thing anymore? Use Bleach as your reason to exit and do something different with your time on Earth.
-
Switch to the sanitizer API. Rework your project to use the sanitizer API.
-
Swap Bleach out for justhtml. Emil provided a migration guide for switching from Bleach to justhtml.
Good luck with whatever option you choose!
Thanks!
Many thanks to James who created Bleach and gave it a set of first principles that guided our choices for 16 years.
Many thanks to Greg who I worked with on Bleach for a long while and maintained Bleach for several years. Working with Greg was always easy and his reviews were thoughtful and spot-on.
Many thanks to Emil who was a contributor to Bleach for a long while and created justhtml providing Bleach users a migration path.
Many thanks to Jonathan who, over the years, provided a lot of insight into how best to solve some of Bleach's more squirrely problems.
Many thanks to Sam who was an indispensible resource on HTML parsing and sanitizing text in the context of HTML.
Many thanks to all the users and contributors of Bleach!
Where to go for more
For more specifics on this release, see here: https://bleach.readthedocs.io/en/latest/changes.html#version-6-4-0-june-5th-2026
Documentation and quickstart here: https://bleach.readthedocs.io/en/latest/
Source code and issue tracker here: https://github.com/mozilla/bleach/
05 Jun 2026 1:00pm GMT
