This is a valid RSS feed.
This feed is valid, but interoperability with the widest range of feed readers could be improved by implementing the following recommendations.
line 2889, column 0: (5 occurrences) [help]
<svg id="layerarrows" style="width: 100%; height: 100%;& ...
line 6312, column 0: (2 occurrences) [help]
<pre style="background: #2d2d2d; color: #ccc; padding: 10px; border- ...
<?xml version="1.0"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"> <channel> <title>Planet Mozilla</title> <link>https://planet.mozilla.org/</link> <language>en</language> <description>Planet Mozilla - https://planet.mozilla.org/</description> <atom:link rel="self" href="https://planet.mozilla.org/rss20.xml" type="application/rss+xml"/> <item> <title>The Mozilla Blog: Introducing early access for Firefox Support for Organizations</title> <guid isPermaLink="false">https://blog.mozilla.org/?p=82895</guid> <link>https://blog.mozilla.org/en/firefox/firefox-support-for-organizations/</link> <description><figure class="wp-block-image size-large"><img alt="Multiple Firefox logos forming a curved trail on a dark background." class="wp-image-82898" height="683" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/11/Press_Firefox_Brand_1200x800_1-1024x683.png" width="1024" /></figure> <p>Increasingly, businesses, schools, and government institutions deploy Firefox at scale for security, resilience, and data sovereignty. Organizations have fine-grained administrative and orchestration control of the browser’s behavior using policies with Firefox and the Extended Support Release (ESR). Today, we’re opening early access to Firefox Support for Organizations, a new program that begins operation in January 2026.</p> <h3>What Firefox Support for Organizations offers</h3> <p>Support for Organizations is a dedicated offering for teams who need private issue triage and escalation, defined response times, custom development options, and close collaboration with Mozilla’s engineering and product teams.</p> <ul><li><strong>Private support channel</strong>: Access a dedicated support system where you can open private help tickets directly with expert support engineers. Issues are triaged by severity level, with defined response times and clear escalation paths to ensure timely resolution.<br /></li> <li><strong>Discounts on custom development:</strong> Paid support customers get discounts on custom development work for integration projects, compatibility testing, or environment-specific needs. With custom development as a paid add-on to support plans, Firefox can adapt with your infrastructure and third-party updates.<br /></li> <li><strong>Strategic collaboration</strong>: Gain early insight into upcoming development and help shape the Firefox Enterprise roadmap through direct collaboration with Mozilla’s team.</li></ul> <p>Support for Organizations adds a new layer of help for teams and businesses that need confidential, reliable, and customized levels of support. All Firefox users will continue to have full access to existing public resources including documentation, the knowledge base, and community forums, and we’ll keep improving those for everyone in future. Support plans will help us better serve users who rely on Firefox for business-critical and sensitive operations.</p> <h3>Get in touch for early access</h3> <p>If these levels of support are interesting for your organization, get in touch using <a href="https://qsurvey.mozilla.com/s3/firefox-support-plan?src=mozilla-blog">our inquiry form</a> and we’ll get back to you with more information.</p> <a class="ft-c-inline-cta" href="https://qsurvey.mozilla.com/s3/firefox-support-plan?src=mozilla-blog"> <div class="ft-c-inline-cta__media"> <img alt="Multiple Firefox logos forming a curved trail on a dark background." class="attachment-1x1 size-1x1" height="800" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/11/Press_Firefox_Brand_1200x800_1-800x800.png" width="800" /> </div> <div class="ft-c-inline-cta__content"> <h4>Firefox Support for Organizations</h4> <span>Get early access</span> </div></a><p>The post <a href="https://blog.mozilla.org/en/firefox/firefox-support-for-organizations/">Introducing early access for Firefox Support for Organizations</a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p></description> <pubDate>Fri, 07 Nov 2025 12:00:00 +0000</pubDate> <dc:creator>Brian Smith</dc:creator></item><item> <title>The Mozilla Blog: Under the hood: How Firefox suggests tab groups with local AI</title> <guid isPermaLink="false">https://blog.mozilla.org/?p=82352</guid> <link>https://blog.mozilla.org/en/mozilla/ai/ai-tech/ai-tab-groups/</link> <description><figure class="wp-block-image size-large"><img alt="Browser popup showing the “Create tab group” menu with color options and AI tab suggestions button." class="wp-image-82462" height="576" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/11/Distilled-Header_AI-Tabs-1024x576.png" width="1024" /></figure> <h3><strong>Background</strong></h3> <p>Mozilla launched <a href="https://blog.mozilla.org/en/firefox/firefox-tab-groups/">Tab Grouping</a> in early 2025, allowing tabs to be arranged and grouped with persistent labels. It was the <a href="https://blog.mozilla.org/en/firefox/tab-groups-community/">most requested feature</a> in the history of <a href="https://connect.mozilla.org/" rel="noreferrer noopener" target="_blank">Mozilla Connect</a>. While tab grouping provides a great way to manage tabs and reduce tab overload, it can be a challenge to locate which tabs to group when you have many open.</p> <p>We sought to improve the workflows by providing an <a href="https://support.mozilla.org/en-US/kb/how-use-ai-enhanced-tab-groups" rel="noreferrer noopener" target="_blank">AI tab grouping feature</a> that enables two key capabilities:</p> <ul><li>Suggesting a title for a tab group when it is created by the user.</li> <li>Suggesting tabs from the current window to be added to a tab group.</li></ul> <p>Of course, we wanted this to work without you needing to send any data of yours to Mozilla, so we used our local <a href="https://blog.mozilla.org/en/firefox/firefox-ai/speeding-up-firefox-local-ai-runtime/">Firefox AI runtime</a> and built an efficient model that delivers the features entirely on your own device. The feature is opt-in and downloads two small ML models when the user clicks to run it the first time.</p> <h3><strong>Group title suggestion</strong></h3> <h4><strong>Understanding the problem</strong></h4> <p>Suggesting titles for grouped tabs is a challenge because it is hard to understand user intent when tabs are first grouped. Based on our interviews when we started the project, we found that while tab groups are sometimes generic terms like ‘Shopping’ or ‘Travel’, over half the time users’ tabs were specific terms such as name of a video game, friend or town. We also found tab names to be extremely short – 1 or 2 words.</p> <div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img alt="Diagram showing Firefox tab information processed by a generative AI model to label topics like Boston Travel" class="wp-image-82355" height="220" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/1-1024x220.png" style="width: 650px;" width="1024" /></figure></div> <h4><strong>Generating a digest of the group</strong></h4> <p>To address these challenges, we adopt a hybrid methodology that combines a modified TF-IDF–based textual analysis with keyword extraction. We identify terms that are statistically distinctive to the titles of pages within a tab group compared to those outside it. The three most prominent keywords, along with the full titles of three randomly selected pages, are then combined to produce a concise digest representing the group, which is used as input for the subsequent stage of processing using a language model.</p> <h4><strong>Generating the label</strong></h4> <p>The digest string is used as an input to a generative model that returns the final label. We used a T5 based encoder-decoder model (flan-t5-base) that was fine tuned on over 10,000 example situations and labels. </p> <p>One of the key challenges in developing the model was generating the training data samples to tune the model without any user data. To do this, we defined a set of user archetypes and used an LLM API (OpenAI GPT-4) to create sample pages for a user performing various tasks. This was augmented by real page titles from the publicly available <a href="https://commoncrawl.org/">common crawl dataset</a>. We then used the LLM to suggest short titles for those use cases. The process was first done at a small scale of several hundred group names. These were manually corrected and curated, adjusting for brevity and consistency. As the process scaled up, the initial 300 group names were used as examples passed to the LLM so that the additional examples created would meet those standards. </p> <h4><strong>Shrinking things down</strong></h4> <p>We need to get the model small enough to run on most computers. Once the initial model was trained, it was sampled to a smaller model using a process known as knowledge distillation. For distillation, we tuned a t5-efficient-tiny model from the token probability outputs of our teacher flan-t5-base model. Midway through the distillation process we also removed two encoder transformer layers and two decoder layers to further reduce the number of parameters.</p> <p>Finally, the model parameters were quantized from floating point (4 bytes per parameter) to integer 8 bit. In the end this entire reduction process reduced the model from 1GB to 57 MB, with only a modest reduction in accuracy. </p> <h3><strong>Suggesting tabs </strong></h3> <h4><strong>Understanding the problem</strong></h4> <p>For tab suggestions, we identified a couple of approaches on how people prefer grouping their tabs. Some people prefer grouping by domain to easily access all documents for work for instance. Others might prefer grouping all their tabs together when they are planning a trip. Others still might prefer separating their “work” and “personal” tabs.</p> <p>Our initial approach on suggesting tabs was based on semantic similarity. Tabs that are topically similar are suggested.</p> <div class="wp-block-image"><figure class="aligncenter size-medium"><img alt="Browser pop-up suggesting related tabs for a Boston trip using AI-based grouping" class="wp-image-82365" height="300" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/2-248x300.png" width="248" /></figure></div> <h4><strong>Identifying topically similar tabs</strong></h4> <p>We first convert tab titles to a feature vector locally using a <em>MiniLM</em> embedding model. Embedding models are trained so that similar content produces vectors that are close together in embedding space. Using a similarity measure such as cosine similarity, we’re able to assign how closely similar a tab title or url is to another.</p> <p>The similarity score between an anchor tab chosen by the user and another tab is a linear combination of the candidate tab with the group title (if present) of the anchor tab, the anchor tab title and the anchor url. Using these values, we generate a similarity probability and tabs that have a high probability threshold are suggested to be part of the group.</p> <div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img alt="Mathematical formula showing conditional probability using weighted similarity and sigmoid function" class="wp-image-82395" height="81" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/5-1024x81.png" style="width: 650px;" width="1024" /></figure></div> <p>where,<br />w is the weight,<br />t_i is the candidate tab,<br />t_a is the anchor tab,<br />g_a is the anchor group title,<br />u_i is the candidate url<br />u_a is the anchor url, and,<br />σ is the sigmoid function</p> <h4><strong>Optimizing the weights</strong></h4> <p>In order to find the weights, we framed the problem as a classification task, where we calculate the precision and recall based on the tabs that were correctly classified given an anchor tab. We used synthetic data generated by OpenAI based on the user archetypes above.</p> <p>We initially used a clustering approach to establish a baseline and switched to a logistic regression when we realized that treating the group, title and url features with varying importances improved our metrics.</p> <div class="wp-block-image"><figure class="aligncenter size-full is-resized"><img alt="Bar chart comparing DBScan and Logistic Regression by precision, recall, and F1 performance metrics" class="wp-image-82375" height="337" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/3.png" style="width: 512px; height: auto;" width="512" /></figure></div> <p>Using logistic regression, there was an 18% improvement against the baseline.</p> <h4><strong>Performance</strong></h4> <p>While the median number of tabs for people using the feature is relatively small (~25), there are some “power” users whose tab count reaches the thousands. This would cause the tab grouping feature to take uncomfortably long. </p> <p>This was part of the reason why we switched from a clustering based approach to a linear model. </p> <p>Using our performance framework, we found that the p99 of running logistic regression compared to a clustering based method such as KMeans improved by 33%.</p> <div class="wp-block-image"><figure class="aligncenter size-full"><img alt="Bar chart comparing KMeans and Logistic Regression using percentile metrics p50, p95, and p99" class="wp-image-82385" height="337" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/4.png" width="512" /></figure></div> <p>Future work here would involve improving F1 score. These could be by adding a time-related component as part of the inference (we are more likely to group tabs together that we’ve opened at the same time) or using a fine-tuned embedding model for our use case.</p> <h3><strong>Thanks for reading</strong></h3> <p>All of our work is open source. If you are a developer feel free to <a href="https://github.com/mozilla/smart-tab-grouping" rel="noreferrer noopener" target="_blank">peruse our source code</a> on our model training, or view our <a href="https://huggingface.co/Mozilla/smart-tab-topic" rel="noreferrer noopener" target="_blank">topic model on Huggingface</a>.</p> <p>Feel free to <a href="https://support.mozilla.org/en-US/kb/how-use-ai-enhanced-tab-groups" rel="noreferrer noopener" target="_blank">try the feature</a> and let us know what you think!</p> <a class="ft-c-inline-cta" href="https://www.mozilla.org/firefox/new/?utm_source=blog.mozilla.org&amp;utm_medium=referral&amp;utm_campaign=blog-nav"> <div class="ft-c-inline-cta__media"> <img alt="" class="attachment-1x1 size-1x1" height="800" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2021/10/Visual-Guidelines-800x800.png" width="800" /> </div> <div class="ft-c-inline-cta__content"> <h4>Take control of your internet</h4> <span>Download Firefox</span> </div></a><p>The post <a href="https://blog.mozilla.org/en/mozilla/ai/ai-tech/ai-tab-groups/">Under the hood: How Firefox suggests tab groups with local AI</a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p></description> <pubDate>Wed, 05 Nov 2025 15:41:58 +0000</pubDate> <dc:creator>Rolf Rando and Vasish Baungally</dc:creator></item><item> <title>Wladimir Palant: An overview of the PPPP protocol for IoT cameras</title> <guid isPermaLink="true">https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/</guid> <link>https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/</link> <description><p>My <a href="https://palant.info/2025/09/08/a-look-at-a-p2p-camera-lookcam-app/">previous article on IoT “P2P” cameras</a> couldn’t go into much detail on the PPPP protocol. However, there is already lots of security research on and around that protocol, and I have a feeling that there is way more to come. There are pieces of information on the protocol scattered throughout the web, yet every one approaching from a very specific narrow angle. This is my attempt at creating an overview so that other people don’t need to start from scratch.</p><p>While the protocol can in principle be used by any kind of device, so far I’ve only seen network-connected cameras. It isn’t really peer-to-peer as advertised but rather relies on central servers, yet the protocol allows to transfer the bulk of data via a direct connection between the client and the device. It’s hard to tell how many users there are but there are <em>lots</em> of apps, I’m sure that I haven’t found all of them.</p><p>There are other protocols with similar approaches being used for the same goal. One is used by ThroughTek’s Kalay Platform which <a href="https://www.thirtythreeforty.net/posts/2020/05/hacking-reolink-cameras-for-fun-and-profit/#the-charlie-scrambler">has the interesting string “Charlie is the designer of P2P!!” in its codebase</a> (32 bytes long, seems to be used as “encryption” key for some non-critical functionality). I recognize both the name and the “handwriting,” it looks like PPPP protocol designer found a new home here. Yet PPPP seems to be still more popular than the competition, thanks to it being the protocol of choice for cheap low-end cameras.</p><p><em>Disclaimer</em>: Most of the information below has been acquired by analyzing public information as well as reverse engineering applications and firmware, not by observing live systems. Consequently, there can be misinterpretations.</p><p><strong>Update</strong> (2025-11-07): Added App2Cam Plus app to the table, representing a number of apps which all seem to be belong to ABUS Smartvest Wireless Alarm System.</p><p><strong>Update</strong> (2025-11-07): This article originally grouped Xiaomi Home together with Yi apps. This was wrong, Xiaomi uses a completely different protocol to communicate with their PPPP devices. A brief description of this protocol has been added.</p><div id="tocBox"> <h5>Contents</h5> <nav id="TableOfContents"> <ul> <li><a href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#the-general-design">The general design</a></li> <li><a href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#the-network-ports">The network ports</a></li> <li><a href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#the-device-ids">The device IDs</a></li> <li><a href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#the-protocol-variants">The protocol variants</a> <ul> <li><a href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#cs2-network">CS2 Network</a></li> <li><a href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#yi-technology">Yi Technology</a></li> <li><a href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#ilnk">iLnk</a></li> <li><a href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#hlp2p">HLP2P</a></li> </ul> </li> <li><a href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#encryption">“Encryption”</a></li> <li><a href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#secret-messages">“Secret” messages</a></li> <li><a href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#applications">Applications</a></li> </ul></nav></div> <h3>The general design</h3><p>The protocol’s goal is to serve as a drop-in replacement for TCP. Rather than establish a connection to a known IP address (or a name to be resolved via DNS), clients connect to a device identifier. The abstraction is supposed to hide away how the device is located (via a server that keeps track of its IP address), how a direct communication channel is established (via <a href="https://en.wikipedia.org/wiki/UDP_hole_punching">UDP hole punching</a>) or when one of multiple possible fallback scenarios is being used because direct communication is not possible.</p><p>The protocol is meant to be resilient, so there are usually three redundant servers handling each network. When a device or client needs to contact a server, it sends the same message to all of them and doesn’t care which one will reply. <em>Note</em>: In this article “network” generally means a PPPP network, i.e. a set of servers and the devices connecting to them. While client applications typically support multiple networks, devices are always associated with a specific one determined by <a href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#the-device-ids">their device prefix</a>.</p><p>For what is meant to be a <a href="https://en.wikipedia.org/wiki/Transport_layer">transport layer protocol</a>, PPPP has some serious complexity issues. It encompasses device discovery on the LAN via UDP broadcasts, UDP communication between device/client and the server and a number of (not exactly trivial) fallback solutions. It also features multiple “encryption” algorithms which are more correctly described as obfuscators and network management functionality.</p><p>Paul Marrapese’s <a href="https://github.com/pmarrapese/iot/tree/master/p2p/dissector">Wireshark Dissector</a> provides an overview of the messages used by the protocol. While it isn’t quite complete, a look into the <code>pppp.fdesc</code> file shows roughly 70 different message types. It’s hard to tell how all these messages play together as the protocol has not been designed as a state machine. The protocol implementation uses its previous actions as context to interpret incoming messages, but it has little indication as to which messages are expected when. Observing a running system is essential to understanding this protocol.</p><p>The complicated message exchange required to establish a connection between a device and a client has been <a href="https://www.elastic.co/security-labs/storm-on-the-horizon#building-a-p2p-client">described by Elastic Security Labs</a>. They also provide the code of their client which implements that secret handshake.</p><p>I haven’t seen any descriptions of how the fallback approaches work when a direct connection cannot be established. Neither could I observe these fallbacks in action, presumably because the network I observed didn’t enable them. There are at least three such fallbacks: UDP traffic can be relayed by a network-provided server, it can be relayed by a “supernode” which is a device that agreed to be used as a relay, and it can be wrapped in a TCP connection to the server. The two centralized solutions incur significant costs for the network owners, rendering them unpopular. And I can imagine the “supernode” approach to be less than reliable with low-end devices like these cameras (it’s also a privacy hazard but this clearly isn’t a consideration).</p><p>I recommend going though the <a href="https://prezi.com/5cztk-98izyc/cs2-network-p2p/">CS2 sales presentation</a> to get an idea of how the protocol is <em>meant</em> to work. Needless to say that it doesn’t always work as intended.</p><h3>The network ports</h3><p>I could identify the following network ports being used:</p><ul><li>UDP 32108: broadcast to discover local devices</li><li>UDP 32100: device/client communication to the server</li><li>TCP 443: client communication to the server as fallback</li></ul><p>Note that while port 443 is normally associated with HTTPS, here it was apparently only chosen to fool firewalls. The traffic is merely obfuscated, not really encrypted.</p><p>The direct communication between the client and the device uses a random UDP port. In my understanding the ports are also randomized when this communication is relayed by a server or supernode.</p><h3>The device IDs</h3><p>The canonical representation of a device ID looks like this: <code>ABC-123456-VWXYZ</code>. Here <code>ABC</code> is a device prefix. While a PPPP network will often handle more than one device prefix, mapping a device prefix to a set of servers is supposed to be unambiguous. This rule isn’t enforced across different <a href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#the-protocol-variants">protocol variants</a> however, e.g. the device prefix <code>EEEE</code> is assigned differently by CS2 and iLnk.</p><p>The six digit number following the device prefix allows distinguishing different devices within a prefix. It seems that vendors can choose these numbers freely – some will assign them to devices sequentially, others go by some more complicated rules. <a href="https://palant.info/2025/09/08/a-look-at-a-p2p-camera-lookcam-app/#c000003">A comment on my previous article</a> even claims that they will sometimes reassign existing device IDs to new devices.</p><p>The final part is the verification code, meant to prevent enumeration of devices. It is generated by some secret algorithm and allows distinguishing valid device IDs from invalid ones. At least one such algorithm got leaked in the past.</p><p>Depending on the application a device ID will not always be displayed in its canonical form. It’s pretty typical for the dashes to be removed for example, in one case I saw the prefix being shortened to one letter. Finally, there are applications that will hide the device ID from the user altogether, displaying only some vendor-specific ID instead.</p><h3>The protocol variants</h3><p>So far I could identify at least four variants of this protocol – if you count HLP2P which is questionable. These protocol implementations differ significantly and aren’t really compatible. A number of apps can work with different protocol implementations but they generally do it by embedding multiple client libraries.</p><table> <thead> <tr> <th>Variant</th> <th>Typical client library names</th> <th>Typical functions</th> </tr> </thead> <tbody> <tr> <td>CS2 Network</td> <td>libPPCS_API.so libobject_jni.so librtapi.so</td> <td>PPPP_Initialize PPPP_ConnectByServer</td> </tr> <tr> <td>Yi Technology</td> <td>PPPP_API.so libmiio_PPPP_API.so</td> <td>PPPP_Initialize PPPP_ConnectByServer</td> </tr> <tr> <td>iLnk</td> <td>libvdp.so libHiChipP2P.so</td> <td>XQP2P_Initialize XQP2P_ConnectByServer HI_XQ_P2P_Init</td> </tr> <tr> <td>HLP2P</td> <td>libobject_jni.so libOKSMARTPPCS.so</td> <td>HLP2P_Initialize HLP2P_ConnectByServer</td> </tr> </tbody></table><h4>CS2 Network</h4><p>The Chinese company CS2 Network is the original developer of the protocol. Their implementation can sometimes be recognized without even looking at any code just by their device IDs. The letters A, I, O and Q are never present in the verification code, there are only 22 valid letters here. Same seems to apply to the Yi Technology fork however which is generally very similar.</p><p>The other giveaway is the “init string” which encodes network parameters. Typically these init strings are hardcoded in the application (sometimes hundreds of them) and chosen based on device prefix, though some applications retrieve them from their servers. These init strings are obfuscated, with the function <code>PPPP_DecodeString</code> doing the decoding. The approach is typical for CS2 Network: a lookup table filled with random values and some random algebraic operations to make things seem more complex. The init strings look like this:</p><pre tabindex="0"><code>DRFTEOBOJWHSFQHQEVGNDQEXFRLZGKLUGSDUAIBXBOIULLKRDNAJDNOZHNKMJO:SECRETKEY</code></pre><p>The part before the colon decodes into:</p><pre tabindex="0"><code>127.0.0.1,192.168.1.1,10.0.0.1,</code></pre><p>This is a typical list of three server IPs. No, the trailing comma isn’t a typo but required for correct parsing. Host names are occasionally used in init strings but this is uncommon. With CS2 Network generally distrusting DNS from the looks of it, they probably recommend vendors to sidestep it. The “secret” key behind the colon is optional and activates <a href="https://palant.info/2025/09/08/a-look-at-a-p2p-camera-lookcam-app/#the-encryption">encryption of transferred data</a> which is better described as obfuscation. Unlike the server addresses, this part isn’t obfuscated.</p><h4>Yi Technology</h4><p>The Xiaomi spinoff Yi Technology appears to have licensed the code of the CS2 Network implementation. They made some moderate changes to it but it is still very similar to the original. For example, they still use the same code to decode init strings, merely with a different lookup table. Consequently, same init string as above would look slightly differently here:</p><pre tabindex="0"><code>LZERHWKWHUEQKOFUOREPNWERHLDLDYFSGUFOJXIXJMASBXANOTHRAFMXNXBSAM:SECRETKEY</code></pre><p>As can be seen from Paul Marrapese’s <a href="https://github.com/pmarrapese/iot/tree/master/p2p/dissector">Wireshark Dissector</a>, the Yi Technology fork added a bunch of custom protocol messages and extended two messages presumably to provide forward compatibility. The latter is a rather unusual step for the PPPP ecosystem where the dominant approach seems to be “devices and clients connecting to the same network always use the same version of the client library which is frozen for all eternity.”</p><p>There is another notable difference: this PPPP implementation doesn’t contain any encryption functionality. There seems to be some AES encryption being performed at the application layer (which is the proper way to do it), I didn’t look too closely however.</p><h4>iLnk</h4><p>The protocol fork developed by Shenzhen Yunni Technology iLnkP2P seems to have been developed from scratch. The device IDs for legacy iLnk networks are easy to recognize because their verification codes only consist of the letters A to F. The algorithm generating these verification codes is public knowledge (CVE-2019-11219) so we know that these are letters taken from an MD5 hex digest. New iLnk networks appear to have verification codes that can contain all Latin letters, some new algorithm replaced the compromised one here. Maybe they use Base64 digests now?</p><p>An iLnk init string can be recognized by the presence of a dash:</p><pre tabindex="0"><code>ATBBARASAXAOAQAOAQAOARBBARAZASAOARAWAYAOARAOARBBARAQAOAQAOAQAOAR-$$</code></pre><p>The part before the dash decodes into:</p><pre tabindex="0"><code>3;127.0.0.1;192.168.1.1;10.0.0.1</code></pre><p>Yes, the first list entry has to specify how many server IPs there are. The decoding approach (function <code>HI_DecStr</code> or <code>XqStrDec</code> depending on the implementation) is much simpler here, it’s a kind of Base26 encoding. The part after the dash can encode additional parameters related to validation of device IDs but typically it will be <code>$$</code> indicating that it is omitted and network-specific device ID validation can be skipped. As far as I can tell, iLnk networks will always send all data as plain text, there is no encryption functionality of any kind.</p><p>Going through the code, the network-level changes in the iLnk fork are extensive, with only the most basic messages shared with the original PPPP protocol. Some message types are clashing like for example <code>MSG_DEV_MAX</code> that uses the same type as <code>MSG_DEV_LGN_CRC</code> in the CS2 implementation. This fork also introduces new magic numbers: while PPPP messages normally start with <code>0xF1</code>, some messages here start with <code>0xA1</code> and one for some reason with <code>0xF2</code>.</p><p>Unfortunately, I haven’t seen any comprehensive analysis of this protocol variant yet, so I’ll just list the message types along with their payload sizes. For messages with 20 bytes payloads it can be assumed that the payload is a device ID. Don’t ask me why two pairs of messages share the same message type.</p><table> <thead> <tr> <th>Message</th> <th>Message type</th> <th>Payload size</th> </tr> </thead> <tbody> <tr> <td>MSG_HELLO</td> <td>F1 00</td> <td>0</td> </tr> <tr> <td>MSG_RLY_PKT</td> <td>F1 03</td> <td>0</td> </tr> <tr> <td>MSG_DEV_LGN</td> <td>F1 10</td> <td>IPv4: 40<br />IPv6: 152</td> </tr> <tr> <td>MSG_DEV_MAX</td> <td>F1 12</td> <td>20</td> </tr> <tr> <td>MSG_P2P_REQ</td> <td>F1 20</td> <td>IPv4: 36<br />IPv6: 152</td> </tr> <tr> <td>MSG_LAN_SEARCH</td> <td>F1 30</td> <td>0</td> </tr> <tr> <td>MSG_LAN_SEARCH_EXT</td> <td>F1 32</td> <td>0</td> </tr> <tr> <td>MSG_LAN_SEARCH_EXT_ACK</td> <td>F1 33</td> <td>52</td> </tr> <tr> <td>MSG_DEV_UNREACH</td> <td>F1 35</td> <td>20</td> </tr> <tr> <td>MSG_PUNCH_PKT</td> <td>F1 41</td> <td>20</td> </tr> <tr> <td>MSG_P2P_RDY</td> <td>F1 42</td> <td>20</td> </tr> <tr> <td>MSG_RS_LGN</td> <td>F1 60</td> <td>28</td> </tr> <tr> <td>MSG_RS_LGN_EX</td> <td>F1 62</td> <td>44</td> </tr> <tr> <td>MSG_LST_REQ</td> <td>F1 67</td> <td>20</td> </tr> <tr> <td>MSG_RLY_HELLO</td> <td>F1 70</td> <td>0</td> </tr> <tr> <td>MSG_RLY_HELLO_ACK</td> <td>F1 71</td> <td>0</td> </tr> <tr> <td>MSG_RLY_PORT</td> <td>F1 72</td> <td>0</td> </tr> <tr> <td>MSG_RLY_PORT_ACK</td> <td>F1 73</td> <td>8</td> </tr> <tr> <td>MSG_RLY_PORT_EX_ACK</td> <td>F1 76</td> <td>264</td> </tr> <tr> <td>MSG_RLY_REQ_EX</td> <td>F1 77</td> <td>288</td> </tr> <tr> <td>MSG_RLY_REQ</td> <td>F1 80</td> <td>IPv4: 40<br />IPv6: 160</td> </tr> <tr> <td>MSG_HELLO_TO_ACK</td> <td>F1 83</td> <td>28</td> </tr> <tr> <td>MSG_RLY_RDY</td> <td>F1 84</td> <td>20</td> </tr> <tr> <td>MSG_SDEV_LGN</td> <td>F1 91</td> <td>20</td> </tr> <tr> <td>MSG_MGM_ADMIN</td> <td>F1 A0</td> <td>160</td> </tr> <tr> <td>MSG_MGM_DEVLIST_CTRL</td> <td>F1 A2</td> <td>20</td> </tr> <tr> <td>MSG_MGM_HELLO</td> <td>F1 A4</td> <td>4</td> </tr> <tr> <td>MSG_MGM_MULTI_DEV_CTRL</td> <td>F1 A6</td> <td><em>variable</em></td> </tr> <tr> <td>MSG_MGM_DEV_DETAIL</td> <td>F1 A8</td> <td>24</td> </tr> <tr> <td>MSG_MGM_DEV_VIEW</td> <td>F1 AA</td> <td>4</td> </tr> <tr> <td>MSG_MGM_RLY_LIST</td> <td>F1 AC</td> <td>12</td> </tr> <tr> <td>MSG_MGM_DEV_CTRL</td> <td>F1 AE</td> <td>24</td> </tr> <tr> <td>MSG_MGM_MEM_DB</td> <td>F1 B0</td> <td>264</td> </tr> <tr> <td>MSG_MGM_RLY_DETAIL</td> <td>F1 B2</td> <td>24</td> </tr> <tr> <td>MSG_MGM_ADMIN_LGOUT</td> <td>F1 BA</td> <td>4</td> </tr> <tr> <td>MSG_MGM_ADMIN_CHG</td> <td>F1 BC</td> <td>164</td> </tr> <tr> <td>MSG_VGW_LGN</td> <td>F1 C0</td> <td>24</td> </tr> <tr> <td>MSG_VGW_LGN_EX</td> <td>F1 C0</td> <td>24</td> </tr> <tr> <td>MSG_VGW_REQ</td> <td>F1 C3</td> <td>20</td> </tr> <tr> <td>MSG_VGW_REQ_ACK</td> <td>F1 C4</td> <td>4</td> </tr> <tr> <td>MSG_VGW_HELLO</td> <td>F1 C5</td> <td>0</td> </tr> <tr> <td>MSG_VGW_LST_REQ</td> <td>F1 C6</td> <td>20</td> </tr> <tr> <td>MSG_DRW</td> <td>F1 D0</td> <td><em>variable</em></td> </tr> <tr> <td>MSG_DRW_ACK</td> <td>F1 D1</td> <td><em>variable</em></td> </tr> <tr> <td>MSG_P2P_ALIVE</td> <td>F1 E0</td> <td>0</td> </tr> <tr> <td>MSG_P2P_ALIVE_ACK</td> <td>F1 E1</td> <td>0</td> </tr> <tr> <td>MSG_CLOSE</td> <td>F1 F0</td> <td>0</td> </tr> <tr> <td>MSG_MGM_DEV_LGN_DETAIL_DUMP</td> <td>F1 F4</td> <td>12</td> </tr> <tr> <td>MSG_MGM_DEV_LGN_DUMP</td> <td>F1 F4</td> <td>12</td> </tr> <tr> <td>MSG_MGM_LOG_CTRL</td> <td>F1 F7</td> <td>12</td> </tr> <tr> <td>MSG_SVR_REQ</td> <td>F2 10</td> <td>0</td> </tr> <tr> <td>MSG_DEV_LV_HB</td> <td>A1 00</td> <td>20</td> </tr> <tr> <td>MSG_DEV_SLP_HB</td> <td>A1 01</td> <td>20</td> </tr> <tr> <td>MSG_DEV_QUERY</td> <td>A1 02</td> <td>20</td> </tr> <tr> <td>MSG_DEV_WK_UP_REQ</td> <td>A1 04</td> <td>20</td> </tr> <tr> <td>MSG_DEV_WK_UP</td> <td>A1 06</td> <td>20</td> </tr> </tbody></table><h4>HLP2P</h4><p>While I’ve seen a few of apps with HLP2P code and the corresponding init strings, I am not sure whether these are still used or merely leftovers from some past adventure. All these apps use primarily networks that rely on other protocol implementations.</p><p>HLP2P init strings contain a dash which follows merely three letters. These three letters are ignored and I am unsure about their significance as I’ve only seen one variant:</p><pre tabindex="0"><code>DAS-0123456789ABCDEF</code></pre><p>The decoding function is called from <code>HLP2P_Initialize</code> function and uses the most elaborate approach of all. The hex-encoded part after the dash is decrypted using AES-CBC where the key and initialization vector are derived from a zero-filled buffer via some bogus MD5 hashing. The decoded result is a list of comma-separated parameters like:</p><pre tabindex="0"><code>DCDC07FF,das,10000001,a+a+a,127.0.0.1-192.168.1.1-10.0.0.1,ABC-CBA</code></pre><p>The fifth parameter is a list of server IP addresses and the sixth appears to be the list of supported device prefixes.</p><p>On the network level HLP2P is an oddity here. Despite trying hard to provide the same API as other PPPP implementations, including concepts like init strings and device IDs, it appears to be a TCP-based protocol (connecting to server’s port 65527) with little resemblance to PPPP. UDP appears to be used for local broadcasts only (on port 65531). I didn’t spend too much time on the analysis however.</p><h3>“Encryption”</h3><p>The CS2 implementation of the protocol is the only one that bothers with encrypting data, though their approach is better described as obfuscation. When encryption is enabled, the function <code>P2P_Proprietary_Encrypt</code> is applied to all outgoing and the function <code>P2P_Proprietary_Decrypt</code> to all incoming messages. These functions take the encryption key (which is visible in the application code as an unobfuscated part of the init string) and mash it into four bytes. These four bytes are then used to select values from a static table that the bytes of the message should be XOR’ed with.</p><p>There is at least one <a href="https://github.com/datenstau/A9_PPPP/blob/c29d1eaccd11794a4cc022cf4ca90b7352920bc1/crypt.js">public implementation of this “encryption”</a> though this one chose to skip the “key mashing” part and simply took the resulting four bytes as its key. A number of articles mention having implemented this algorithm however, it’s not really complicated.</p><p>The same obfuscation is used unconditionally for TCP traffic (TCP communication on port 443 as fallback). Here each message header contains two random bytes. The hex representation of these bytes is used as key to obfuscate message contents.</p><p>All <code>*_CRC</code> messages like <code>MSG_DEV_LGN_CRC</code> have an additional layer of obfuscation, performed by the functions <code>PPPP_CRCEnc</code> and <code>PPPP_CRCDec</code>. Unlike <code>P2P_Proprietary_Encrypt</code> which is applied to the entire message including the header, <code>PPPP_CRCEnc</code> is only applied to the payload. As normally only messages exchanged between the device and the server are obfuscated in this way, the corresponding key tends to be contained only in the device firmware and not in the application. Here as well the key is mashed into four bytes which are then used to generate a byte sequence that the message (extended by four <code>+</code> signs) is XOR’ed with. This is effectively an <a href="https://en.wikipedia.org/wiki/XOR_cipher">XOR cipher</a> with a static key which is easy to crack even without knowing the key.</p><h3>“Secret” messages</h3><p>The CS2 implementation of the protocol contains a curiosity: two messages starting with <code>338DB900E559</code> being processed in a special way. No, this isn’t a hexadecimal representation of the bytes – it’s literally the message contents. No magic bytes, no encryption, the messages are expected to be 17 bytes long and are treated as zero-terminated strings.</p><p>I tried sending <code>338DB900E5592B32</code> (with a trailing zero byte) to a PPPP server and, surprisingly, received a response (non-ASCII bytes are represented as escape sequences):</p><pre tabindex="0"><code>\x0e\x0ay\x07\x08uT_ChArLiE@Cs2-NeTwOrK.CoM!</code></pre><p>This response was consistent for this server, but another server of the same network responded slightly differently:</p><pre tabindex="0"><code>\x0e\x0ay\x07\x08vT_ChArLiE@Cs2-NeTwOrK.CoM!</code></pre><p>A server from a different network which normally encrypts all communication also responded:</p><pre tabindex="0"><code>\x17\x06f\x12fDT_ChArLiE@Cs2-NeTwOrK.CoM!</code></pre><p>It doesn’t take a lot of cryptanalysis knowledge to realize that an <a href="https://en.wikipedia.org/wiki/XOR_cipher">XOR cipher</a> with a constant key is being applied here. Thanks to my “razor sharp deduction” I could conclude that the servers are replying with their respective names and these names are being XOR’ed with the string <code>CS2MWDT_ChArLiE@Cs2-NeTwOrK.CoM!</code>. Yes, likely the very same Charlie already mentioned at the start of this article. Hi, Charlie!</p><p>I didn’t risk sending the other message, not wanting to shut down a server accidentally. But maybe Shodan wants to extend their method of detecting PPPP servers: their current approach only works when no encryption is used, yet this message seems to get replies from all CS2 servers regardless of encryption.</p><h3>Applications</h3><p>Once a connection between the client and the device is established, <code>MSG_DRW</code> messages are exchanged in both directions. The messages will be delivered in order and retransmitted if lost, giving application developers something resembling a TCP stream if you don’t look too closely. In addition, each message is tagged with a channel ID, a number between 0 and 7. It looks like channel IDs are universally ignored by devices and are only relevant in the other direction. The idea seems to be that a client receiving a video stream should still be able to send commands to the device and receive responses over the same connection.</p><p>The PPPP protocol doesn’t make any recommendations about how applications should encode their data within that stream, and so they developed a number of wildly different application-level protocols. As a rule of thumb, all devices and clients on a particular PPPP network will always speak the same application-level protocol, though there might be slight differences in the supported capabilities. Different networks can share the same protocol, allowing them to be supported within the same application. Usually, there will be multiple applications implementing the same application-level protocol and working with the same PPPP networks, but I haven’t yet seen any applications supporting different protocols.</p><p>This allows grouping the applications by their application-level protocol. Applications within the same group are largely interchangeable, same devices can be accessed from any application. This doesn’t necessarily mean that everything will work correctly, as there might still be subtle differences. E.g. an application meant for visual doorbells probably accesses somewhat different functionality than one meant for security cameras even if both share the same protocol. Also, devices might be tied to the cloud infrastructure of a specific application, rendering them inaccessible to other applications working with the same PPPP network.</p><p>Fun fact: it is often <em>very</em> hard to know up front which protocol your device will speak. There is a <a href="https://community.home-assistant.io/t/popular-a9-mini-wi-fi-camera-the-ha-challenge/230108">huge thread</a> with many spin-offs where people are attempting to reverse engineer A9 Mini cameras so that these can be accessed without an app. This effort is being massively complicated by the fact that all these cameras look basically the same, yet depending on the camera one out of at least four extremely different protocols could be used: HDWifiCamPro variant of SHIX JSON, YsxLite variant of iLnk binary, JXLCAM variant of CGI calls, or some protocol I don’t know because it isn’t based on PPPP.</p><p>The following is a list of PPPP-based applications I’ve identified so far, at least the ones with noteworthy user numbers. Mind you, these numbers aren’t necessarily indicative of the number of PPPP devices – some applications listed only use PPPP for some devices, likely using other protocols for most of their supported devices (particularly the ones that aren’t cameras). I try to provide a brief overview of the application-level protocol in the footnotes. <em>Disclaimer</em>: These applications tend to support a huge number of device prefixes in theory, so I mostly chose the “typical” ones based on which ones appear in YouTube videos or GitHub discussions.</p><table> <thead> <tr> <th>Application</th> <th>Typical device prefixes</th> <th>Application-level protocol</th> </tr> </thead> <tbody> <tr> <td><a href="https://play.google.com/store/apps/details?id=com.xiaomi.smarthome">Xiaomi Home</a></td> <td>XMSYSGB</td> <td>JSON (MISS) <sup id="fnref:1"><a class="footnote-ref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fn:1">1</a></sup></td> </tr> <tr> <td><a href="https://play.google.com/store/apps/details?id=com.yitechnology.kamihome">Kami Home</a><br /><a href="https://play.google.com/store/apps/details?id=com.ants360.yicamera.international">Yi Home</a><br /><a href="https://play.google.com/store/apps/details?id=com.yunyi.smartcamera">Yi iot</a></td> <td>TNPCHNA TNPCHNB TNPUSAC TNPUSAM TNPXGAC</td> <td>binary <sup id="fnref:2"><a class="footnote-ref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fn:2">2</a></sup></td> </tr> <tr> <td><a href="https://play.google.com/store/apps/details?id=com.tuya.smart">Tuya - Smart Life,Smart Living</a></td> <td>TUYASA</td> <td>binary (Tuya SDK) <sup id="fnref:3"><a class="footnote-ref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fn:3">3</a></sup></td> </tr> <tr> <td><a href="https://play.google.com/store/apps/details?id=shix.cam365.camera">365Cam</a><br /><a href="https://play.google.com/store/apps/details?id=shix.cy.camera">CY365</a><br /><a href="https://play.google.com/store/apps/details?id=shix.good.cam">Goodcam</a><br /><a href="https://play.google.com/store/apps/details?id=com.shix.qhipc">HDWifiCamPro</a><br /><a href="https://play.google.com/store/apps/details?id=shix.pixlink.camera">PIX-LINK CAM</a><br /><a href="https://play.google.com/store/apps/details?id=shix.vi.camera">VI365</a><br /><a href="https://play.google.com/store/apps/details?id=shix.go.zoom">X-IOT CAM</a></td> <td>DBG DGB DGO DGOA DGOC DGOE NMSA PIXA PIZ</td> <td>JSON (SHIX) <sup id="fnref:4"><a class="footnote-ref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fn:4">4</a></sup></td> </tr> <tr> <td><a href="https://play.google.com/store/apps/details?id=vstc.vscam.client">Eye4</a><br /><a href="https://play.google.com/store/apps/details?id=com.okampro.oksmart">O-KAM Pro</a><br /><a href="https://play.google.com/store/apps/details?id=object.pnpcam3.client">Veesky</a></td> <td>EEEE VSTA VSTB VSTC VSTD VSTF VSTJ</td> <td>CGI calls <sup id="fnref:5"><a class="footnote-ref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fn:5">5</a></sup></td> </tr> <tr> <td><a href="https://play.google.com/store/apps/details?id=com.hichip">CamHi</a><br /><a href="https://play.google.com/store/apps/details?id=com.hichip.campro">CamHipro</a></td> <td>AAFF EEEE MMMM NNNN PPPP SSAA SSAH SSAK SSAT SSSS TTTT</td> <td>binary <sup id="fnref:6"><a class="footnote-ref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fn:6">6</a></sup></td> </tr> <tr> <td><a href="https://play.google.com/store/apps/details?id=com.cloudedge.smarteye">CloudEdge</a><br /><a href="https://play.google.com/store/apps/details?id=com.iegeekCam.cam">ieGeek Cam</a></td> <td>ECIPCM</td> <td>binary (Meari SDK) <sup id="fnref:7"><a class="footnote-ref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fn:7">7</a></sup></td> </tr> <tr> <td><a href="https://play.google.com/store/apps/details?id=com.ysxlite.cam">YsxLite</a></td> <td>BATC BATE PTZ PTZA PTZB TBAT</td> <td>binary (iLnk) <sup id="fnref:8"><a class="footnote-ref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fn:8">8</a></sup></td> </tr> <tr> <td><a href="https://play.google.com/store/apps/details?id=com.fty.cam">FtyCamPro</a></td> <td>FTY FTYA FTYC FTZ FTZW</td> <td>binary (iLnk) <sup id="fnref:9"><a class="footnote-ref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fn:9">9</a></sup></td> </tr> <tr> <td><a href="https://play.google.com/store/apps/details?id=com.rtp2p.jxlcam">JXLCAM</a></td> <td>ACCQ BCCA BCCQ CAMA</td> <td>CGI calls <sup id="fnref:10"><a class="footnote-ref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fn:10">10</a></sup></td> </tr> <tr> <td><a href="https://play.google.com/store/apps/details?id=com.view.ppcs">LookCam</a></td> <td>BHCC FHBB GHBB</td> <td>JSON <sup id="fnref:11"><a class="footnote-ref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fn:11">11</a></sup></td> </tr> <tr> <td><a href="https://play.google.com/store/apps/details?id=shix.homeeye.camera">HomeEye</a><br /><a href="https://play.google.com/store/apps/details?id=com.shix.lookcam">LookCamPro</a><br /><a href="https://play.google.com/store/apps/details?id=shix.stareye.camera">StarEye</a></td> <td>AYS AYSA TUT</td> <td>JSON (SHIX) <sup id="fnref:12"><a class="footnote-ref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fn:12">12</a></sup></td> </tr> <tr> <td><a href="https://play.google.com/store/apps/details?id=com.rtp2p.minicam">minicam</a></td> <td>CAM888</td> <td>CGI calls <sup id="fnref:13"><a class="footnote-ref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fn:13">13</a></sup></td> </tr> <tr> <td><a href="https://play.google.com/store/apps/details?id=com.abus.app2camplus.gcm">App2Cam Plus</a></td> <td>CGAG CMAG CTAI WGAG</td> <td>binary (Jsw SDK) <sup id="fnref:14"><a class="footnote-ref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fn:14">14</a></sup></td> </tr> </tbody></table><div class="footnotes"><hr /><ol><li id="fn:1"><p>Each message starts with a 4 byte command ID. The initial authorization messages (command ID <code>0x100</code> and <code>0x101</code>) contain plain JSON data. Other messages contain ChaCha20-encoded data: first 8 bytes nonce, then the ciphertext. The encryption key is negotiated in the authorization phase. The decrypted plaintext again starts with a <a href="https://github.com/MiEcosystem/miot-plugin-sdk/blob/e4883f6f58528cdae9ef632a011ab11ad4b4d023/miot-sdk/service/miotcamera.js#L17">4 byte command ID</a>, followed by JSON data. There is even some <a href="https://iot.mi.com/new/doc/accesses/direct-access/extension-development/extension-functions/p2p">Chinese documentation of this interface</a> though it is rather underwhelming. <a class="footnote-backref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fnref:1">↩︎</a></p></li><li id="fn:2"><p>The device-side implementation of the protocol is <a href="https://github.com/frankzhangshcn/p2p_tnp/blob/191f2e7c4841ab6113ad6fa4b80affbd4cad556c/p2p_tnp.c#L7308">available on the web</a>. This doesn’t appear to be reverse engineered, it’s rather the source code of the real thing complete with Chinese comments. No idea who or why published this, I found it linked by the people who develop own changes to the stock camera firmware. The extensive <code>tnp_eventlist_msg_s</code> structure being sent and received here supports a large number of commands. <a class="footnote-backref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fnref:2">↩︎</a></p></li><li id="fn:3"><p>Each message is preceded by a 16 byte header: <code>78 56 34 12</code> magic bytes, request ID, command ID, payload size. This is a very basic interface exposing merely 10 commands, most of which are requesting device information while the rest control video/audio playback. As Tuya SDK also communicates with devices by means other than PPPP, more advanced functionality is probably exposed elsewhere. <a class="footnote-backref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fnref:3">↩︎</a></p></li><li id="fn:4"><p>Messages are preceded by an 8 byte binary header: <code>06 0A A0 80</code> magic bytes, four bytes payload size (there is <a href="https://github.com/datenstau/A9_PPPP/blob/c29d1eaccd11794a4cc022cf4ca90b7352920bc1/pppp.js#L234">a JavaScript-based implementation</a>). The SHIX JSON format is a translation of <a href="https://wiki.instar.com/dl/Developer/INSTAR_CGI_MJPEG_Chipset_English.pdf">this web API interface</a>: <code>/check_user.cgi?user=admin&amp;pwd=pass</code> becomes <code>{"pro": "check_user", "cmd": 100, "user": "admin", "pwd": "pass"}</code>. The <code>pro</code> and <code>cmd</code> fields are redundant, representing a command both as a string and as a number. <a class="footnote-backref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fnref:4">↩︎</a></p></li><li id="fn:5"><p>The binary message headers are similar to the ones used by apps like 365Cam: <code>01 0A 00 00</code> magic bytes, four bytes payload size. The payload is however a web request loosely based on <a href="https://wiki.instar.com/dl/Developer/INSTAR_CGI_MJPEG_Chipset_English.pdf">this web API interface</a>: <code>GET /check_user.cgi?loginuse=admin&amp;loginpas=pass&amp;user=admin&amp;pwd=pass</code>. Yes, user name and password are duplicated, probably because not all devices expect <code>loginuse</code>/<code>loginpas</code> parameters? You can see in <a href="https://x9security.com/vstarcam-an-investigative-security-journey-part-1-by-redcodefinal/#:~:text=UDP%20GET%20Requests">this article</a> what the requests looks like. <a class="footnote-backref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fnref:5">↩︎</a></p></li><li id="fn:6"><p>Each message is preceded by a 24 byte header starting with the magic bytes <code>99 99 99 99</code>, payload size and command ID. The other 12 bytes of the header are unused. Not trusting PPPP, CamHi encrypts the payload using AES. It looks like the encryption key is an MD5 hash of a string containing the user name and password among other things. Somebody published some <a href="https://github.com/0xedh/hichip-p2p-firmware-rce#CamHI">initial insights into the application code</a>. <a class="footnote-backref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fnref:6">↩︎</a></p></li><li id="fn:7"><p>Each message is preceded by a 52 byte header starting with the magic bytes <code>56 56 50 99</code>. Bulk of this header is taken up by an authentication token: a SHA1 hex digest hashing the username (always admin), device password, sequence number, command ID and payload size. The implemented interface provides merely 14 very basic commands, essentially only exposing access to recordings and the live stream. So the payload even where present is something trivial like a date. As Meari SDK also communicates with devices by means other than PPPP, more advanced functionality is probably exposed elsewhere. <a class="footnote-backref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fnref:7">↩︎</a></p></li><li id="fn:8"><p>The commands and their binary representation are contained within <code>libvdp.so</code> which is the iLnk implementation of the PPPP protocol. Each message is preceded by a 12 bytes header starting with the <code>11 0A</code> magic bytes. The commands are two bytes long with the higher byte indicating the command type: 2 for SD card command, 3 for A/V command, 4 for file command, 5 for password command, 6 for network command, 7 for system command. <a class="footnote-backref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fnref:8">↩︎</a></p></li><li id="fn:9"><p>While FtyCamPro app handles different networks than YsxLite, it relies on the same <code>libvdp.so</code> library, meaning that the application-level protocol should be the same. It’s possible that some commands are interpreted differently however. <a class="footnote-backref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fnref:9">↩︎</a></p></li><li id="fn:10"><p>The protocol is very similar to the one used by VStarcam apps like O-KAM Pro. The payload has only one set of credentials however, the parameters <code>user</code> and <code>pwd</code>. It’s also a far more limited and sometimes different set of commands. <a class="footnote-backref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fnref:10">↩︎</a></p></li><li id="fn:11"><p>Each message is wrapped in binary data: a prefix starting with <code>A0 AF AF AF</code> before it, the bytes <code>F4 F3 F2 F1</code> after. For some reason the prefix length seems to be different depending on whether the message is sent to the device (26 bytes) or received from it (25 bytes). I don’t know what most of it is yet everything but the payload length at the end of the prefix seems irrelevant. <a href="https://www.dcs.warwick.ac.uk/~fenghao/files/hidden_camera.pdf">This Warwick University paper</a> has some info on the JSON payload. It’s particularly notable that the password sent along with each command isn’t actually being checked. <a class="footnote-backref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fnref:11">↩︎</a></p></li><li id="fn:12"><p>LookCamPro &amp; Co. share significant amounts of code with the SHIX apps like 365Cam, they implement basically the same application-level protocol. There are differences in the supported commands however. It’s difficult to say how significant these differences are because all apps contain significant amounts of dead code, defining commands that are never used and probably not even supported. <a class="footnote-backref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fnref:12">↩︎</a></p></li><li id="fn:13"><p>The minicam app seems to use almost the same protocol as VStarcam apps like O-KAM Pro. It handles other networks however. Also, a few of the commands seem different from the ones used by O-KAM Pro, though it is hard to tell how significant these incompatibilities really are. <a class="footnote-backref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fnref:13">↩︎</a></p></li><li id="fn:14"><p>Each message is preceded by a 4 bytes header: 3 bytes payload size, 1 byte I/O type (1 for AUTH, 2 for VIDEO, 3 for AUDIO, 4 for IOCTRL, 5 for FILE). The payload starts with a type-specific header. If I read the code correctly, the first 16 bytes of the payload are encrypted with AES-ECB (unpadded) while the rest is sent unchanged. There is an “xor byte” in the payload header which is changed with every request seemingly to avoid generating identical ciphertexts. Payloads smaller than 16 bytes are not encrypted. I cannot see any initialization of the encryption key beyond filling it with 32 zero bytes, which would mean that this entire mechanism is merely obfuscation. <a class="footnote-backref" href="https://palant.info/2025/11/05/an-overview-of-the-pppp-protocol-for-iot-cameras/#fnref:14">↩︎</a></p></li></ol></div></description> <pubDate>Wed, 05 Nov 2025 15:11:36 +0000</pubDate></item><item> <title>Niko Matsakis: But then again...maybe alias?</title> <guid isPermaLink="false">https://smallcultfollowing.com/babysteps/blog/2025/11/05/maybe-alias/</guid> <link>https://smallcultfollowing.com/babysteps/blog/2025/11/05/maybe-alias/?utm_source=atom_feed</link> <description><p>Hmm, as I re-read the post I literally <em>just</em> posted a few minutes ago, I got to thinking. Maybe the right name is indeed <code>Alias</code>, and not <code>Share</code>. The rationale is simple: alias can serve as both a noun and a verb. It hits that sweet spot of “common enough you know what it means, but weird enough that it can be Rust Jargon for something quite specific”. In the same way that we talk about “passing a clone of <code>foo</code>” we can talk about “passing an alias to <code>foo</code>” or an “alias of <code>foo</code>”. Food for thought! I’m going to try <code>Alias</code> on for size in future posts and see how it feels.</p></description> <pubDate>Wed, 05 Nov 2025 13:57:20 +0000</pubDate></item><item> <title>Niko Matsakis: Bikeshedding `Handle` and other follow-up thoughts</title> <guid isPermaLink="false">https://smallcultfollowing.com/babysteps/blog/2025/11/05/bikeshedding-handle/</guid> <link>https://smallcultfollowing.com/babysteps/blog/2025/11/05/bikeshedding-handle/?utm_source=atom_feed</link> <description><p>There have been two major sets of responses to my proposal for a <code>Handle</code> trait. The first is that the <code>Handle</code> trait seems useful but doesn’t over all the cases where one would like to be able to ergonomically clone things. The second is that the name doesn’t seem to fit with our Rust conventions for trait names, which emphasize short verbs over nouns. The TL;DR of my response is that (1) I agree, this is why I think we should work to make <code>Clone</code> ergonomic as well as <code>Handle</code>; and (2) I agree with that too, which is why I think we should find another name. At the moment I prefer <code>Share</code>, with <code>Alias</code> coming in second.</p><h3>Handle doesn’t cover everything</h3><p>The first concern with the <code>Handle</code> trait is that, while it gives a clear semantic basis for when to implement the trait, it does not cover all the cases where calling <code>clone</code> is annoying. In other words, if we opt to use <code>Handle</code>, and then we make creating new handles very ergonomic, but calling <code>clone</code> remains painful, there will be a temptation to use the <code>Handle</code> when it is not appropriate.</p><p>In one of our lang team design meetings, TC raised the point that, for many applications, even an “expensive” clone isn’t really a big deal. For example, when writing CLI tools and things, I regularly clone strings and vectors of strings and hashmaps and whatever else; I could put them in an Rc or Arc but I know it just doens’t matter.</p><p>My solution here is simple: let’s make solutions that apply to both <code>Clone</code> and <code>Handle</code>. Given that I think we need a proposal that allows for handles that are <em>both</em> ergonomic <em>and</em> explicit, it’s not hard to say that we should extend that solution to include the option for clone.</p><p>The <a href="https://smallcultfollowing.com/babysteps/ /blog/2025/10/22/explicit-capture-clauses.html">explicit capture clause</a> post already fits this design. I explicitly chose a design that allowed for users to write <code>move(a.b.c.clone())</code> or <code>move(a.b.c.handle())</code>, and hence works equally well (or equally not well…) with both traits</p><h3>The name <code>Handle</code> doesn’t fit the Rust conventions</h3><p>A number of people have pointed out <code>Handle</code> doesn’t fit the Rust naming conventions for traits like this, which aim for short verbs. You can interpret <code>handle</code> as a verb, but it doesn’t mean what we want. Fair enough. I like the name <code>Handle</code> because it gives a <em>noun</em> we can use to talk about, well, <em>handles</em>, but I agree that the trait name doesn’t seem right. There was a lot of bikeshedding on possible options but I think I’ve come back to preferring Jack Huey’s original proposal, <code>Share</code> (with a method <code>share</code>). I think <code>Alias</code> and <code>alias</code> is my second favorite. Both of them are short, relatively common verbs.</p><p>I originally felt that <code>Share</code> was a bit too generic and overly associated with sharing across threads – but then I at least always call <code>&amp;T</code> a <em>shared reference</em><sup id="fnref:1"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:1">1</a></sup>, and an <code>&amp;T</code> would implement <code>Share</code>, so it all seems to work well. Hat tip to Ariel Ben-Yehuda for pushing me on this particular name.</p><h3>Coming up next</h3><p>The flurry of posts in this series have been an attempt to survey all the discussions that have taken place in this area. I’m not yet aiming to write a final proposal – I think what will come out of this is a series of multiple RFCs.</p><p>My current feeling is that we should add the <code>Hand^H^H^H^H</code>, uh, <code>Share</code> trait. I also think we should add <a href="https://smallcultfollowing.com/babysteps/ /blog/2025/10/22/explicit-capture-clauses.html">explicit capture clauses</a>. However, while explicit capture clauses are clearly “low-level enough for a kernel”, I don’t really think they are “usable enough for a GUI” . The next post will explore another idea that I think might bring us closer to that ultimate <a href="https://smallcultfollowing.com/babysteps/ /blog/2025/10/13/ergonomic-explicit-handles.html">ergonomic and explicit</a> goal.</p><div class="footnotes"><hr /><ol><li id="fn:1"><p>A lot of people say <em>immutable reference</em> but that is simply accurate: an <code>&amp;Mutex</code> is not immutable. I think that the term shared reference is better. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:1">↩︎</a></p></li></ol></div></description> <pubDate>Wed, 05 Nov 2025 13:15:38 +0000</pubDate></item><item> <title>This Week In Rust: This Week in Rust 624</title> <guid isPermaLink="false">tag:this-week-in-rust.org,2025-11-05:/blog/2025/11/05/this-week-in-rust-624/</guid> <link>https://this-week-in-rust.org/blog/2025/11/05/this-week-in-rust-624/</link> <description><p>Hello and welcome to another issue of <em>This Week in Rust</em>!<a href="https://www.rust-lang.org/">Rust</a> 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<a href="https://bsky.app/profile/thisweekinrust.bsky.social">@thisweekinrust.bsky.social</a> on Bluesky or<a href="https://mastodon.social/@thisweekinrust">@ThisWeekinRust</a> on mastodon.social, or<a href="https://github.com/rust-lang/this-week-in-rust">send us a pull request</a>.Want to get involved? <a href="https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md">We love contributions</a>.</p><p><em>This Week in Rust</em> is openly developed <a href="https://github.com/rust-lang/this-week-in-rust">on GitHub</a> and archives can be viewed at <a href="https://this-week-in-rust.org/">this-week-in-rust.org</a>.If you find any errors in this week's issue, <a href="https://github.com/rust-lang/this-week-in-rust/pulls">please submit a PR</a>.</p><p>Want TWIR in your inbox? <a href="https://this-week-in-rust.us11.list-manage.com/subscribe?u=fd84c1c757e02889a9b08d289&amp;id=0ed8b72485">Subscribe here</a>.</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#updates-from-rust-community">Updates from Rust Community</a></h4> <h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#official">Official</a></h5><ul><li><a href="https://blog.rust-lang.org/2025/10/28/project-goals-2025h2/">Project goals for 2025H2 | Rust Blog</a></li><li><a href="https://blog.rust-lang.org/2025/10/30/Rust-1.91.0/">Announcing Rust 1.91.0 | Rust Blog</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#foundation">Foundation</a></h5><ul><li><a href="https://rustfoundation.org/media/announcing-the-rust-foundation-maintainers-fund/">Announcing the Rust Foundation Maintainers Fund - The Rust Foundation</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#newsletters">Newsletters</a></h5><ul><li><a href="https://rust-trends.com/newsletter/production-rust-internet-scale">Rust Trends Issue #71: Production Rust at Internet Scale</a></li><li><a href="https://www.redox-os.org/news/this-month-251031/">This Month in Redox - October 2025 - Redox - Your Next(Gen) OS</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#projecttooling-updates">Project/Tooling Updates</a></h5><ul><li><a href="https://opendevicepartnership.github.io/patina/introduction.html">Developing UEFI in Rust with Patina</a></li><li><a href="https://contextgeneric.dev/blog/cgp-serde-release/">Announcing cgp-serde: A modular serialization library for Serde powered by CGP</a></li><li><a href="https://contextgeneric.dev/blog/v0-6-0-release/">CGP v0.6.0 Release - Major ergonomic improvements for provider and context implementations</a></li><li><a href="https://developer.espressif.com/blog/2025/10/esp-hal-1/"><code>esp-hal</code> 1.0.0 release announcement</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#observationsthoughts">Observations/Thoughts</a></h5><ul><li><a href="https://predr.ag/blog/ghosts-in-the-compilation/">Ghosts in the Compilation</a></li><li><a href="https://corrode.dev/blog/defensive-programming/">Patterns for Defensive Programming in Rust | corrode Rust Consulting</a></li><li><a href="https://corrode.dev/podcast/s05e03-cloudflare/">Cloudflare with Edward Wang &amp; Kevin Guthrie - Rust in Production</a></li><li><a href="https://pranitha.dev/posts/neural-networks-with-candle/">Neural Networks with Candle</a></li><li><a href="https://www.youtube.com/watch?v=_x61dSP4ZKM">Async Rust - Part 18 of Idiomatic Rust in Simple Steps</a></li><li><a href="https://shnatsel.medium.com/the-state-of-simd-in-rust-in-2025-32c263e5f53d">The state of SIMD in Rust in 2025</a></li><li><a href="https://kerkour.com/rust-is-eating-the-world">Rust is eating the world: From embedded firmware to cross-platform applications, databases and big servers</a></li><li>[video] <a href="https://www.youtube.com/watch?v=Ga2YDNDHQsM">Building Next Generation Rail Systems With Rust: Tom Praderio of Parallel</a></li><li>[video] <a href="https://www.youtube.com/watch?v=0ZrD2oYabn4">Are we desktop yet? - Victoria Brekenfeld | EuroRust 2025</a></li><li>[audio] <a href="https://netstack.fm/#episode-12">Netstack.FM Episode 12 – Oxide Networking with Ryan Goodfellow</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-walkthroughs">Rust Walkthroughs</a></h5><ul><li><a href="https://jorgeortiz.dev/posts/rust_unit_testing_test_doubles_fake/">Rust Unit Testing Test Doubles: Fakes</a></li><li><a href="https://blog.0xshadow.dev/posts/coding-agent-in-rust/coding-agent-in-rust-chat/">Building a Coding Agent in Rust: Implementing Chat Feature</a></li><li><a href="https://www.djamware.com/post/690864cde87a290bcfebeebe/image-classification-in-rust-with-tchrs-torch-bindings">Image Classification in Rust with Tch-rs (Torch bindings)</a></li><li><a href="https://blog.cuongle.dev/p/inside-rusts-std-and-parking-lot-mutexes-who-win">Inside Rust's std and parking_lot mutexes - who wins?</a></li><li><a href="https://positron.solutions/articles/building-nicely-with-rust-and-nix">Positron - Only the Future Is Certain</a></li><li><a href="https://www.svix.com/blog/getting-started-with-rust-and-clickhouse/">Getting Started with Rust and ClickHouse</a></li><li><a href="https://sunshowers.io/posts/socketaddrv6-not-roundtrip/"><code>SocketAddrV6</code> is not roundtrip serializable · sunshowers</a></li><li><a href="https://filtra.io/rust/interviews/parallel-nov-25">Building Next Generation Rail Systems With Rust: Tom Praderio of Parallel</a></li><li><a href="https://blog.weiznich.de/rustweek_2025.html#/title-slide">Diesel Workshop Slides from RustWeek2025</a></li><li>[video] <a href="https://www.youtube.com/watch?v=N21aCBICHLU">Building Coding Agent in Rust | Implement Chat CLI | Part-2</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#miscellaneous">Miscellaneous</a></h5><ul><li><a href="https://cant.bearblog.dev/can-t-stop-till-you-get-enough/">Can-t stop till you get enough</a></li></ul><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#crate-of-the-week">Crate of the Week</a></h4><p>This week's crate is <a href="https://docs.rs/dioxus">dioxus</a>, a framework for building cross-platform apps.</p><p>Thanks to <a href="https://users.rust-lang.org/t/crate-of-the-week/2704/1484">llogiq</a> for the suggestion!</p><p><a href="https://users.rust-lang.org/t/crate-of-the-week/2704">Please submit your suggestions and votes for next week</a>!</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#calls-for-testing">Calls for Testing</a></h4><p>An important step for RFC implementation is for people to experiment with theimplementation and give feedback, especially before stabilization.</p><p>If you are a feature implementer and would like your RFC to appear in this list, add a<code>call-for-testing</code> label to your RFC along with a comment providing testing instructions and/orguidance on which aspect(s) of the feature need testing.</p><ul><li><em>No calls for testing were issued this week by <a href="https://github.com/rust-lang/rust/labels/call-for-testing">Rust</a>, <a href="https://github.com/rust-lang/cargo/labels/call-for-testing">Cargo</a>, <a href="https://github.com/rust-lang/rfcs/issues?q=label%3Acall-for-testing">Rust language RFCs</a> or <a href="https://github.com/rust-lang/rustup/labels/call-for-testing">Rustup</a>.</em></li></ul><p><a href="https://github.com/rust-lang/this-week-in-rust/issues">Let us know</a> if you would like your feature to be tracked as a part of this list.</p><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rfcs"></a><a href="https://github.com/rust-lang/rfcs/issues?q=label%3Acall-for-testing">RFCs</a></h5><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust"></a><a href="https://github.com/rust-lang/rust/labels/call-for-testing">Rust</a></h5><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rustup"></a><a href="https://github.com/rust-lang/rustup/labels/call-for-testing">Rustup</a></h5><p>If you are a feature implementer and would like your RFC to appear on the above list, add the new <code>call-for-testing</code>label to your RFC along with a comment providing testing instructions and/or guidance on which aspect(s) of the featureneed testing.</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#call-for-participation-projects-and-speakers">Call for Participation; projects and speakers</a></h4><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cfp-projects">CFP - Projects</a></h5><p>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!</p><p>Some of these tasks may also have mentors available, visit the task page for more information.</p> <ul><li><a href="https://github.com/moturus/motor-os/issues/33">Motor OS - Improve rush (the shell in Motor OS)</a></li><li><a href="https://github.com/moturus/motor-os/issues/24">Motor OS - Make imager configurable</a></li><li><a href="https://github.com/moturus/motor-os/issues/26">Motor OS - Port libc/llvm/rustc</a></li><li><a href="https://github.com/diesel-rs/diesel/issues/4764">Diesel - Improve documentation for Postgres loading modes</a></li></ul> <p>If you are a Rust project owner and are looking for contributors, please submit tasks <a href="https://github.com/rust-lang/this-week-in-rust?tab=readme-ov-file#call-for-participation-guidelines">here</a> or through a <a href="https://github.com/rust-lang/this-week-in-rust">PR to TWiR</a> or by reaching out on <a href="https://bsky.app/profile/thisweekinrust.bsky.social">Bluesky</a> or <a href="https://mastodon.social/@thisweekinrust">Mastodon</a>!</p><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cfp-events">CFP - Events</a></h5><p>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.</p> <ul><li><a href="https://tokio.rs/blog/2025-09-26-announcing-tokio-conf-cfp"><strong>TokioConf 2026</strong></a>| CFP closes 2025-12-08 | Portland, Oregon, USA | 2026-04-20</li></ul><p>If you are an event organizer hoping to expand the reach of your event, please submit a link to the website through a <a href="https://github.com/rust-lang/this-week-in-rust">PR to TWiR</a> or by reaching out on <a href="https://bsky.app/profile/thisweekinrust.bsky.social">Bluesky</a> or <a href="https://mastodon.social/@thisweekinrust">Mastodon</a>!</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#updates-from-the-rust-project">Updates from the Rust Project</a></h4><p>480 pull requests were <a href="https://github.com/search?q=is%3Apr+org%3Arust-lang+is%3Amerged+merged%3A2025-10-28..2025-11-04">merged in the last week</a></p><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#compiler">Compiler</a></h6><ul><li><a href="https://github.com/rust-lang/rust/pull/148240"><code>rustc_codegen</code>: fix musttail returns for cast/indirect ABIs</a></li><li><a href="https://github.com/rust-lang/rust/pull/148182">accept trivial consts based on trivial consts</a></li><li><a href="https://github.com/rust-lang/rust/pull/148350">add LLVM range attributes to slice length parameters</a></li><li><a href="https://github.com/rust-lang/rust/pull/148157">adjust successor iterators</a></li><li><a href="https://github.com/rust-lang/rust/pull/148299">allow check builds with binaries for the dummy codegen backend</a></li><li><a href="https://github.com/rust-lang/rust/pull/148177">allow codegen backends to indicate which crate types they support</a></li><li><a href="https://github.com/rust-lang/rust/pull/148400">better warning message for crate type unsupported by codegen backend</a></li><li><a href="https://github.com/rust-lang/rust/pull/144444">contract variable declarations</a></li><li><a href="https://github.com/rust-lang/rust/pull/148287">fix deferred cast checks using the wrong body for determining constness</a></li><li><a href="https://github.com/rust-lang/rust/pull/148262">fix types being marked as dead when they are inferred generic arguments</a></li><li><a href="https://github.com/rust-lang/rust/pull/139751">implement pin-project in pattern matching for <code>&amp;pin mut|const T</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/147642">miscellaneous const-generics-related fixes</a></li><li><a href="https://github.com/rust-lang/rust/pull/148193">remove <code>QPath::LangItem</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/145974">stabilize -Zno-jump-tables into -Cjump-tables=bool</a></li><li><a href="https://github.com/rust-lang/rust/pull/145640">when a trait isn't implemented, but another similar impl is found, point at it</a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#library">Library</a></h6><ul><li><a href="https://github.com/rust-lang/rust/pull/146057">add <code>from_fn_ptr</code> to <code>Waker</code> and <code>LocalWaker</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/146260">add SliceIndex wrapper types Last and <code>Clamp&lt;Idx&gt;</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/146573">constify Range functions</a></li><li><a href="https://github.com/rust-lang/rust/pull/144291">constify trait aliases</a></li><li><a href="https://github.com/rust-lang/rust/pull/147161">implement VecDeque <code>extend_from_within</code> and <code>prepend_from_within</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/147780">implement <code>VecDeque::extract_if</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/147947">implement <code>strip_circumfix</code> lib feature</a></li><li><a href="https://github.com/rust-lang/rust/pull/144420">smart pointer <code>(try_)map</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/145915">stabilize <code>fmt::from_fn</code></a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cargo">Cargo</a></h6><ul><li><a href="https://github.com/rust-lang/cargo/pull/16150"><code>build-analysis</code>: JSONL-based logging infra</a></li><li><a href="https://github.com/rust-lang/cargo/pull/16179"><code>build-analysis</code>: emit timing-info log</a></li><li><a href="https://github.com/rust-lang/cargo/pull/16180"><code>config-include</code>: add optional field support</a></li><li><a href="https://github.com/rust-lang/cargo/pull/16174"><code>config-include</code>: support inline and array of tables</a></li><li><a href="https://github.com/rust-lang/cargo/pull/16103">support array of any types in Cargo config</a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rustdoc">Rustdoc</a></h6><ul><li><a href="https://github.com/rust-lang/rust/pull/148301">search: Include extern crates when filtering on <code>import</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/148176">Include attribute and derive macros when filtering on "macros"</a></li><li><a href="https://github.com/rust-lang/rust/pull/148068">use configured target modifiers when collecting doctests</a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#clippy">Clippy</a></h6><ul><li><a href="https://github.com/rust-lang/rust-clippy/pull/15902"><code>search_is_some</code>: Fix when the closure spans multiple lines</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15939"><code>double_parens</code>: don't lint in proc-macros</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/16006"><code>let_and_return</code>: disallow <code>_any_</code> text between let and return</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15946"><code>use_debug</code>: don't get confused by nested <code>Debug</code> impls</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15795"><code>incompatible_msrv</code>: Don't check the const MSRV for uncalled functions</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15817"><code>manual_unwrap_or(_default)</code>: don't lint if not safe to move scrutinee</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/14361">extend <code>needless_collect</code></a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15984">fix <code>replace_box</code> false positive when the box is moved</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15967">improve doc comment code language tag parsing, don't use a full parser</a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-analyzer">Rust-Analyzer</a></h6><ul><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20565">add ide-assist: <code>convert_range_for_to_while</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20927">support memory profiling with dhat</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20957">fix missing other assoc items for <code>generate_blanket_trait_impl</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20915">fix not applicable on while for <code>replace_is_method_with_if_let_method</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20964">canonicalize <code>custom-target.json</code> paths when fetching sysroot metadata</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20961">consider more expression types as <code>in_value</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20963">expand literals with wrong suffixes into <code>LitKind::Err</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20942">false positive syntax errors on frontmatter</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20930">fix handling of blocks modules that are not the root module</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20934">improve error recovery when parsing malformed function return types</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20906">properly support opaques</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20920">resolve <code>target-dir</code> more precisely</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20931">show proper async function signatures in the signature help</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-compiler-performance-triage">Rust Compiler Performance Triage</a></h5><p>Mostly positive week. We saw a great performance win implemented by <a href="https://github.com/rust-lang/rust/pull/148040">#148040</a> and <a href="https://github.com/rust-lang/rust/pull/148182">#148182</a>, which optimizes crates with a lot of trivial constants.</p><p>Triage done by <strong>@kobzol</strong>.</p><p>Revision range: <a href="https://perf.rust-lang.org/?start=23fced0fcc5e0ec260d25f04a8b78b269e5e90f0&amp;end=35ebdf9ba1414456dfe1cb6a6b13ebae80e99734&amp;absolute=false&amp;stat=instructions%3Au">23fced0f..35ebdf9b</a></p><p><strong>Summary</strong>:</p><table><thead><tr><th align="center">(instructions:u)</th><th align="center">mean</th><th align="center">range</th><th align="center">count</th></tr></thead><tbody><tr><td align="center">Regressions ❌ <br /> (primary)</td><td align="center">0.8%</td><td align="center">[0.1%, 2.9%]</td><td align="center">22</td></tr><tr><td align="center">Regressions ❌ <br /> (secondary)</td><td align="center">0.5%</td><td align="center">[0.1%, 1.7%]</td><td align="center">48</td></tr><tr><td align="center">Improvements ✅ <br /> (primary)</td><td align="center">-2.8%</td><td align="center">[-16.4%, -0.1%]</td><td align="center">102</td></tr><tr><td align="center">Improvements ✅ <br /> (secondary)</td><td align="center">-1.9%</td><td align="center">[-8.0%, -0.1%]</td><td align="center">51</td></tr><tr><td align="center">All ❌✅ (primary)</td><td align="center">-2.1%</td><td align="center">[-16.4%, 2.9%]</td><td align="center">124</td></tr></tbody></table><p>4 Regressions, 6 Improvements, 7 Mixed; 7 of them in rollups36 artifact comparisons made in total</p><p><a href="https://github.com/rust-lang/rustc-perf/blob/057eaab3021d6bc301bba06b69e7e1cfdb4f9c3d/triage/2025/2025-11-03.md">Full report here</a>.</p><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#approved-rfcs"></a><a href="https://github.com/rust-lang/rfcs/commits/master">Approved RFCs</a></h5><p>Changes to Rust follow the Rust <a href="https://github.com/rust-lang/rfcs#rust-rfcs">RFC (request for comments) process</a>. Theseare the RFCs that were approved for implementation this week:</p><ul><li><em>No RFCs were approved this week.</em></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#final-comment-period">Final Comment Period</a></h5><p>Every week, <a href="https://www.rust-lang.org/team.html">the team</a> announces the 'final comment period' for RFCs and key PRswhich are reaching a decision. Express your opinions now.</p><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#tracking-issues-prs">Tracking Issues &amp; PRs</a></h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust_1"></a><a href="https://github.com/rust-lang/rust/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Rust</a><ul><li><a href="https://github.com/rust-lang/rust/pull/146978">Emit error when using path-segment keyword as cfg pred</a></li><li><a href="https://github.com/rust-lang/rust/pull/145954">stabilize extern_system_varargs</a></li><li><a href="https://github.com/rust-lang/rust/issues/65816">Tracking issue for <code>vec_into_raw_parts</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/146495">rustdoc: Erase <code>#![doc(document_private_items)]</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/141470">Add new <code>function_casts_as_integer</code> lint</a></li><li><a href="https://github.com/rust-lang/rust/pull/147984">resolve: Preserve ambiguous glob reexports in crate metadata</a></li><li><a href="https://github.com/rust-lang/rust/pull/148122">Make deref_nullptr deny by default instead of warn</a></li><li><a href="https://github.com/rust-lang/rust/issues/146724">Tracking Issue for <code>const_mul_add</code></a></li></ul><a class="toclink" href="http://this-week-in-rust.org/atom.xml#compiler-team-mcps-only"></a><a href="https://github.com/rust-lang/compiler-team/issues?q=label%3Amajor-change%20%20label%3Afinal-comment-period">Compiler Team</a> <a href="https://forge.rust-lang.org/compiler/mcp.html">(MCPs only)</a><ul><li><a href="https://github.com/rust-lang/compiler-team/issues/940">remove support for <code>typeof</code></a></li></ul><a class="toclink" href="http://this-week-in-rust.org/atom.xml#language-reference"></a><a href="https://github.com/rust-lang/reference/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Language Reference</a><ul><li><a href="https://github.com/rust-lang/reference/pull/2064">Guarantee the binary representation of <code>isize</code> explicitly</a></li></ul><a class="toclink" href="http://this-week-in-rust.org/atom.xml#leadership-council"></a><a href="https://github.com/rust-lang/leadership-council/issues?q=state%3Aopen%20label%3Afinal-comment-period">Leadership Council</a><ul><li><a href="https://github.com/rust-lang/leadership-council/issues/228">Proposal: Require all project team members to have Zulip IDs</a></li></ul><p><em>No Items entered Final Comment Period this week for <a href="https://github.com/rust-lang/cargo/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Cargo</a>, <a href="https://github.com/rust-lang/rfcs/labels/final-comment-period">Rust RFCs</a>, <a href="https://github.com/rust-lang/lang-team/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc+">Language Team</a> or <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Unsafe Code Guidelines</a>.</em></p><p>Let us know if you would like your PRs, Tracking Issues or RFCs to be tracked as a part of this list.</p><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#new-and-updated-rfcs"></a><a href="https://github.com/rust-lang/rfcs/pulls">New and Updated RFCs</a></h6><ul><li><a href="https://github.com/rust-lang/rfcs/pull/3875">build-std: explicit dependencies</a></li><li><a href="https://github.com/rust-lang/rfcs/pull/3874">build-std: always</a></li><li><a href="https://github.com/rust-lang/rfcs/pull/3873">build-std: context</a></li></ul><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#upcoming-events">Upcoming Events</a></h4><p>Rusty Events between 2025-11-05 - 2025-12-03 🦀</p><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#virtual">Virtual</a></h5><ul><li>2025-11-05 | Virtual (Buffalo, NY, US) | <a href="https://www.meetup.com/buffalo-rust-meetup">Buffalo Rust Meetup</a><ul><li><a href="https://www.meetup.com/buffalo-rust-meetup/events/305304242/"><strong>Buffalo Rust User Group</strong></a></li></ul></li><li>2025-11-05 | Virtual (Indianapolis, IN, US) | <a href="https://www.meetup.com/indyrs">Indy Rust</a><ul><li><a href="https://www.meetup.com/indyrs/events/311574520/"><strong>Indy.rs - with Social Distancing</strong></a></li></ul></li><li>2025-11-05 | Virtual | <a href="https://www.eventbrite.com/o/ardan-labs-7092394651">Ardan Labs</a><ul><li><a href="https://www.eventbrite.com/e/mastering-error-handling-in-rust-from-panics-to-thiserror-anyhow-tickets-1849030121869"><strong>Mastering Error Handling in Rust: From Panics to thiserror &amp; anyhow</strong></a></li></ul></li><li>2025-11-06 | Virtual (Berlin, DE) | <a href="https://www.meetup.com/rust-berlin/events/">Rust Berlin</a><ul><li><a href="https://www.meetup.com/rust-berlin/events/305646021/"><strong>Rust Hack and Learn</strong></a></li></ul></li><li>2025-11-09 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/events/">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/311109175/"><strong>Rust Readers Discord Discussion: Macros</strong></a></li></ul></li><li>2025-11-10 || <a href="https://www.bettercode.eu/">BetterCode</a><ul><li>$<a href="https://dev.events/conferences/better-code-rust-i6inve6t"><strong>betterCode() Industrielle Anwendungen mit Rust</strong></a></li></ul></li><li>2025-11-11 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/events/">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/305361536/"><strong>Second Tuesday</strong></a></li></ul></li><li>2025-11-11 | Virtual (London, UK) | <a href="https://www.meetup.com/women-in-rust/events/">Women in Rust</a><ul><li><a href="https://www.meetup.com/women-in-rust/events/311068632/"><strong>👋 Community Catch Up</strong></a></li></ul></li><li>2025-11-12 | Virtual (Boulder, CO, US) | <a href="https://www.meetup.com/boulder-elixir/events/">Boulder Elixir</a><ul><li><a href="https://www.meetup.com/boulder-elixir/events/310996627/"><strong>Integrating Elixir and Apache DataFusion with Rustler</strong></a></li></ul></li><li>2025-11-12 | Virtual (Girona, ES) | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/yhe1xrhe"><strong>Sessió setmanal de codificació / Weekly coding session</strong></a></li></ul></li><li>2025-11-13 | Virtual (Nürnberg, DE) | <a href="https://www.meetup.com/rust-noris/events/">Rust Nuremberg</a><ul><li><a href="https://www.meetup.com/rust-noris/events/310849154/"><strong>Rust Nürnberg online</strong></a></li></ul></li><li>2025-11-16 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/events/">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/311109181/"><strong>Rust Readers Discord Discussion: Macros</strong></a></li></ul></li><li>2025-11-18 | Virtual (Washington, DC, US) | <a href="https://www.meetup.com/rustdc/events/">Rust DC</a><ul><li><a href="https://www.meetup.com/rustdc/events/310002262/"><strong>Mid-month Rustful</strong></a></li></ul></li><li>2025-11-19 | Virtual (Girona, ES) | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/l2xukapz"><strong>Sessió setmanal de codificació / Weekly coding session</strong></a></li></ul></li><li>2025-11-19 | Virtual (Vancouver, BC, CA) | <a href="https://www.meetup.com/vancouver-rust/events/">Vancouver Rust</a><ul><li><a href="https://www.meetup.com/vancouver-rust/events/309926564/"><strong>Rust Study/Hack/Hang-out</strong></a></li></ul></li><li>2025-11-20 | Virtual (Berlin, DE) | <a href="https://www.meetup.com/rust-berlin/events/">Rust Berlin</a><ul><li><a href="https://www.meetup.com/rust-berlin/events/306046642/"><strong>Rust Hack and Learn</strong></a></li></ul></li><li>2025-11-20 | Virtual (Charlottesville, VA, US) | <a href="https://www.meetup.com/charlottesville-rust-meetup/events/">Charlottesville Rust Meetup</a><ul><li><a href="https://www.meetup.com/charlottesville-rust-meetup/events/311705915/"><strong>Tock, a Rust based Operating System Part #1</strong></a></li></ul></li><li>2025-11-23 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/events/">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/311109183/"><strong>Rust Readers Discord Discussion: Macros</strong></a></li></ul></li><li>2025-11-25 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/events/">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/305361446/"><strong>Fourth Tuesday</strong></a></li></ul></li><li>2025-11-25 | Virtual (London, UK) | <a href="https://www.meetup.com/women-in-rust/events/">Women in Rust</a><ul><li><a href="https://www.meetup.com/women-in-rust/events/311534469/"><strong>Data-Intensive Systems in Rust: Safety, Speed, Concurrency</strong></a></li></ul></li><li>2025-11-26 | Virtual (Girona, ES) | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/q5tjirkt"><strong>Sessió setmanal de codificació / Weekly coding session</strong></a></li></ul></li><li>2025-11-30 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/events/">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/311109188/"><strong>Rust Readers Discord Discussion: Macros</strong></a></li></ul></li><li>2025-12-02 | Virtual (London, GB) | <a href="https://www.meetup.com/women-in-rust/events/">Women in Rust</a><ul><li><a href="https://www.meetup.com/women-in-rust/events/311068648/"><strong>Advent of Code - Kick Off!</strong></a></li></ul></li><li>2025-12-03 | Virtual (Buffalo, NY, US) | <a href="https://www.meetup.com/buffalo-rust-meetup/events/">Buffalo Rust Meetup</a><ul><li><a href="https://www.meetup.com/buffalo-rust-meetup/events/305304242/"><strong>Buffalo Rust User Group</strong></a></li></ul></li><li>2025-12-03 | Virtual (Girona, ES) | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/yf2t878c"><strong>Sessió setmanal de codificació / Weekly coding session</strong></a></li></ul></li><li>2025-12-03 | Virtual (Indianapolis, IN, US) | <a href="https://www.meetup.com/indyrs/events/">Indy Rust</a><ul><li><a href="https://www.meetup.com/indyrs/events/wqzhftyhcqbfb/"><strong>Indy.rs - with Social Distancing</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#africa">Africa</a></h5><ul><li>2025-11-11 | Johannesburg, ZA | <a href="https://www.meetup.com/johannesburg-rust-meetup/events/">Johannesburg Rust Meetup</a><ul><li><a href="https://www.meetup.com/johannesburg-rust-meetup/events/311726345/"><strong>More on Rust types</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#asia">Asia</a></h5><ul><li>2025-11-15 | Bangalore, IN | <a href="https://hasgeek.com/rustbangalore">Rust Bangalore</a><ul><li><a href="https://hasgeek.com/rustbangalore/november-2025-rustacean-meetup//"><strong>November 2025 Rustacean meetup</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#europe">Europe</a></h5><ul><li>2025-11-05 | Bergen, NO | <a href="https://www.meetup.com/bergen-html-css-meetup-group/events/">Hubbel kodeklubb</a><ul><li><a href="https://www.meetup.com/bergen-html-css-meetup-group/events/311784113/"><strong>Workshop c# - nr 1 av 2 - grunnleggende nivå</strong></a></li></ul></li><li>2025-11-05 | Girona, ES | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/xl8ob0tn"><strong>Rust Girona Hack &amp; Learn 11 2025</strong></a></li></ul></li><li>2025-11-05 | Köln, DE | <a href="https://www.meetup.com/rust-cologne-bonn/events/">Rust Cologne</a><ul><li><a href="https://www.meetup.com/rustcologne/events/311767026/"><strong>Rust in November: Small Crates Cult</strong></a></li></ul></li><li>2025-11-05 | Oslo, NO | <a href="https://www.meetup.com/rust-oslo">Rust Oslo</a><ul><li><a href="https://www.meetup.com/rust-oslo/events/310601872/"><strong>Rust Hack'n'Learn at Kampen Bistro</strong></a></li></ul></li><li>2025-11-05 | Oxford, UK | <a href="https://www.meetup.com/oxford-rust-meetup-group/events/">Oxford ACCU/Rust Meetup.</a><ul><li><a href="https://www.meetup.com/oxford-rust-meetup-group/events/311569796/"><strong>Halloween special.</strong></a></li></ul></li><li>2025-11-06 | Gdansk, PL | <a href="https://www.meetup.com/rust-gdansk/events/">Rust Gdansk</a><ul><li><a href="https://www.meetup.com/rust-gdansk/events/310924266/"><strong>Rust Gdansk Meetup #11</strong></a></li></ul></li><li>2025-11-06 | Vienna, AT | <a href="https://www.meetup.com/rust-vienna/events/">Rust Vienna</a><ul><li><a href="https://www.meetup.com/rust-vienna/events/311679397/"><strong>Season 2 Kickoff | at metalab 🦀</strong></a></li></ul></li><li>2025-11-07 | Ostrava, CZ | <a href="https://www.meetup.com/techmeetupostrava/events/">TechMeetup Ostrava</a><ul><li><a href="https://www.meetup.com/techmeetupostrava/events/306776025/"><strong>TechMeetup Ostrava Conference</strong></a></li></ul></li><li>2025-11-11 | London, UK | <a href="https://www.meetup.com/rust-london-user-group/events/">Rust London User Group</a><ul><li><a href="https://www.meetup.com/rust-london-user-group/events/311737021/"><strong>Rust London x Zed Meetup</strong></a></li></ul></li><li>2025-11-11 | Stockholm, SE | <a href="https://www.meetup.com/func-prog-sweden/events/">Func Prog Sweden</a><ul><li><a href="https://www.meetup.com/func-prog-sweden/events/308526518/"><strong>Func Prog Sweden 2025 at Kivra</strong></a></li></ul></li><li>2025-11-12 | Cambridge, UK | <a href="https://www.meetup.com/cambridge-rust-meetup/events/">Cambridge Rust Meetup</a><ul><li><a href="https://www.meetup.com/cambridge-rust-meetup/events/311583721/"><strong>Monthly Rust Meetup</strong></a></li></ul></li><li>2025-11-12 | Reading, UK | <a href="https://www.meetup.com/reading-rust-workshop/events/">Reading Rust Workshop</a><ul><li><a href="https://www.meetup.com/reading-rust-workshop/events/308944050/"><strong>Reading Rust Meetup</strong></a></li></ul></li><li>2025-11-13 | Geneva, CH | <a href="https://www.posttenebraslab.ch/wiki/events/monthly_meeting/rust_meetup">Rust Geneva</a><ul><li><a href="https://www.posttenebraslab.ch/wiki/events/monthly_meeting/rust_meetup"><strong>Rust Meetup Geneva</strong></a></li></ul></li><li>2025-11-13 | Paris, FR | <a href="https://www.meetup.com/rust-paris/events/">Rust Paris</a><ul><li><a href="https://www.meetup.com/rust-paris/events/311461594/"><strong>Rust meetup #80</strong></a></li></ul></li><li>2025-11-14 | Stockholm, SE | <a href="https://www.meetup.com/stockholm-rust/events/">Stockholm Rust</a><ul><li><a href="https://www.meetup.com/stockholm-rust/events/311844163/"><strong>Rust Meetup @Magello</strong></a></li></ul></li><li>2025-11-18 | Leipzig, SN, DE | <a href="https://www.meetup.com/rust-modern-systems-programming-in-leipzig/events/">Rust - Modern Systems Programming in Leipzig</a><ul><li><a href="https://www.meetup.com/rust-modern-systems-programming-in-leipzig/events/308592257/"><strong>Topic TBD</strong></a></li></ul></li><li>2025-11-19 | Ostrava, CZ | <a href="https://www.meetup.com/techmeetupostrava/events/">TechMeetup Ostrava</a><ul><li><a href="https://www.meetup.com/techmeetupostrava/events/311581090/"><strong>QA Circle</strong></a></li></ul></li><li>2025-11-20 | Aarhus, DK | <a href="https://www.meetup.com/rust-aarhus/events/">Rust Aarhus</a><ul><li><a href="https://www.meetup.com/rust-aarhus/events/311502123/"><strong>Social Night</strong></a></li></ul></li><li>2025-11-20 | Amsterdam, NL | <a href="https://www.meetup.com/rust-amsterdam-group/events/">Rust Developers Amsterdam Group</a><ul><li><a href="https://www.meetup.com/rust-amsterdam-group/events/311829267/"><strong>Rust Meetup @ Monumental X Zed</strong></a></li></ul></li><li>2025-11-20 | Luzern, CH | [Rust Luzern]((https://www.meetup.com/rust-luzern/)<ul><li><a href="https://www.meetup.com/rust-luzern/events/311410681/"><strong>2025 Rust Talks Luzern #3: Crate Walkthroughs @ Noser Engineering AG</strong></a></li></ul></li><li>2025-11-26 | Bergen, NO | <a href="https://www.meetup.com/bergen-html-css-meetup-group/events/">Hubbel kodeklubb</a><ul><li><a href="https://www.meetup.com/bergen-html-css-meetup-group/events/311784127/"><strong>Workshop c# - nr 2 av 2 - grunnleggende nivå</strong></a></li></ul></li><li>2025-11-26 | Bern, CH | <a href="https://www.meetup.com/rust-bern/events/">Rust Bern</a><ul><li><a href="https://www.meetup.com/rust-bern/events/311792568/"><strong>2025 Rust Talks Bern #5 @Source Engineers</strong></a></li></ul></li><li>2025-11-27 | Barcelona, ES | <a href="https://www.meetup.com/bcnrust/events/">BcnRust</a><ul><li><a href="https://www.meetup.com/bcnrust/events/311787736/"><strong>19th BcnRust Meetup</strong></a></li></ul></li><li>2025-11-27 | Edinburgh, UK | <a href="https://www.meetup.com/rust-edi/events/">Rust and Friends</a><ul><li><a href="https://www.meetup.com/rust-and-friends/events/311753411/"><strong>November Talks: Exotically Sized Types and ...</strong></a></li></ul></li><li>2025-11-28 | Prague, CZ | <a href="https://www.meetup.com/rust-prague/events/">Rust Prague</a><ul><li><a href="https://www.meetup.com/rust-prague/events/311846118/"><strong>Rust Meetup Prague @ Barclays</strong></a></li></ul></li><li>2025-12-03 | Oxford, UK | <a href="https://www.meetup.com/oxford-rust-meetup-group/events/">Oxford ACCU/Rust Meetup.</a><ul><li><a href="https://www.meetup.com/oxford-rust-meetup-group/events/nnrkttyhcqbfb/"><strong>Rust/ACCU meetup.</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#north-america">North America</a></h5><ul><li>2025-11-06 | Montréal, QC, CA | <a href="https://www.meetup.com/rust-montreal/events/">Rust Montréal</a><ul><li><a href="https://www.meetup.com/rust-montreal/events/311762040/"><strong>November Monthly Social</strong></a></li></ul></li><li>2025-11-06 | Saint Louis, MO, US | <a href="https://www.meetup.com/stl-rust/events/">STL Rust</a><ul><li><a href="https://www.meetup.com/stl-rust/events/307251982/"><strong>Surprise</strong></a></li></ul></li><li>2025-11-08 | Boston, MA, US | <a href="https://www.meetup.com/bostonrust/events/">Boston Rust Meetup</a><ul><li><a href="https://www.meetup.com/bostonrust/events/311039501/"><strong>Winter Hill Rust Lunch, Nov 8</strong></a></li></ul></li><li>2025-11-13 | Lehi, UT, US | <a href="https://www.meetup.com/utah-rust/events/">Utah Rust</a><ul><li><a href="https://www.meetup.com/utah-rust/events/311613658/"><strong>Ipmap: Building Desktop Apps with Tauri</strong></a></li></ul></li><li>2025-11-18 | San Francisco, CA, US | <a href="https://www.meetup.com/san-francisco-rust-study-group/events/">San Francisco Rust Study Group</a><ul><li><a href="https://www.meetup.com/san-francisco-rust-study-group/events/308865806/"><strong>Rust Hacking in Person</strong></a></li></ul></li><li>2025-11-20 | Seattle, WA, US | <a href="https://www.meetup.com/join-srug/events/">Seattle Rust User Group</a><ul><li><a href="https://www.meetup.com/seattle-rust-user-group/events/311351673/"><strong>November, 2025 SRUG (Seattle Rust User Group) Meetup</strong></a></li></ul></li><li>2025-11-20 | Spokane, WA, US | <a href="https://www.meetup.com/spokane-rust/events/">Spokane Rust</a><ul><li><a href="https://www.meetup.com/spokane-rust/events/311863560/"><strong>Monthly Rust Meetup: November</strong></a></li></ul></li><li>2025-11-26 | Austin, TX, US | <a href="https://www.meetup.com/rust-atx/events/">Rust ATX</a><ul><li><a href="https://www.meetup.com/rust-atx/events/310457310/"><strong>Rust Lunch - Fareground</strong></a></li></ul></li><li>2025-12-02 | Chicago, IL, US | <a href="https://www.meetup.com/chicago-rust-meetup/events/">Chicago Rust Meetup</a><ul><li><a href="https://www.meetup.com/chicago-rust-meetup/events/311736848/"><strong>Rust Talk December</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#oceania">Oceania</a></h5><ul><li>2025-11-11 | Christchurch, NZ | <a href="https://www.meetup.com/christchurch-rustlang-meetup-group/events/">Christchurch Rust Meetup Group</a><ul><li><a href="https://www.meetup.com/christchurch-rustlang-meetup-group/events/311685331/"><strong>Christchurch Rust Meetup</strong></a></li></ul></li></ul><p>If you are running a Rust event please add it to the <a href="https://www.google.com/calendar/embed?src=apd9vmbc22egenmtu5l6c5jbfc%40group.calendar.google.com">calendar</a> to getit mentioned here. Please remember to add a link to the event too.Email the <a href="mailto:community-team@rust-lang.org">Rust Community Team</a> for access.</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#jobs">Jobs</a></h4><p>Please see the latest <a href="https://www.reddit.com/r/rust/comments/1nknaii/official_rrust_whos_hiring_thread_for_jobseekers/">Who's Hiring thread on r/rust</a></p><h3><a class="toclink" href="http://this-week-in-rust.org/atom.xml#quote-of-the-week">Quote of the Week</a></h3><blockquote><p>If someone opens a PR introducing C++ to your Rust project, that code is free as in "use after"</p></blockquote><p>– <a href="https://hachyderm.io/@predrag/115475147692306391">Predrag Gruevski on Mastodon</a></p><p>Thanks to <a href="https://users.rust-lang.org/t/twir-quote-of-the-week/328/1726">Brett Witty</a> for the suggestion!</p><p><a href="https://users.rust-lang.org/t/twir-quote-of-the-week/328">Please submit quotes and vote for next week!</a></p><p>This Week in Rust is edited by:</p><ul><li><a href="https://github.com/nellshamrell">nellshamrell</a></li><li><a href="https://github.com/llogiq">llogiq</a></li><li><a href="https://github.com/ericseppanen">ericseppanen</a></li><li><a href="https://github.com/extrawurst">extrawurst</a></li><li><a href="https://github.com/U007D">U007D</a></li><li><a href="https://github.com/mariannegoldin">mariannegoldin</a></li><li><a href="https://github.com/bdillo">bdillo</a></li><li><a href="https://github.com/opeolluwa">opeolluwa</a></li><li><a href="https://github.com/bnchi">bnchi</a></li><li><a href="https://github.com/KannanPalani57">KannanPalani57</a></li><li><a href="https://github.com/tzilist">tzilist</a></li></ul><p><em>Email list hosting is sponsored by <a href="https://foundation.rust-lang.org/">The Rust Foundation</a></em></p><p><small><a href="https://www.reddit.com/r/rust/comments/1optr5g/this_week_in_rust_624/">Discuss on r/rust</a></small></p></description> <pubDate>Wed, 05 Nov 2025 05:00:00 +0000</pubDate> <dc:creator>TWiR Contributors</dc:creator></item><item> <title>Firefox Add-on Reviews: Supercharge your productivity with a Firefox extension</title> <guid isPermaLink="true">https://addons.mozilla.org/blog/supercharge-your-productivity-with-a-browser-extension/</guid> <link>https://addons.mozilla.org/blog/supercharge-your-productivity-with-a-browser-extension/</link> <description><p>With more work and education happening online you may find yourself needing new ways to juice your productivity. From time management to organizational tools and more, the right Firefox extension can give you an edge in the art of efficiency. </p> <h3><strong><em>I need help saving and organizing a lot of web content </em></strong></h3> <h4><strong>Raindrop.io</strong></h4> <p>Organize anything you find on the web with <a href="https://addons.mozilla.org/firefox/addon/raindropio/" rel="noreferrer noopener">Raindrop.io</a> — news articles, videos, PDFs, and more. </p> <div class="addon-card"></div> <p>Raindrop.io makes it simple to gather clipped web content by subject matter and organize with ease by applying tags, filters, and in-app search. This extension is perfectly suited for projects that require gathering and organizing lots of mixed media.</p> <h4><strong>Gyazo</strong></h4> <p>Capture, save, and share anything you find on the web. <a href="https://addons.mozilla.org/firefox/addon/gyazo-official/" rel="noreferrer noopener">Gyazo</a> is a great tool for personal or collaborative record keeping and research. </p> <div class="addon-card"></div> <p>Clip entire pages or just pertinent portions. Save images or take screenshots. Gyazo makes it easy to perform any type of web clipping action by either right-clicking on the page element you want to save or using the extension’s toolbar button. Everything gets saved to your Gyazo account, making it accessible across devices and collaborative teams. </p> <p>On your Gyazo homepage you can easily browse and sort everything you’ve clipped; and organize it all into shareable topics or collections. </p> <figure class="wp-block-image size-large"><img alt="" class="wp-image-210" height="757" src="https://mozamo.wpengine.com/wp-content/uploads/2021/07/blog_prod_gyoza-1024x757.jpg" width="1024" />&lt;figcaption class="wp-element-caption"&gt;With its minimalist pop-up interface, Gyazo makes it easy to clip elements, sections, or entire web pages. &lt;/figcaption&gt;</figure> <h4><strong>Evernote Web Clipper</strong></h4> <p>Similar to Gyazo and Raindrop.io, <a href="https://addons.mozilla.org/firefox/addon/evernote-web-clipper/" rel="noreferrer noopener">Evernote Web Clipper</a> offers a kindred feature set — clip, save, and share web content — albeit with some nice user interface distinctions. </p> <div class="addon-card"></div> <p>Evernote makes it easy to annotate images and articles for collaborative projects. It also has a strong internal search feature, allowing you to look for specific words and phrases that might appear across scattered collections of clipped content. Evernote also automatically strips out ads and social widgets on your saved pages. </p> <h4><strong>Notefox</strong></h4> <p>Wouldn’t it be great if you could leave yourself little sticky notes anywhere you wanted around the web? Well now you can with <a href="https://addons.mozilla.org/firefox/addon/websites-notes/" rel="noreferrer noopener">Notefox</a>.</p> <div class="addon-card"></div> <p>Leave notes on specific web pages or entire domains. You can access all your notes from a central repository so everything is easy to find. The extension also includes a helpful auto-save feature so you’ll never lose a note.</p> <h4><strong>Print Edit WE</strong></h4> <p>If you need to save or print an important web page — but it’s mucked up with a bunch of unnecessary clutter like ads, sidebars, and other peripheral distractions — <a href="https://addons.mozilla.org/firefox/addon/print-edit-we/">Print Edit WE</a> lets you easily remove those unwanted elements.</p> <div class="addon-card"></div> <p>Along with a host of great features like the option to save web pages as either HTML or PDF files, automatically delete graphics, and the ability to alter text or add notes, Print Edit WE also provides an array of productivity optimizations like keyboard shortcuts and mouse gestures. This is the ideal productivity extension for any type of work steeped in web research and cataloging.</p> <h3><em>Focus! Focus! Focus!</em></h3> <p>Anti-distraction and decluttering extensions can provide a major boon for online workers and students… </p> <h4>Block Site </h4> <p>Do you struggle avoiding certain time-wasting, productivity-sucking websites? With <a href="https://addons.mozilla.org/firefox/addon/block-website/" rel="noreferrer noopener">Block Site</a> you can enforce restrictions on sites that tempt you away from good work habits. </p> <div class="addon-card"></div> <p>Just list the websites you want to avoid for specified periods of time (certain hours of the day or some days entirely) and Block Site won’t let you access them until you’re out of the focus zone. There’s also a fun redirection feature where you’re automatically redirected to a more productive website anytime you try to visit a time waster. </p> <figure class="wp-block-image size-large"><img alt="" class="wp-image-208" height="746" src="https://mozamo.wpengine.com/wp-content/uploads/2021/07/blog_prod_blocksite-1024x746.jpg" width="1024" />&lt;figcaption class="wp-element-caption"&gt;Give yourself a custom message of encouragement (or scolding?) whenever you try to visit a restricted site with Block Site.&lt;/figcaption&gt;</figure> <h4>LeechBlock NG</h4> <p>Very similar in function to Block Site, <a href="https://addons.mozilla.org/firefox/addon/leechblock-ng/" rel="noreferrer noopener">LeechBlock NG</a> offers a few intriguing twists beyond standard site-blocking features. </p> <div class="addon-card"></div> <p>In addition to blocking sites during specified times, LeechBlock NG offers an array of granular, website-specific blocking abilities — like blocking just portions of websites (e.g. you can’t access the YouTube homepage but you can see video pages) to setting restrictions on predetermined days (e.g. no Twitter on weekends) to 60-second delayed access to certain websites to give you time to reconsider that potential productivity killing decision. </p> <h4>Tomato Clock</h4> <p>A simple but highly effective time management tool, <a href="https://addons.mozilla.org/firefox/addon/tomato-clock/" rel="noreferrer noopener">Tomato Clock</a> (based on the <a href="https://www.themuse.com/advice/take-it-from-someone-who-hates-productivity-hacksthe-pomodoro-technique-actually-works/" rel="noreferrer noopener">Pomodoro technique</a>) helps you stay on task by tracking short, focused work intervals. </p> <div class="addon-card"></div> <p>The premise is simple: it assumes everyone’s productive attention span is limited, so break up your work into manageable “tomato” chunks. Let’s say you work best in 40-minute bursts. Set Tomato Clock and your browser will notify you when it’s break time (which is also time customizable). It’s a great way to stay focused via short sprints of productivity. The extension also keeps track of your completed tomato intervals so you can track your achieved results over time.</p> <h4>Time Tracker</h4> <p>See how much time you spend on every website you visit. <a href="https://addons.mozilla.org/firefox/addon/besttimetracker/" rel="noreferrer noopener">Time Tracker</a> provides a granular view of your web habits.</p> <div class="addon-card"></div> <p>If you find you’re spending too much time on certain websites, Time Tracker offers a block site feature to break the bad habit.</p> <h4>Tabby – Window &amp; Tab Manager</h4> <p>Are you overwhelmed by lots of open tabs and windows? Need an easy way to overcome desktop chaos? <a href="https://addons.mozilla.org/firefox/addon/tabby-window-tab-manager/">Tabby – Window &amp; Tab Manager</a> to the rescue.</p> <div class="addon-card"></div> <p>Regain control of your ever-sprawling open tabs and windows with an extension that lets you quickly reorganize everything. Tabby makes it easy to find what you need in a chaotic sea of open tabs — you can word/phrase search for what you’re looking for, of use Tabby’s visual preview feature to see little thumbnail images of your open tabs without actually navigating to them. And whenever you need a clean slate but want to save your work, you can save and close all of your open tabs with a single mouse click and return to them later.</p> <figure class="wp-block-image size-large"><img alt="" class="wp-image-352" height="623" src="https://mozamo.wpengine.com/wp-content/uploads/2021/07/blog_Tabby-1-1024x623.png" width="1024" />&lt;figcaption class="wp-element-caption"&gt;Access all of Tabby’s features in one convenient pop-up. &lt;/figcaption&gt;</figure> <h4>Tranquility Reader</h4> <p>Imagine a world wide web where everything but the words are stripped away — no more distracting images, ads, tempting links to related stories, nothing — just the words you’re there to read. That’s <a href="https://addons.mozilla.org/firefox/addon/tranquility-1/" rel="noreferrer noopener">Tranquility Reader</a>. </p> <div class="addon-card"></div> <p>Simply hit the toolbar button and instantly streamline any web page. Tranquility Reader offers quite a few other nifty features as well, like the ability to save content offline for later, customizable font size and colors, add annotations to saved pages, and more. </p> <h4><strong>Checker Plus for Gmail</strong></h4> <p>Stop wasting time bouncing between the web and your Gmail app. <a href="https://addons.mozilla.org/firefox/addon/checker-plus-gmail/" rel="noreferrer noopener">Checker Plus for Gmail</a> puts your inbox and more right into Firefox’s toolbar so it’s with you wherever you go on the internet. </p> <div class="addon-card"></div> <p>See email notifications, read, reply, delete, mark as ‘read’ and more — all within a convenient browser pop-up. </p> <p>We hope some of these great extensions will give your productivity a serious boost! Fact is there are a vast number of extensions that can help with productivity — everything from ways to <a href="https://addons.mozilla.org/blog/too-many-open-tabs-extensions-to-the-rescue/" rel="noreferrer noopener">organize tons of open tabs</a> to <a href="https://addons.mozilla.org/blog/translate-the-web-easily-with-a-browser-extension/" rel="noreferrer noopener">translation tools</a> to <a href="https://addons.mozilla.org/firefox/extensions/category/bookmarks/" rel="noreferrer noopener">bookmark managers</a> and more. </p></description> <pubDate>Tue, 04 Nov 2025 01:42:25 +0000</pubDate> <dc:creator>Scott DeVaney</dc:creator></item><item> <title>Chris H-C: Ten-Year Moziversary</title> <guid isPermaLink="false">http://chuttenblog.wordpress.com/?p=6507</guid> <link>https://chuttenblog.wordpress.com/2025/11/03/ten-year-moziversary/</link> <description><p>I’m a few days late publishing this, but this October marks the tenth anniversary of my first day working at Mozilla. I’m on my third hardware refresh (a Dell XPS which I can’t recommend), still just my third CEO, and now <a href="https://arewereorganizedyet.com/">68 reorgs in</a>.</p> <p>For something as momentous as breaking into two-digit territory, there’s not really much that’s different from <a href="https://chuttenblog.wordpress.com/2024/10/18/nine-year-moziversary/">last year</a>. I’m still trying to get Firefox Desktop to use Glean instead of Legacy Telemetry and I’m still not blogging nearly as much as I’d like. Though, I did get promoted earlier this year. I am now a Senior Staff Software Engineer, which means I’m continuing on the journey of doing fewer things myself and instead empowering other people to do things.</p> <p>As for predictions, I was spot on about FOG Migration actually taking off a little — in fact, quite a lot. All data collection in Firefox Desktop now either passes through Glean to get to Legacy Telemetry, has Glean mirroring alongside it, or has been removed. This is in large part thanks to a big help from Florian Quèze and his willingness to stop asking when we could start and just <a href="https://arewegleanyet.com/">migrate the codebase</a>. Now we’re working on moving the business data calculations onto Glean-sent data, and getting individual teams to change over too. If you’re reading this and were looking for an excuse to remove Legacy Telemetry from your component, <a href="https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/start/remove-telemetry.html">this is your excuse</a>.</p> <p>My prediction that there’d be an All Hands was wrong. Mozilla Leadership has decided that the US is neither a place they want to force people to travel to nor is it a place they want to force people to travel out of (and then need to attempt to return to) in the current political climate. This means that business gatherings of any size are… complicated. Some teams have had simultaneous summits in cities both within and without the US. Some teams have had one or the other side call in virtually from their usual places of work. And our team… well, we’ve not gathered at all. Which is a bummer, since we’ve had a few shuffles in the ranks and it’d be good to get us all in one place. (I will be in Toronto with some fellow senior Data Engineering folks before the end of the year, but that’s the extent of work travel.) I’m broadly in favour of removing the requirement and expectation of travel over the US border — too many people have been disappeared in too many ways. We don’t want to make anyone feel as though they have to risk it. But it seems as though we’re also leaning away from allowing people to risk it if they want to, which is a level of paternalism that I didn’t want to see.</p> <p>I did have one piece of “work” travel in that I attended CSV Conf in Bologna, Italy. Finally spent my Professional Development budget, and wow what a great investment. I learned so much and had a great time, and that was despite the heat and humidity (goodness, Italy. I was in your North (ish). In September. Why you gotta 30degC me like this?). I’m on the lookout for other great conferences to attend in 2026, so if you know any, get in touch.</p> <p>My prediction that I’d still be three CEOs in because the search for a new one wouldn’t have completed by now: spot on. Ditto on executing my hardware refresh, though I’m still using a personal monitor at work. I should do something about that.</p> <p>My prediction that we’d stop putting AI in everything has partially come true. There’s been a noticeable shift away from “Put genAI in it and find a problem for it to (maybe) solve” towards “If you find a problem that genAI can help with, give it a try.” You wouldn’t notice it, necessarily, looking at feature announcements for Firefox, as quite a lot of the integration infrastructure all landed in the past couple of months, making headlines. My feelings on LLMs and genAI have gained layers and nuance since last year. They’re still plagiarism machines that are illegally built by the absolute worst people in ways that worsen the climate catastrophe and entrench existing inequalities. But now they’ve apparently become actually useful in some ways. I’ve read reports from very senior developers about use cases that LLMs have been able to assist with. They are narrow use cases — you must only use it to work on components you understand well, you must only use it on tasks you would do yourself if you had the time and energy — but they’re real. And that means my usual hard line of “And even if you ignore the moral, ethical, environmental, economic, and industry concerns about using LLMs: they don’t even work” no longer applies. And in situations like a for-profit corporation lead by people from industry… ignoring the moral, ethical, environmental, economic, and industry concerns is de rigeur.</p> <p>Add these to the sorta-kinda-okay things LLMs can do like natural language processing and aiding in training and refinement of machine translation models, and it looks as though we’re figuring out the “reheat the leftovers” and “melt butter and chocolate” use cases for <a href="https://www.colincornaby.me/2025/08/in-the-future-all-food-will-be-cooked-in-a-microwave-and-if-you-cant-deal-with-that-then-you-need-to-get-out-of-the-kitchen/">these microwave ovens</a>.</p> <p>It still remains to be seen if, after the bubble pops, these nuclear-powered lake-draining art-stealing microwaves will find a home in many kitchens. I expect the fully-burdened cost will be awfully prohibitive for individuals who just want it to poorly regurgitate Wikipedia articles in a chat interface. It might even be too spicy for enterprises who think (likely erroneously) that they confer some instantaneous and generous productivity multiplier. Who knows.</p> <p>All I know is that I still don’t like it. But I’ll likely find myself using one before the end of the year. If so, I intend to write up the experience and hopefully address my blogging drought by publishing it here.</p> <p>Another thing that happened this year that I alluded to in last year’s post was the Google v DOJ ruling in the US. Well, the first two rulings anyway. Still years of appeal to come, but even the existing level of court seemed to agree that the business model that allows Mozilla to receive a bucketload of dollabux from Google for search engine placement in Firefox (aka, <a href="https://chuttenblog.wordpress.com/2015/11/25/how-mozilla-pays-me/">the thing that supplies most of my paycheque</a>) should not be illegal at this time. Which is a bit of a relief. One existential threat to the business down… for now.</p> <p>But mostly? This year has been feeling a little like 2016 again. Instead of The Internet of Things (IoT, where the S stands for Security), it’s genAI. Instead of Mexico and Muslims it’s Antifa and Trans people. The Jays are in the postseason again. Shit’s fucked and getting worse. But in all that, someone still has to rake the leaves and wash the dishes. And if I don’t do it, it won’t get done.</p> <p>With that bright spot highlighted, what are my predictions for the new year:</p> <ul class="wp-block-list"><li>I will requisition a second work monitor so I stop using personal hardware for work things.</li> <li>FOG Migration (aka the Instrumentation Consolidation Project) will not fully remove all of Legacy Telemetry by this time next year. There’s evidence of cold feet on the “change business metrics to Glean-sent data” front, and even if there weren’t, there’s such a long tail that there’s no doubt something load-bearing that’d delay things to Q4 2025. I _am_ however predicting that FOG Migration will no longer being all-encompassing work — I will have a chance to do something else with my time.</li> <li>I predict that one of the things I will do with that extra time is, since MoCo insists on a user population measurement KPI, push for a sensible user population measurement. Measuring the size of the user population by counting distinct _profiles_ we’ve _received_ a data packet from on a day (not that the data was collected on that day)? We can do better.</li> <li>I don’t think there’s going to be an All Hands next year. If there is, I’d expect it to be Summit style: multiple cities simultaneously, with video links. Fingers crossed for Toronto finally getting its chance. Though I suppose if the people of the US rose up and took back their country, or if the current President should die, that could change the odds a little. Other US administrations saw the benefit of freedom of movement, regardless of which side of the aisle.</li> <li>Maybe the genAI bubble will have burst? Timing these things is impossible, even if it weren’t the first time in history that this much of the US’ (and world’s) economy is inflating it. The sooner it bursts, the better, as it’s only getting bigger. (I suppose an alternative would be for the next shiny thing to happen along and the interest in genAI to dwindle more slowly with no single burst, just a bunch of crashes. Like blockchain/web3/etc. In that case a slower diminishing would be better than a sooner burst.)</li> <li>I predict that a new MoCo CEO will have been found, but not yet sworn in by this time next year. I have no basis for this prediction: vibes only.</li></ul> <p>To another year of supporting <a href="https://www.mozilla.org/mission/">the Mission</a>!</p> <p>:chutten</p></description> <pubDate>Mon, 03 Nov 2025 21:47:32 +0000</pubDate> <dc:creator>chuttenc</dc:creator></item><item> <title>Mozilla Localization (L10N): L10n Report: November Edition 2025</title> <guid isPermaLink="false">https://blog.mozilla.org/l10n/?p=1796</guid> <link>https://blog.mozilla.org/l10n/2025/11/03/l10n-report-november-edition-2025/</link> <description><p><i>Please note some of the information provided in this report may be subject to change as we are sometimes sharing information about projects that are still in early stages and are not final yet. </i></p><h3>Welcome!</h3><h3>What’s new or coming up in Firefox desktop</h3><h4>Firefox Backup</h4><p>Firefox backup is a new feature being introduced in Firefox 145, currently testable in Beta and Nightly behind a preference flag. See <a href="https://docs.google.com/document/d/e/2PACX-1vTkMmsafMbb5G139lbeE55YhgKYT1NJkFO7M1_VOp1awNdWQyExIHWYSzJ6IlIyt_20k9uV2zNCON76/pub">here</a> for instructions on how to test this feature.</p><p>This feature allows users to save a backup of their Firefox data to their local device at regular intervals, and later use that backup to restore their browser data or migrate their browser to a new device. One of the use cases is for current Windows 10 users who may be migrating to a new Windows 11 device. The user can save their Firefox backup to OneDrive, and later after setting up their new device can then install Firefox and restore their browsing data from the backup saved in OneDrive.</p><p>This is an alternative to using the sync functionality in combination with a Mozilla account.</p><h4>Settings Redesign</h4><p>Coming up in future releases, the current settings menu is being re-organized and re-designed to be more user friendly and easier to understand. New strings will be rolling out with relative frequency, but they can’t be viewed or tested in Beta or Nightly yet. If you encounter anything where you need additional context, please feel free to use the request context button in Pontoon or drop into our <a href="https://chat.mozilla.org/#/room/#l10n-community:mozilla.org">localization matrix channel</a> where you can get the latest updates and engage with your fellow localizers from around the world.</p><h3>What’s new or coming up in mobile</h3><p>Here’s what’s been going on in Firefox for Android land lately: you may have noticed strings landing for the Toolbar refresh, the tab tray layout, as well as for a homepage revamp. All of this is work is ongoing, so expect to see more strings landing soon!</p><p>On the Firefox for iOS side, there have been improvements to Search along with a revamp of the menu and tab tray. Ongoing work continues on the Translations feature integration, the homepage revamp, and the toolbar refresh.</p><p>More updates coming soon — stay tuned!</p><h3>What’s new or coming up in web projects</h3><h4>AMO and AMO Frontend</h4><p>The team has been working on identifying and removing obsolete strings to minimize unnecessary translation effort especially the locales that are still catching on. Recently they removed an additional 160 or so strings.</p><p>To remain in production, a locale must have both projects at or above 80% completion. If only one project meets the threshold, neither will be enabled. This policy helps prevent users from unintentionally switching between their preferred language and English. Please review your locale to confirm both projects are localized and in good standing.</p><p>If a locale already in production falls below the threshold, the team will be notified. Each month, they will review the status of all locales and manually add or remove them from production as needed.</p><h4>Mozilla accounts</h4><p>The Mozilla accounts team has been working on the ability to customize surfaces for the various projects that rely on Mozilla accounts for account management such as sync, Mozilla VPN, and others. This customization applies only to a predetermined set of pages (such as sign-in, authentication, etc.) and emails (sign-up confirmation, sign-in verification code, etc.) and is managed through a content management system. This CMS process bypasses the typical build process and as a result changes are shown in production within a very short time-frame (within minutes). Each customization requires an instance of a string, even if that value hasn’t changed, so this can result in a large number of identical strings being created.</p><p>This project will be managed in a new “Mozilla accounts CMS” project within Pontoon instead of the main “Mozilla accounts” project. We are doing this for a couple reasons:</p><ul><li><b>To reduce or eliminate the need to translate duplicate strings</b>: In most cases it’s best to have different strings to allow for translation adjustments depending on context, however due to the nature of this project, identical strings for the same page element (e.g. “button”) will use a single translation. For example, all buttons with the text “Sign in” will only require a single translation. This has reduced the number of strings requiring translation by over 50% already, and will reduce the number of additional strings in the future.</li><li><b>To enable pretranslation:</b> <i>Important note – this only applies to locales that have opted-in to the pretranslation feature.</i> Due to the CMS string process skipping the normal build cycle and being exposed to production near instantaneously, there’s a high likelihood that untranslated strings may be shown in English before teams have the chance to translate. If a locale has opted in for <a href="https://blog.mozilla.org/l10n/2024/02/07/a-deep-dive-into-the-evolution-of-pretranslation-in-pontoon/">pretranslation</a>, then the “Mozilla accounts CMS” project will have pretranslation enabled by default and show pretranslated strings until the team has a chance to review and update strings. If your locale has decided not to use the pretranslation feature, then nothing will change and translated strings will be displayed once your team has them translated and approved in Pontoon.</li></ul><h3>Newly published localizer facing documentation</h3><p>We’ve recently updated our testing instructions for <a href="https://mozilla-l10n.github.io/localizer-documentation/products/firefox_android/testing.html">Firefox for Android</a> and for <a href="https://mozilla-l10n.github.io/localizer-documentation/products/firefox_ios/testing.html#testing-with-screenshots">Firefox for iOS</a>! If you spot anything that could be improved, please <a href="https://github.com/mozilla-l10n/localizer-documentation/issues/new">file an issue</a> — we’d love your feedback.</p><h3>Friends of the Lion</h3><div class="wp-caption alignright" id="attachment_1131" style="width: 262px;"><img alt="" class="wp-image-1131 size-medium" height="232" src="https://blog.mozilla.org/l10n/files/2017/07/2-Lions-01-252x232.png" width="252" /><p class="wp-caption-text" id="caption-attachment-1131">Image by Elio Qoshi</p></div><ul><li>We’ve started a new blog series spotlighting amazing contributors from Mozilla’s localization community. The first one features <a href="https://blog.mozilla.org/l10n/2025/09/30/localizer-spotlight-selim/">Selim of the Turkish community</a>.</li><li>A second localizer spotlight was published! This time, <a href="https://blog.mozilla.org/l10n/2025/10/24/localizer-spotlight-bogo/">meet Bogo</a>, a long-time contributor to Bulgarian projects.</li></ul><p>Want to learn more from your fellow contributors? Who would you like to be featured? You are invited to <a href="https://survey.alchemer.com/s3/8493108/Nominate-the-Next-Featured-Localizer">nominate the next candidate</a>!</p><p>Know someone in your l10n community who’s been doing a great job and should appear here? <a href="mailto:l10n-drivers@mozilla.org">Contact us</a> and we’ll make sure they get a shout-out!</p><h3>Questions? Want to get involved?</h3><p>If you want to get involved, or have any question about l10n, reach out to:</p><ul><li><a href="https://pontoon.mozilla.org/contributors/mZuzEFP7EcmgBBTbvtgJP2LFFTY/">Francesco Lodolo (flod)</a> – Engineering Manager</li><li><a href="https://pontoon.mozilla.org/contributors/CMLZ_n1lNNSfQScLGE2yBmlS55w/">Bryan</a> – L10n Project Manager</li><li><a href="https://pontoon.mozilla.org/contributors/3LPn77ppB_IQ9F6ruL5lw2IVrvQ/">Delphine</a> – L10n Project Manager for mobile</li><li><a href="https://pontoon.mozilla.org/contributors/jIdunhnZ8Edgi9npILuSoFvf5ZY/">Peiying (CocoMo)</a> – L10n Project Manager for mozilla.org, marketing, and legal</li><li><a href="https://pontoon.mozilla.org/contributors/m6r3HOfoijMdyeJNKKFHchjjRbw/">Francis</a> – L10n Project Manager for Common Voice, Mozilla Foundation</li><li><a href="https://pontoon.mozilla.org/contributors/lY_FTvtnYcVoDP7JYZjMsm6tRno/">Théo Chevalier</a> – L10n Project Manager for Mozilla Foundation</li><li><a href="https://pontoon.mozilla.org/contributors/9rSAS6h8LlBD9DQQtHgdCwvVen0/">Kiki</a> – L10n Project Manager for SUMO</li><li><a href="https://pontoon.mozilla.org/contributors/dvgiVCmoeidF2xcqSnBHtpzLTFU/">Matjaž (mathjazz)</a> – Pontoon dev</li><li><a href="https://pontoon.mozilla.org/contributors/pmz0uSCe_Mk9Td1cksHLI1y471k/">Eemeli</a> – Pontoon, Fluent dev</li></ul><p>Did you enjoy reading this report? <a href="mailto:l10n-drivers@mozilla.org">Let us know</a> how we can improve it.</p></description> <pubDate>Mon, 03 Nov 2025 20:07:07 +0000</pubDate> <dc:creator>Bryan Olsson</dc:creator></item><item> <title>Mozilla Privacy Blog: Pathways to a fairer digital world: Mozilla shares views on the EU Digital Fairness Act</title> <guid isPermaLink="false">https://blog.mozilla.org/netpolicy/?p=2517</guid> <link>https://blog.mozilla.org/netpolicy/2025/10/31/pathways-to-a-fairer-digital-world-mozilla-shares-views-on-the-eu-digital-fairness-act/</link> <description><p>The <b>Digital Fairness Act (DFA)</b> is a defining opportunity to modernise Europe’s consumer protection framework for the digital age. Mozilla welcomes the European Commission’s ambition to ensure that digital environments are fair, open, and respecting of user autonomy.</p><p>As online environments are increasingly shaped by <b>manipulative design, pervasive personalization, and emerging AI systems</b>, traditional transparency and consent mechanisms are no longer sufficient. The DFA must therefore address how digital systems are designed and operated – from interface choices to system-level defaults and AI-mediated decision-making.</p><p>Mozilla believes the DFA, if designed in a smart way, will complement existing legislation (such as GDPR, DSA, DMA, AI Act) by closing long-recognized legal and enforcement gaps. When properly scoped, the DFA can <b>simplify</b> the regulatory landscape, <b>reduce fragmentation,</b> and <b>enhance legal certainty</b> for innovators, while also enabling consumers to exercise their choices online and bolster overall consumer protection. Ensuring effective consumer choice is at the heart of contestable markets, encouraging innovation and new entry.</p><p><b>Policy recommendations</b></p><p><b>1. Recognize and outlaw harmful design practices at the interface and system levels.</b></p><ul><li>Update existing rules to ensure that manipulative and deceptive patterns at both interface and system architecture levels<strong> are explicitly banned</strong>.</li><li>Extend protection beyond “dark patterns” to <strong>include AI-driven and agentic systems</strong> that steer users toward outcomes they did not freely choose.</li><li>Introduce <strong>anti-circumvention and burden-shifting provisions</strong> requiring platforms to demonstrate the fairness of their design and user-interaction systems.</li><li><strong>Harmonize key definitions and obligations</strong> across the different legislative instruments within consumer, competition, and data protection law.</li></ul><p><b>2. Establish substantive fairness standards for personalization and online advertising.</b></p><ul><li><b>Prohibit exploitative or manipulative personalization</b> based on sensitive data or vulnerabilities.</li><li>Guarantee <b>simple, meaningful opt-outs</b> that do not degrade service quality.</li><li>Require the use of <b>privacy-preserving technologies (PETs)</b> and data minimisation by design in all personalization systems.</li><li>Mandate <b>regular audits</b> to assess fairness and detect systemic bias or manipulation across the ad-tech chain.</li></ul><p><b>3. Strengthen centralized enforcement and cooperation across regulators. </b></p><ul><li>Adopt the DFA as a Regulation and introduce <strong>centralized enforcement to ensure consistent application</strong> across Member States.</li><li>Create formal mechanisms for <strong>cross-regulator coordination</strong> among consumer, data protection, and competition authorities.</li><li><strong>Update the “average consumer” standard</strong> to reflect real behavioral dynamics online, ensuring protection for all users, not just the hypothetical rational actor.</li></ul><p>A strong, harmonized DFA would modernize Europe’s consumer protection architecture, strengthen trust, and promote a fairer, more competitive digital economy. By closing long-recognized legal gaps, it would reinforce genuine user choice, simplify compliance, enhance legal certainty, and support responsible innovation.</p><p>You can read our position in more detail <a href="https://blog.mozilla.org/netpolicy/files/2025/10/Digital-Fairness-Act_Consultation-submission.pdf">here</a>.</p><p>The post <a href="https://blog.mozilla.org/netpolicy/2025/10/31/pathways-to-a-fairer-digital-world-mozilla-shares-views-on-the-eu-digital-fairness-act/">Pathways to a fairer digital world: Mozilla shares views on the EU Digital Fairness Act</a> appeared first on <a href="https://blog.mozilla.org/netpolicy">Open Policy &amp; Advocacy</a>.</p></description> <pubDate>Fri, 31 Oct 2025 12:54:11 +0000</pubDate> <dc:creator>Tasos Stampelos</dc:creator></item><item> <title>The Rust Programming Language Blog: Announcing Rust 1.91.0</title> <guid isPermaLink="true">https://blog.rust-lang.org/2025/10/30/Rust-1.91.0/</guid> <link>https://blog.rust-lang.org/2025/10/30/Rust-1.91.0/</link> <description><p>The Rust team is happy to announce a new version of Rust, 1.91.0. Rust is a programming language empowering everyone to build reliable and efficient software.</p><p>If you have a previous version of Rust installed via <code>rustup</code>, you can get 1.91.0 with:</p><pre class="language-console z-code"><code class="language-console"><span class="z-text z-plain">$ rustup update stable</span></code></pre><p>If you don't have it already, you can <a href="https://www.rust-lang.org/install.html">get <code>rustup</code></a> from the appropriate page on our website, and check out the <a href="https://doc.rust-lang.org/stable/releases.html#version-1910-2025-10-30">detailed release notes for 1.91.0</a>.</p><p>If you'd like to help us out by testing future releases, you might consider updating locally to use the beta channel (<code>rustup default beta</code>) or the nightly channel (<code>rustup default nightly</code>). Please <a href="https://github.com/rust-lang/rust/issues/new/choose">report</a> any bugs you might come across!</p><h3><a class="anchor" href="https://blog.rust-lang.org/2025/10/30/Rust-1.91.0/#what-s-in-1-91-0-stable"></a>What's in 1.91.0 stable</h3><h4><a class="anchor" href="https://blog.rust-lang.org/2025/10/30/Rust-1.91.0/#aarch64-pc-windows-msvc-is-now-a-tier-1-platform"></a><code>aarch64-pc-windows-msvc</code> is now a Tier 1 platform</h4><p>The Rust compiler supports <a href="https://doc.rust-lang.org/rustc/platform-support.html">a wide variety of targets</a>, butthe Rust Team can't provide the same level of support for all of them. Toclearly mark how supported each target is, we use a tiering system:</p><ul><li>Tier 3 targets are technically supported by the compiler, but we don't checkwhether their code build or passes the tests, and we don't provide anyprebuilt binaries as part of our releases.</li><li>Tier 2 targets are guaranteed to build and we provide prebuilt binaries, butwe don't execute the test suite on those platforms: the produced binariesmight not work or might have bugs.</li><li>Tier 1 targets provide the highest support guarantee, and we run the fullsuite on those platforms for every change merged in the compiler. Prebuiltbinaries are also available.</li></ul><p>Rust 1.91.0 promotes the <code>aarch64-pc-windows-msvc</code> target to Tier 1 support,bringing our highest guarantees to users of 64-bit ARM systems running Windows.</p><h4><a class="anchor" href="https://blog.rust-lang.org/2025/10/30/Rust-1.91.0/#add-lint-against-dangling-raw-pointers-from-local-variables"></a>Add lint against dangling raw pointers from local variables</h4><p>While Rust's borrow checking prevents dangling references from being returned, it doesn'ttrack raw pointers. With this release, we are adding a warn-by-default lint on rawpointers to local variables being returned from functions. For example, code like this:</p><pre class="language-rust z-code"><code class="language-rust"><span class="z-source z-rust"><span class="z-meta z-function z-rust"><span class="z-meta z-function z-rust"><span class="z-storage z-type z-function z-rust">fn</span> </span><span class="z-entity z-name z-function z-rust">f</span></span><span class="z-meta z-function z-rust"><span class="z-meta z-function z-parameters z-rust"><span class="z-punctuation z-section z-parameters z-begin z-rust">(</span></span><span class="z-meta z-function z-rust"><span class="z-meta z-function z-parameters z-rust"><span class="z-punctuation z-section z-parameters z-end z-rust">)</span></span></span></span><span class="z-meta z-function z-rust"> <span class="z-meta z-function z-return-type z-rust"><span class="z-punctuation z-separator z-rust">-&gt;</span> <span class="z-storage z-modifier z-rust">*const</span> <span class="z-storage z-type z-rust">u8</span></span> </span><span class="z-meta z-function z-rust"><span class="z-meta z-block z-rust"><span class="z-punctuation z-section z-block z-begin z-rust">{</span></span></span></span><span class="z-source z-rust"><span class="z-meta z-function z-rust"><span class="z-meta z-block z-rust"> <span class="z-storage z-type z-rust">let</span> x <span class="z-keyword z-operator z-assignment z-rust">=</span> <span class="z-constant z-numeric z-integer z-decimal z-rust">0</span><span class="z-punctuation z-terminator z-rust">;</span></span></span></span><span class="z-source z-rust"><span class="z-meta z-function z-rust"><span class="z-meta z-block z-rust"> <span class="z-keyword z-operator z-bitwise z-rust">&amp;</span>x</span></span></span><span class="z-source z-rust"><span class="z-meta z-function z-rust"><span class="z-meta z-block z-rust"></span><span class="z-meta z-block z-rust"><span class="z-punctuation z-section z-block z-end z-rust">}</span></span></span></span></code></pre><p>will now produce a lint:</p><pre class="z-code"><code><span class="z-text z-plain">warning: a dangling pointer will be produced because the local variable `x` will be dropped</span><span class="z-text z-plain"> --&gt; src/lib.rs:3:5</span><span class="z-text z-plain"> |</span><span class="z-text z-plain">1 | fn f() -&gt; *const u8 {</span><span class="z-text z-plain"> | --------- return type of the function is `*const u8`</span><span class="z-text z-plain">2 | let x = 0;</span><span class="z-text z-plain"> | - `x` is part the function and will be dropped at the end of the function</span><span class="z-text z-plain">3 | &amp;x</span><span class="z-text z-plain"> | ^^</span><span class="z-text z-plain"> |</span><span class="z-text z-plain"> = note: pointers do not have a lifetime; after returning, the `u8` will be deallocated</span><span class="z-text z-plain"> at the end of the function because nothing is referencing it as far as the type system is</span><span class="z-text z-plain"> concerned</span><span class="z-text z-plain"> = note: `#[warn(dangling_pointers_from_locals)]` on by default</span></code></pre><p>Note that the code above is not unsafe, as it itself doesn't perform any dangerousoperations. Only dereferencing the raw pointer after the function returns would beunsafe. We expect future releases of Rust to add more functionality helping authorsto safely interact with raw pointers, and with unsafe code more generally.</p><h4><a class="anchor" href="https://blog.rust-lang.org/2025/10/30/Rust-1.91.0/#stabilized-apis"></a>Stabilized APIs</h4><ul><li><a href="https://doc.rust-lang.org/stable/std/path/struct.Path.html#method.file_prefix"><code>Path::file_prefix</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_ptr_add"><code>AtomicPtr::fetch_ptr_add</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_ptr_sub"><code>AtomicPtr::fetch_ptr_sub</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_byte_add"><code>AtomicPtr::fetch_byte_add</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_byte_sub"><code>AtomicPtr::fetch_byte_sub</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_or"><code>AtomicPtr::fetch_or</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_and"><code>AtomicPtr::fetch_and</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_xor"><code>AtomicPtr::fetch_xor</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_add"><code>{integer}::strict_add</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_sub"><code>{integer}::strict_sub</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_mul"><code>{integer}::strict_mul</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_div"><code>{integer}::strict_div</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_div_euclid"><code>{integer}::strict_div_euclid</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_rem"><code>{integer}::strict_rem</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_rem_euclid"><code>{integer}::strict_rem_euclid</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_neg"><code>{integer}::strict_neg</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_shl"><code>{integer}::strict_shl</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_shr"><code>{integer}::strict_shr</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_pow"><code>{integer}::strict_pow</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_add_unsigned"><code>i{N}::strict_add_unsigned</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_sub_unsigned"><code>i{N}::strict_sub_unsigned</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_abs"><code>i{N}::strict_abs</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_add_signed"><code>u{N}::strict_add_signed</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_sub_signed"><code>u{N}::strict_sub_signed</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/panic/struct.PanicHookInfo.html#method.payload_as_str"><code>PanicHookInfo::payload_as_str</code></a></li><li><a href="https://doc.rust-lang.org/stable/core/iter/fn.chain.html"><code>core::iter::chain</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.u16.html#method.checked_signed_diff"><code>u{N}::checked_signed_diff</code></a></li><li><a href="https://doc.rust-lang.org/stable/core/array/fn.repeat.html"><code>core::array::repeat</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.add_extension"><code>PathBuf::add_extension</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.with_added_extension"><code>PathBuf::with_added_extension</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.from_mins"><code>Duration::from_mins</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.from_hours"><code>Duration::from_hours</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#impl-PartialEq%3Cstr%3E-for-PathBuf"><code>impl PartialEq&lt;str&gt; for PathBuf</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#impl-PartialEq%3CString%3E-for-PathBuf"><code>impl PartialEq&lt;String&gt; for PathBuf</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/path/struct.Path.html#impl-PartialEq%3Cstr%3E-for-Path"><code>impl PartialEq&lt;str&gt; for Path</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/path/struct.Path.html#impl-PartialEq%3CString%3E-for-Path"><code>impl PartialEq&lt;String&gt; for Path</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/string/struct.String.html#impl-PartialEq%3CPathBuf%3E-for-String"><code>impl PartialEq&lt;PathBuf&gt; for String</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/string/struct.String.html#impl-PartialEq%3CPath%3E-for-String"><code>impl PartialEq&lt;Path&gt; for String</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.str.html#impl-PartialEq%3CPathBuf%3E-for-str"><code>impl PartialEq&lt;PathBuf&gt; for str</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.str.html#impl-PartialEq%3CPath%3E-for-str"><code>impl PartialEq&lt;Path&gt; for str</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.from_octets"><code>Ipv4Addr::from_octets</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.from_octets"><code>Ipv6Addr::from_octets</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.from_segments"><code>Ipv6Addr::from_segments</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/default/trait.Default.html#impl-Default-for-Pin%3CBox%3CT%3E%3E"><code>impl&lt;T&gt; Default for Pin&lt;Box&lt;T&gt;&gt; where Box&lt;T&gt;: Default, T: ?Sized</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/default/trait.Default.html#impl-Default-for-Pin%3CRc%3CT%3E%3E"><code>impl&lt;T&gt; Default for Pin&lt;Rc&lt;T&gt;&gt; where Rc&lt;T&gt;: Default, T: ?Sized</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/default/trait.Default.html#impl-Default-for-Pin%3CArc%3CT%3E%3E"><code>impl&lt;T&gt; Default for Pin&lt;Arc&lt;T&gt;&gt; where Arc&lt;T&gt;: Default, T: ?Sized</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/cell/struct.Cell.html#method.as_array_of_cells"><code>Cell::as_array_of_cells</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.u64.html#method.carrying_add"><code>u{N}::carrying_add</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.u64.html#method.borrowing_sub"><code>u{N}::borrowing_sub</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.u64.html#method.carrying_mul"><code>u{N}::carrying_mul</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.u64.html#method.carrying_mul_add"><code>u{N}::carrying_mul_add</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/collections/struct.BTreeMap.html#method.extract_if"><code>BTreeMap::extract_if</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/collections/struct.BTreeSet.html#method.extract_if"><code>BTreeSet::extract_if</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/os/windows/ffi/struct.EncodeWide.html#impl-Debug-for-EncodeWide%3C'_%3E"><code>impl Debug for windows::ffi::EncodeWide&lt;'_&gt;</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.str.html#method.ceil_char_boundary"><code>str::ceil_char_boundary</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.str.html#method.floor_char_boundary"><code>str::floor_char_boundary</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/num/struct.Saturating.html#impl-Sum-for-Saturating%3Cu32%3E"><code>impl Sum for Saturating&lt;u{N}&gt;</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/num/struct.Saturating.html#impl-Sum%3C%26Saturating%3Cu32%3E%3E-for-Saturating%3Cu32%3E"><code>impl Sum&lt;&amp;Self&gt; for Saturating&lt;u{N}&gt;</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/num/struct.Saturating.html#impl-Product-for-Saturating%3Cu32%3E"><code>impl Product for Saturating&lt;u{N}&gt;</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/num/struct.Saturating.html#impl-Product%3C%26Saturating%3Cu32%3E%3E-for-Saturating%3Cu32%3E"><code>impl Product&lt;&amp;Self&gt; for Saturating&lt;u{N}&gt;</code></a></li></ul><p>These previously stable APIs are now stable in const contexts:</p><ul><li><a href="https://doc.rust-lang.org/stable/std/primitive.array.html#method.each_ref"><code>&lt;[T; N]&gt;::each_ref</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.array.html#method.each_mut"><code>&lt;[T; N]&gt;::each_mut</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.new"><code>OsString::new</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.new"><code>PathBuf::new</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/any/struct.TypeId.html#method.of"><code>TypeId::of</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/ptr/fn.with_exposed_provenance.html"><code>ptr::with_exposed_provenance</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/ptr/fn.with_exposed_provenance_mut.html"><code>ptr::with_exposed_provenance_mut</code></a></li></ul><h4><a class="anchor" href="https://blog.rust-lang.org/2025/10/30/Rust-1.91.0/#platform-support"></a>Platform Support</h4><ul><li><a href="https://github.com/rust-lang/rust/pull/145682">Promote <code>aarch64-pc-windows-msvc</code> to Tier 1</a></li><li><a href="https://github.com/rust-lang/rust/pull/143031">Promote <code>aarch64-pc-windows-gnullvm</code> and <code>x86_64-pc-windows-gnullvm</code> to Tier 2 with host tools.</a>Note: llvm-tools and MSI installers are missing but will be added in future releases.</li></ul><p>Refer to Rust’s <a href="https://doc.rust-lang.org/rustc/platform-support.html">platform support page</a> for more information on Rust’s tiered platform support.</p><h4><a class="anchor" href="https://blog.rust-lang.org/2025/10/30/Rust-1.91.0/#other-changes"></a>Other changes</h4><p>Check out everything that changed in <a href="https://github.com/rust-lang/rust/releases/tag/1.91.0">Rust</a>, <a href="https://doc.rust-lang.org/nightly/cargo/CHANGELOG.html#cargo-191-2025-10-30">Cargo</a>, and <a href="https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-191">Clippy</a>.</p><h3><a class="anchor" href="https://blog.rust-lang.org/2025/10/30/Rust-1.91.0/#contributors-to-1-91-0"></a>Contributors to 1.91.0</h3><p>Many people came together to create Rust 1.91.0. We couldn't have done it without all of you. <a href="https://thanks.rust-lang.org/rust/1.91.0/">Thanks!</a></p></description> <pubDate>Thu, 30 Oct 2025 00:00:00 +0000</pubDate> <dc:creator>The Rust Release Team</dc:creator></item><item> <title>Mozilla Privacy Blog: California’s Opt Me Out Act is a Win for Privacy</title> <guid isPermaLink="false">https://blog.mozilla.org/netpolicy/?p=2515</guid> <link>https://blog.mozilla.org/netpolicy/2025/10/29/californias-opt-me-out-act-is-a-win-for-privacy/</link> <description><p>It’s no secret that privacy and user empowerment have always been core to Mozilla’s mission.</p><p>Over the years, we’ve consistently engaged with policymakers to advance strong privacy protections. We were thrilled when the <a href="https://blog.mozilla.org/netpolicy/2019/12/09/mozilla-comments-on-ccpa-regulations/">California Consumer Privacy Act (CCPA)</a> was signed into law, giving people the ability to opt-out and send a clear signal to websites that they don’t want their personal data tracked or sold. Despite this progress, many browsers and operating systems still failed to make these controls available or offer the tools to do so without third-party support. This gap is why we’ve pushed time and time again for additional legislation to ensure people can easily exercise their privacy rights online.</p><p>Last year, we <a href="https://blog.mozilla.org/netpolicy/2024/10/10/how-lawmakers-can-help-people-take-control-of-their-privacy/">shared our disappointment</a> when California’s <a href="https://leginfo.legislature.ca.gov/faces/billTextClient.xhtml?bill_id=202320240AB3048">AB 3048</a> was not signed into law. This bill was a meaningful step toward empowering consumers. When it failed to pass, we urged policymakers to continue efforts to advance similar legislation, to close gaps and strengthen enforcement.</p><p>We can’t stress this enough: Legislation must prioritize people’s privacy and meet the expectations that consumers rightly have about treatment of their sensitive personal information.</p><p>That’s why we <a href="https://advocacy.consumerreports.org/wp-content/uploads/2025/03/Privacy-Coalition-Letter-A.B.-566-Lowenthal-%E2%80%93-SUPPORT-Final-1.pdf">joined allies </a>to support AB 566, the <a href="https://leginfo.legislature.ca.gov/faces/billNavClient.xhtml?bill_id=202520260AB566">California Opt Me Out Act</a>, mandating that browsers include an opt-out setting so Californians can easily communicate their privacy preferences. Earlier this month, we were happy to see it pass and Governor Newsom sign it into law.</p><p>Mozilla has long advocated for easily accessible universal opt-out mechanisms; it’s <a href="https://blog.mozilla.org/netpolicy/2021/10/28/implementing-global-privacy-control/">a core feature built into Firefox</a> through our Global Privacy Control (GPC) mechanism. By requiring browsers to provide tools like GPC, California is setting an important precedent that brings us closer to a web where privacy controls are consistent, effective, and easy to use.</p><p>We hope to see similar steps in other states and at the federal level, to advance meaningful privacy protections for everyone online – the issue is more urgent than ever. We remain committed to working alongside policymakers across the board to ensure it happens.</p><p>The post <a href="https://blog.mozilla.org/netpolicy/2025/10/29/californias-opt-me-out-act-is-a-win-for-privacy/">California’s Opt Me Out Act is a Win for Privacy</a> appeared first on <a href="https://blog.mozilla.org/netpolicy">Open Policy &amp; Advocacy</a>.</p></description> <pubDate>Wed, 29 Oct 2025 23:53:38 +0000</pubDate> <dc:creator>Jenn Taylor Hodges</dc:creator></item><item> <title>Mozilla Addons Blog: New Recommended Extensions arrived, thanks to our community curators</title> <guid isPermaLink="false">https://blog.mozilla.org/addons/?p=9269</guid> <link>https://blog.mozilla.org/addons/2025/10/29/new-recommended-extensions-arrived-thanks-to-our-community-curators/</link> <description><p>Every so often we host community-driven curatorial projects to select new <a href="https://extensionworkshop.com/documentation/publish/recommended-extensions/" rel="noopener" target="_blank">Firefox Recommended Extensions</a>. By gathering a diverse group of community contributors who share a passion for the open web and add-ons, we aim to identify new Recommended Extensions that meet Mozilla’s “highest standards of security, functionality, and user experience.”</p><p>Earlier this year we concluded yet another successful curatorial project spanning six months. We evaluated dozens of worthy nominations. Those that received highest marks for functionality and user experience were then put through a technical review process to ensure they adhere to <a href="https://extensionworkshop.com/documentation/publish/add-on-policies/" rel="noopener" target="_blank">Add-on Policies</a> and our industry-leading security standards. A few candidates are still working their way through the final stages of review, but most of the new batch of Recommended Extensions are now live on AMO (<a href="http://addons.mozilla.org">addons.mozilla.org</a>) and we wanted to share the news, so without further ado here are some exciting new additions to the program…</p><p><a href="https://addons.mozilla.org/firefox/addon/yomitan/" rel="noopener" target="_blank">Yomitan</a> is a dictionary extension uniquely suited for learning new languages (20+). An interactive pop-up provides not only word definitions but audio pronunciation guidance as well, plus other great features tailored for understanding foreign languages.</p><p><a href="https://addons.mozilla.org/firefox/addon/power-thesaurus/" rel="noopener" target="_blank">Power Thesaurus</a> is another elite language tool that provides a vast world of synonyms just a mouse click away (antonyms too!).</p><div class="wp-caption alignright" id="attachment_9270" style="width: 490px;"><a href="https://addons.mozilla.org/firefox/addon/power-thesaurus/" rel="noopener" target="_blank"><img alt="" class="wp-image-9270" height="357" src="https://blog.mozilla.org/addons/files/2025/10/blog_PowerThes-580x431.png" width="480" /></a><p class="wp-caption-text" id="caption-attachment-9270">Power Thesaurus brings a world of words into Firefox.</p></div><p><a href="https://addons.mozilla.org/firefox/addon/photoshow/" rel="noopener" target="_blank">PhotoShow</a> is a fabulous tool for any photophile. Just hover over images to instantly enlarge their appearance with an option to download in high-def. Works with 300+ top websites.</p><p><a href="https://addons.mozilla.org/firefox/addon/simple-gesture/" rel="noopener" target="_blank">Simple Gesture for Android</a> provides a suite of touch gestures like page scrolling, back and forth navigation, tab management, and more.</p><p><a href="https://addons.mozilla.org/firefox/addon/immersive-translate/" rel="noopener" target="_blank">Immersive Translate</a> is a feature-packed translation extension. Highlights include translations across mediums like web, PDF, eBooks, even video subtitles. Works great on both Firefox desktop and Android.</p><p><a href="https://addons.mozilla.org/firefox/addon/besttimetracker/" rel="noopener" target="_blank">Time Tracker</a> offers key insights into your web habits. Track the time you spend on websites — with an option to block specific sites if you find they’re stealing too much of your time.</p><p><a href="https://addons.mozilla.org/firefox/addon/checker-plus-gmail/" rel="noopener" target="_blank">Checker Plus for Gmail</a> makes it easy to stay on top of your Gmail straight from Firefox’s toolbar. See email notifications, read, reply, delete, mark as read and more — without clicking away from wherever you are on the web.</p><p><a href="https://addons.mozilla.org/firefox/addon/youtube-suite-search-fixer/" rel="noopener" target="_blank">YouTube Search Fixer</a> de-clutters the YouTube experience by removing distracting features like Related Videos, For You, People Also Watched, Shorts — all that stuff intended to rabbit hole your attention. It’s completely customizable, so you’re free to tweak YouTube to taste.</p><div class="wp-caption alignright" id="attachment_9271" style="width: 254px;"><a href="https://addons.mozilla.org/firefox/addon/youtube-suite-search-fixer/" rel="noopener" target="_blank"><img alt="" class="wp-image-9271" height="563" src="https://blog.mozilla.org/addons/files/2025/10/blog_ytsearchfixer.png" width="244" /></a><p class="wp-caption-text" id="caption-attachment-9271">YouTube Search Fixer puts you in control of what you see.</p></div><p><a href="https://addons.mozilla.org/firefox/addon/websites-notes/" rel="noopener" target="_blank">Notefox</a> lets you leave notes to yourself on any website (per page or domain wide). It’s a simple, ideal tool for deep researchers or anyone who needs to leave themselves helpful notes around the web.</p><p><a href="https://addons.mozilla.org/firefox/addon/sink-it-for-reddit/" rel="noopener" target="_blank">Sink It for Reddit</a> features a bunch of “quality of life improvements” as its developer puts it, including color coded comments, content muting, adaptive dark mode, and more.</p><p><a href="https://addons.mozilla.org/firefox/addon/raindropio/" rel="noopener" target="_blank">Raindrop.io</a> helps you save and organize anything you find on the web. This is a tremendous tool for clipping articles, videos, even PDFs — and categorizing them by topic.</p><p><a href="https://addons.mozilla.org/firefox/addon/show-video-controls-firefox/" rel="noopener" target="_blank">Show Video Controls for Firefox</a> is a beloved feature for watchers of WebM formatted videos. The extension automatically enables video controls (volume/mute, play/pause, full screen, etc.).</p><p><a href="https://addons.mozilla.org/firefox/addon/chrome-mask/" rel="noopener" target="_blank">Chrome Mask</a> is a clever little extension designed to “mask” Firefox as the Chrome browser to websites that otherwise try to block or don’t want to support Firefox.</p><p>Congratulations to all of the developers! You’ve built incredible features that will be appreciated by millions of Firefox users.</p><p>Finally, a huge thank you to the <a href="https://wiki.mozilla.org/AMO/Featured_Board_Process" rel="noopener" target="_blank">Firefox Recommended Extensions Advisory Board</a> who contributed their time and talent helping curate all these new Recommended extensions. Shout outs to Amber Shumaker, C. Liam Brown, Cody Ortt, Danny Colin, gsakel, Lewis, Michael Soh, Paul, Rafi Meher, and Rusty (<a href="https://www.youtube.com/@RustyZone" rel="noopener" target="_blank">Rusty Zone on YouTube</a>).</p><p>We’re planning another curatorial project sometime in 2026, so if you’re the developer of a Firefox extension you believe meets the <a href="https://extensionworkshop.com/documentation/publish/recommended-extensions/#criteria" rel="noopener" target="_blank">criteria to become a Recommended extension</a>, or you’re the user of an extension you feel deserves consideration for the program, please email us nominations at <b>amo-featured [at] mozilla [dot]</b> <b>org</b>.</p><p>The post <a href="https://blog.mozilla.org/addons/2025/10/29/new-recommended-extensions-arrived-thanks-to-our-community-curators/">New Recommended Extensions arrived, thanks to our community curators</a> appeared first on <a href="https://blog.mozilla.org/addons">Mozilla Add-ons Community Blog</a>.</p></description> <pubDate>Wed, 29 Oct 2025 23:25:54 +0000</pubDate> <dc:creator>Scott DeVaney</dc:creator></item><item> <title>This Week In Rust: This Week in Rust 623</title> <guid isPermaLink="false">tag:this-week-in-rust.org,2025-10-29:/blog/2025/10/29/this-week-in-rust-623/</guid> <link>https://this-week-in-rust.org/blog/2025/10/29/this-week-in-rust-623/</link> <description><p>Hello and welcome to another issue of <em>This Week in Rust</em>!<a href="https://www.rust-lang.org/">Rust</a> 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<a href="https://bsky.app/profile/thisweekinrust.bsky.social">@thisweekinrust.bsky.social</a> on Bluesky or<a href="https://mastodon.social/@thisweekinrust">@ThisWeekinRust</a> on mastodon.social, or<a href="https://github.com/rust-lang/this-week-in-rust">send us a pull request</a>.Want to get involved? <a href="https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md">We love contributions</a>.</p><p><em>This Week in Rust</em> is openly developed <a href="https://github.com/rust-lang/this-week-in-rust">on GitHub</a> and archives can be viewed at <a href="https://this-week-in-rust.org/">this-week-in-rust.org</a>.If you find any errors in this week's issue, <a href="https://github.com/rust-lang/this-week-in-rust/pulls">please submit a PR</a>.</p><p>Want TWIR in your inbox? <a href="https://this-week-in-rust.us11.list-manage.com/subscribe?u=fd84c1c757e02889a9b08d289&amp;id=0ed8b72485">Subscribe here</a>.</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#updates-from-rust-community">Updates from Rust Community</a></h4> <h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#newsletters">Newsletters</a></h5><ul><li><a href="https://www.theembeddedrustacean.com/p/the-embedded-rustacean-issue-57">The Embedded Rustacean Issue #57</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#projecttooling-updates">Project/Tooling Updates</a></h5><ul><li><a href="https://fory.apache.org/blog/fory_rust_versatile_serialization_framework/">Introducing Apache Fory™</a></li><li><a href="https://www.sea-ql.org/blog/2025-10-30-sea-orm-2.0/">SeaORM 2.0: Entity First Workflow</a></li><li><a href="https://ryanskinner.com/posts/the-rari-ssr-breakthrough-12x-faster-10x-higher-throughput-than-nextjs">Rari v0.3.0: Rust-based React framework with SSR - 12x faster, 10x higher throughput than Next.js</a></li><li><a href="https://burn.dev/blog/release-0.19.0/">Burn 0.19.0 Release: Quantization, Distributed Training, and LLVM Backend</a></li><li><a href="https://blog.yelken.io/last-alpha-and-yelken-cloud/">Yelken's Last Alpha Release and Intro to Yelken Cloud</a></li><li><a href="https://dwrensha.github.io/capnproto-rust/2025/10/27/0.22-release.html">Capnproto 0.22 — async methods</a></li><li><a href="https://fyrox.rs/blog/post/fyrox-game-engine-1-0-0-rc-1/">Fyrox 1.0.0-rc.1</a></li><li><a href="https://boajs.dev/blog/2025/10/22/boa-release-21">Boa release v0.21</a></li><li><a href="https://typst.app/blog/2025/typst-0.14/">Typst: Typst 0.14: Now accessible</a></li><li><a href="https://www.iroh.computer/blog/iroh-blobs-0-95-new-features">iroh-blobs 0.95</a></li><li><a href="https://www.rustydonkey.dev/blog/2025.10.24_this_week_in_heave/">This week in Heave (2025.10.24)</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#observationsthoughts">Observations/Thoughts</a></h5><ul><li><a href="https://smallcultfollowing.com/babysteps/blog/2025/10/22/explicit-capture-clauses/">Explicit capture clauses</a></li><li><a href="https://andwass.github.io/rust/2025/10/23/closure-captures.html">Closure captures</a></li><li><a href="https://www.ncameron.org/blog/recent-rust-changes/">Recent Rust Changes</a></li><li><a href="https://kerkour.com/signal-app-rust">How Signal uses Rust to secure the communications of millions of people</a></li><li><a href="https://bitfieldconsulting.com/posts/hard-rain-json-rust">A hard rain's a-gonna fall: decoding JSON in Rust</a></li><li><a href="https://lorrens.me/2025/10/26/GSoC-Parallel-Macro-Expansion.html">GSoC ‘25 Work Product: Parallel Macro Expansion</a></li><li><a href="https://cat-solstice.github.io/test-pqueue/">When O3 is 2x slower than O2</a></li><li><a href="https://blog.goose.love/posts/history-of-clippy-changelog-cat/">The (rust) Clippy Changelog Cat Contest, a brief retrospective</a></li><li>[audio] <a href="https://netstack.fm/#episode-11">Netstack.FM — Episode 11 – Modern networking in Firefox with Max Inden</a></li><li>[audio] <a href="https://rustacean-station.org/episode/rust-1.81-1.82-1.83-1.84/">What's New in Rust 1.81 through 1.84</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-walkthroughs">Rust Walkthroughs</a></h5><ul><li><a href="https://ericfecteau.ca/data/rust-data-analysis/index.html">Data Analysis in Rust</a></li><li><a href="https://qouteall.fun/qouteall-blog/2025/How%20to%20Avoid%20Fighting%20Rust%20Borrow%20Checker">How to Avoid Fighting Rust Borrow Checker</a></li><li><a href="https://jorgeortiz.dev/posts/rust_unit_testing_test_doubles_mock/">Rust Unit Testing: Mocks and flexible verification</a></li><li><a href="https://blog.0xshadow.dev/posts/coding-agent-in-rust/coding-agent-in-rust-introduction/">Building a Coding Agent in Rust: Introduction</a></li><li><a href="https://internet.place/content/teddy-bear-trash-compactor/">Teddy Bear Trash Compactor</a></li><li><a href="https://www.afloat.boats/posts/rust-for-javascript-engineers-interactivity">Rust for JavaScript Engineers - Connect-4 Interactivity</a></li><li><a href="https://kerkour.com/rust-lifetimes-rc-arc">Cleanup your lifetime annotations in Rust with Rc and Arc</a></li><li><a href="https://medium.com/@carlmkadie/081e0f06886d">Vibe Validation with Lean, ChatGPT-5, &amp; Claude 4.5: Nine Rules for Proving (Rust) Algorithms Correct Without Knowing Formal Methods (Part 2)</a></li><li>[video] <a href="https://www.youtube.com/watch?v=Imb6vJkD0Vc">Rust Axum 0.8 Backend Engineering | Hello World</a></li><li>[video] <a href="https://www.youtube.com/watch?v=tQJTuYkZ4u8&amp;t=1s">Building Coding Agent in Rust | Project Setup</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#research">Research</a></h5><ul><li><a href="https://blog.weiznich.de/blog/diesel-infer-sql-nullablity/">Supporting <code>VIEW</code>s in Diesel</a></li></ul><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#crate-of-the-week">Crate of the Week</a></h4><p>This week's crate is <a href="https://github.com/joshrotenberg/tower-resilience">tower-resilience</a>, a library offering resilience features for tower.</p><p>Thanks to <a href="https://users.rust-lang.org/t/crate-of-the-week/2704/1483">Josh Rotenberg</a> for the self-suggestion!</p><p><a href="https://users.rust-lang.org/t/crate-of-the-week/2704">Please submit your suggestions and votes for next week</a>!</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#calls-for-testing">Calls for Testing</a></h4><p>An important step for RFC implementation is for people to experiment with theimplementation and give feedback, especially before stabilization.</p><p>If you are a feature implementer and would like your RFC to appear in this list, add a<code>call-for-testing</code> label to your RFC along with a comment providing testing instructions and/orguidance on which aspect(s) of the feature need testing.</p><ul><li><em>No calls for testing were issued this week by <a href="https://github.com/rust-lang/rust/labels/call-for-testing">Rust</a>, <a href="https://github.com/rust-lang/cargo/labels/call-for-testing">Cargo</a>, <a href="https://github.com/rust-lang/rfcs/issues?q=label%3Acall-for-testing">Rust language RFCs</a> or <a href="https://github.com/rust-lang/rustup/labels/call-for-testing">Rustup</a>.</em></li></ul><p><a href="https://github.com/rust-lang/this-week-in-rust/issues">Let us know</a> if you would like your feature to be tracked as a part of this list.</p><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rfcs"></a><a href="https://github.com/rust-lang/rfcs/issues?q=label%3Acall-for-testing">RFCs</a></h5><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust"></a><a href="https://github.com/rust-lang/rust/labels/call-for-testing">Rust</a></h5><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rustup"></a><a href="https://github.com/rust-lang/rustup/labels/call-for-testing">Rustup</a></h5><p>If you are a feature implementer and would like your RFC to appear on the above list, add the new <code>call-for-testing</code>label to your RFC along with a comment providing testing instructions and/or guidance on which aspect(s) of the featureneed testing.</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#call-for-participation-projects-and-speakers">Call for Participation; projects and speakers</a></h4><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cfp-projects">CFP - Projects</a></h5><p>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!</p><p>Some of these tasks may also have mentors available, visit the task page for more information.</p> <ul><li><a href="https://github.com/diesel-rs/diesel/issues/4840">Diesel - https://github.com/diesel-rs/diesel/issues/4840</a></li></ul><p>If you are a Rust project owner and are looking for contributors, please submit tasks <a href="https://github.com/rust-lang/this-week-in-rust?tab=readme-ov-file#call-for-participation-guidelines">here</a> or through a <a href="https://github.com/rust-lang/this-week-in-rust">PR to TWiR</a> or by reaching out on <a href="https://bsky.app/profile/thisweekinrust.bsky.social">Bluesky</a> or <a href="https://mastodon.social/@thisweekinrust">Mastodon</a>!</p><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cfp-events">CFP - Events</a></h5><p>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.</p><p><em>No Calls for papers or presentations were submitted this week.</em></p><p>If you are an event organizer hoping to expand the reach of your event, please submit a link to the website through a <a href="https://github.com/rust-lang/this-week-in-rust">PR to TWiR</a> or by reaching out on <a href="https://bsky.app/profile/thisweekinrust.bsky.social">Bluesky</a> or <a href="https://mastodon.social/@thisweekinrust">Mastodon</a>!</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#updates-from-the-rust-project">Updates from the Rust Project</a></h4><p>463 pull requests were <a href="https://github.com/search?q=is%3Apr+org%3Arust-lang+is%3Amerged+merged%3A2025-10-21..2025-10-28">merged in the last week</a></p><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#compiler">Compiler</a></h6><ul><li><a href="https://github.com/rust-lang/rust/pull/146725"><code>-Znext-solver</code> instantiate predicate binder without recanonicalizing goal</a></li><li><a href="https://github.com/rust-lang/rust/pull/142712"><code>hir_analysis</code>: add missing sizedness bounds</a></li><li><a href="https://github.com/rust-lang/rust/pull/142339">add NonNull pattern types</a></li><li><a href="https://github.com/rust-lang/rust/pull/148040">add a fast path for lowering trivial consts</a> (great speedup!)</li><li><a href="https://github.com/rust-lang/rust/pull/147083">do not lifetime-extend array/slice indices</a></li><li><a href="https://github.com/rust-lang/rust/pull/147890">deduce <code>captures(none)</code> for a return place and parameters</a></li><li><a href="https://github.com/rust-lang/rust/pull/147486">privacy: introduce some caching to type visiting in <code>DefIdVisitorSkeleton</code></a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#library">Library</a></h6><ul><li><a href="https://github.com/rust-lang/rust/pull/141445">add <code>FromIterator</code> impls for <code>ascii::Char</code>s to <code>String</code>s</a></li><li><a href="https://github.com/rust-lang/rust/pull/134316">add <code>String::replace_first</code> and <code>String::replace_last</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/115501">add new <code>inherit_handles</code> flag to CommandExt trait</a></li><li><a href="https://github.com/rust-lang/rust/pull/147788">const Cell methods</a></li><li><a href="https://github.com/rust-lang/rust/pull/145939">const <code>select_unpredictable</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/147932">create UTF-8 version of <code>OsStr</code>/<code>OsString</code></a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cargo">Cargo</a></h6><ul><li><a href="https://github.com/rust-lang/cargo/pull/16156">git: support shallow fetch for Git CLI backend</a></li><li><a href="https://github.com/rust-lang/cargo/pull/16144">make shell completion variables private</a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rustdoc">Rustdoc</a></h6><ul><li><a href="https://github.com/rust-lang/rust/pull/147991">Check <code>doc(cfg())</code> even of private/hidden items</a></li><li><a href="https://github.com/rust-lang/rust/pull/147762"><code>--emit=depinfo</code> output to stdout via <code>-</code></a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#clippy">Clippy</a></h6><ul><li><a href="https://github.com/rust-lang/rust-clippy/pull/15919"><code>manual_let_else</code>: wrap expressions ending with <code>'}'</code></a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15934"><code>match_as_ref</code>: suggest <code>as_ref</code> when the reference needs to be cast</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15960"><code>needless_if</code>: don't expand macro invocations in the suggestion</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15926"><code>manual_option_as_slice</code>: improve diagnostics</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15928"><code>match_as_ref</code>: improve diagnostics</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15929"><code>unnecessary_{find,filter}_map</code>: make diagnostic spans more precise</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15871"><code>{option,result}_map_unit_fn</code>: fix and clean-up tests, make suggestions multiline</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15676">consider labels of inline asm as conditionally executed</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15894">fix <code>len_zero</code> false positive on unstable methods</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/14421">lint precedence possible ambiguity between closure and method call</a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-analyzer">Rust-Analyzer</a></h6><ul><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20837">add an Extension Config API</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20921">avoid calling <code>specializes()</code> query on crates that do not define <code>#![feature(specialization)]</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20705">add "Flip range expression" assist</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/19918">add "Remove <code>else</code> branches" assist</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20186">provide an option to not show derives near the ADT for "Goto Implementations" or "Implementations" codelens</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20369">when renaming <code>self</code> to other name, change callers method method call syntax to assoc fn syntax</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20755">add <code>#[doc = include_str!("…")]</code> completion</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20831">add shorthand record field completions</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20571">add type keyword completions</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20658">complete <code>else</code> in more expressions</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20912">complete <code>let</code> before expression in <code>if</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20919">consider all matches for flyimport even when searched with a qualifier</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20905">fix array inhabitedness check</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20759">fix casts and use typed syntax tree API in <code>convert_to_guarded_return</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20764">handle <code>if</code>-<code>let</code> in <code>convert_to_guarded_return</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20712">handle shorthand field patterns in <code>destructure_tuple_binding</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20893">implement <code>Interner::impl_specializes()</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20889">improve field completion parentheses heuristic</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20886">improve handling of missing names in <code>MethodCallExpr</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20554">improve handling of the <code>env!</code> macro</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20670">improve incomplete statement heuristic</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20895">lower async block/closures correctly</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20844">offer <code>add_braces</code> on assignments</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20771">offer <code>invert_if</code> on <code>else</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20589">place new module outside <code>impl</code> block in <code>extract_module</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20913">support <code>let</code>-chains in <code>replace_is_method_with_if_let_method</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20922">reduce <code>client_commands</code> allocations in proto conversion</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20896">remove <code>hir-ty/src/next_solver/mapping.rs</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20891">semantic type for logical not</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-compiler-performance-triage">Rust Compiler Performance Triage</a></h5><p>Mostly negative week, coming almost entirely from adding sizedness bounds in <a href="https://github.com/rust-lang/rust/pull/142712">#142712</a>. Other than that, we got a nice win for async code from state transform optimization in <a href="https://github.com/rust-lang/rust/pull/147493">#147493</a> and quite a few smaller improvements from codegen optimization in <a href="https://github.com/rust-lang/rust/pull/147890">#147890</a>.</p><p>Triage done by <strong>@panstromek</strong>.Revision range: <a href="https://perf.rust-lang.org/?start=4068bafedd8ba724e332a5221c06a6fa531a30d2&amp;end=23fced0fcc5e0ec260d25f04a8b78b269e5e90f0&amp;absolute=false&amp;stat=instructions%3Au">4068bafe..23fced0f</a></p><p><strong>Summary</strong>:</p><table><thead><tr><th align="center">(instructions:u)</th><th align="center">mean</th><th align="center">range</th><th align="center">count</th></tr></thead><tbody><tr><td align="center">Regressions ❌ <br /> (primary)</td><td align="center">0.7%</td><td align="center">[0.2%, 3.7%]</td><td align="center">113</td></tr><tr><td align="center">Regressions ❌ <br /> (secondary)</td><td align="center">0.5%</td><td align="center">[0.1%, 1.7%]</td><td align="center">75</td></tr><tr><td align="center">Improvements ✅ <br /> (primary)</td><td align="center">-0.4%</td><td align="center">[-0.7%, -0.2%]</td><td align="center">3</td></tr><tr><td align="center">Improvements ✅ <br /> (secondary)</td><td align="center">-2.3%</td><td align="center">[-20.8%, -0.1%]</td><td align="center">30</td></tr><tr><td align="center">All ❌✅ (primary)</td><td align="center">0.7%</td><td align="center">[-0.7%, 3.7%]</td><td align="center">116</td></tr></tbody></table><p>2 Regressions, 2 Improvements, 7 Mixed; 2 of them in rollups42 artifact comparisons made in total</p><p><a href="https://github.com/rust-lang/rustc-perf/blob/0d28673aa9dacd2fe062baa1cd5336247f373d57/triage/2025/2025-10-27.md">Full report here</a></p><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#approved-rfcs"></a><a href="https://github.com/rust-lang/rfcs/commits/master">Approved RFCs</a></h5><p>Changes to Rust follow the Rust <a href="https://github.com/rust-lang/rfcs#rust-rfcs">RFC (request for comments) process</a>. Theseare the RFCs that were approved for implementation this week:</p><ul><li><em>No RFCs were approved this week.</em></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#final-comment-period">Final Comment Period</a></h5><p>Every week, <a href="https://www.rust-lang.org/team.html">the team</a> announces the 'final comment period' for RFCs and key PRswhich are reaching a decision. Express your opinions now.</p><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#tracking-issues-prs">Tracking Issues &amp; PRs</a></h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust_1"></a><a href="https://github.com/rust-lang/rust/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Rust</a><ul><li><a href="https://github.com/rust-lang/rust/pull/147017">FCW for repr(C) enums whose discriminant values do not fit into a c_int</a></li><li><a href="https://github.com/rust-lang/rust/issues/79995">Tracking Issue for maybe_uninit_write_slice</a></li><li><a href="https://github.com/rust-lang/rust/pull/145504">Add some conversion trait impls</a></li><li><a href="https://github.com/rust-lang/rust/issues/139201">Tracking Issue for <code>Duration::from_nanos_u128</code></a></li><li><a href="https://github.com/rust-lang/rust/issues/133508">Tracking Issue for <code>core_slice_as_array</code>.</a></li><li><a href="https://github.com/rust-lang/rust/pull/147400"><code>TryFrom&lt;integer&gt;</code> for <code>bool</code></a></li><li><a href="https://github.com/rust-lang/rust/issues/75027">Tracking Issue for slice::array_windows</a></li><li><a href="https://github.com/rust-lang/rust/issues/63569">Tracking issue for <code>#![feature(maybe_uninit_slice)]</code></a></li><li><a href="https://github.com/rust-lang/rust/issues/129333">Tracking Issue for <code>lazy_get</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/141994">add Iterator::contains</a></li><li><a href="https://github.com/rust-lang/rust/issues/85122">Tracking Issue for inherent unchecked integer methods</a></li><li><a href="https://github.com/rust-lang/rust/pull/145656">Stabilize s390x <code>vector</code> target feature and <code>is_s390x_feature_detected!</code> macro</a></li><li><a href="https://github.com/rust-lang/rust/pull/142682">Update bundled musl to 1.2.5</a></li></ul><a class="toclink" href="http://this-week-in-rust.org/atom.xml#compiler-team-mcps-only"></a><a href="https://github.com/rust-lang/compiler-team/issues?q=label%3Amajor-change%20%20label%3Afinal-comment-period">Compiler Team</a> <a href="https://forge.rust-lang.org/compiler/mcp.html">(MCPs only)</a><ul><li><a href="https://github.com/rust-lang/compiler-team/issues/938">Use v0 mangling by default on nightly</a></li><li><a href="https://github.com/rust-lang/compiler-team/issues/937">Use <code>annotate-snippets</code> as the default emitter on nightly</a></li><li><a href="https://github.com/rust-lang/compiler-team/issues/936">Creating a new maintainable debuginfo test suite</a></li><li><a href="https://github.com/rust-lang/compiler-team/issues/934">Switch to v0 mangling for symbols exceeding 64KB characters on targets generated PDB debug info</a></li><li><a href="https://github.com/rust-lang/compiler-team/issues/932">Promote <code>riscv64a23-unknown-linux-gnu</code> to Tier 2 without host tools</a></li><li><a href="https://github.com/rust-lang/compiler-team/issues/929">Omit suggestions when spans overlap</a></li><li><a href="https://github.com/rust-lang/compiler-team/issues/926">Replace <code>rustc_target::specTarget::arch</code> string with enum</a></li><li><a href="https://github.com/rust-lang/compiler-team/issues/923">Run main rust-analyzer tests in rust-lang/rust CI</a></li><li><a href="https://github.com/rust-lang/compiler-team/issues/920">Turn emscripten-wasm-eh unwinding ABI on by default</a></li><li><a href="https://github.com/rust-lang/compiler-team/issues/919">target tier 3 support for hexagon-unknown-qurt</a></li><li><a href="https://github.com/rust-lang/compiler-team/issues/906">Proposal for a dedicated test suite for the parallel frontend</a></li><li><a href="https://github.com/rust-lang/compiler-team/issues/835">Give integer literals a sign instead of relying on negation expressions</a></li><li><a href="https://github.com/rust-lang/compiler-team/issues/806">New Tier-3 target proposal: <code>loongarch64-linux-android</code></a></li></ul><a class="toclink" href="http://this-week-in-rust.org/atom.xml#leadership-council"></a><a href="https://github.com/rust-lang/leadership-council/issues?q=state%3Aopen%20label%3Afinal-comment-period">Leadership Council</a><ul><li><a href="https://github.com/rust-lang/leadership-council/issues/228">Proposal: Require all project team members to have Zulip IDs</a></li></ul><p><em>No Items entered Final Comment Period this week for<a href="https://github.com/rust-lang/rfcs/labels/final-comment-period">Rust RFCs</a>,<a href="https://github.com/rust-lang/cargo/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Cargo</a>,<a href="https://github.com/rust-lang/lang-team/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc+">Language Team</a>,<a href="https://github.com/rust-lang/reference/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Language Reference</a> or<a href="https://github.com/rust-lang/unsafe-code-guidelines/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Unsafe Code Guidelines</a>.</em></p><p>Let us know if you would like your PRs, Tracking Issues or RFCs to be tracked as a part of this list.</p><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#new-and-updated-rfcs"></a><a href="https://github.com/rust-lang/rfcs/pulls">New and Updated RFCs</a></h6><ul><li><a href="https://github.com/rust-lang/rfcs/pull/3872">Adding a crates.io Security tab</a></li></ul><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#upcoming-events">Upcoming Events</a></h4><p>Rusty Events between 2025-10-29 - 2025-11-26 🦀</p><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#virtual">Virtual</a></h5><ul><li>2025-10-29 | Virtual (Boulder, CO, US) | <a href="https://www.meetup.com/boulder-elixir/events/">Boulder Elixir</a><ul><li><a href="https://www.meetup.com/boulder-elixir/events/310996627/"><strong>Integrating Elixir and Apache DataFusion with Rustler</strong></a></li></ul></li><li>2025-10-29 | Virtual (Cardiff, UK) | <a href="https://www.meetup.com/rust-and-c-plus-plus-in-cardiff/events/">Rust and C++ Cardiff</a><ul><li><a href="https://www.meetup.com/rust-and-c-plus-plus-in-cardiff/events/311721465/"><strong>Hybrid event with Rust Dortmund!</strong></a></li></ul></li><li>2025-10-29 | Virtual (Tel Aviv-yafo, IL) | <a href="https://www.meetup.com/rust-tlv/events/">Rust 🦀 TLV</a><ul><li><a href="https://www.meetup.com/rust-tlv/events/311669921/"><strong>שיחה חופשית ווירטואלית על ראסט</strong></a></li></ul></li><li>2025-10-29 | Virtual (Girona, ES) | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/t8yovmmm"><strong>Sessió setmanal de codificació / Weekly coding session</strong></a></li></ul></li><li>2025-11-01 | Virtual (Kampala, UG) | <a href="https://www.eventbrite.com/o/rust-circle-kampala-65249289033">Rust Circle Meetup</a><ul><li><a href="https://www.eventbrite.com/e/rust-circle-meetup-tickets-628763868657"><strong>Rust Circle Meetup</strong></a></li></ul></li><li>2025-11-02 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/311109173/"><strong>Rust Readers Discord Discussion: Macros</strong></a></li></ul></li><li>2025-11-04 | Virtual (Beijing, CN) | <a href="https://www.meetup.com/wasm-rust-meetup/events/">WebAssembly and Rust Meetup (Wasm Empowering AI)</a><ul><li><a href="https://www.meetup.com/wasm-rust-meetup/events/311759399/"><strong>Monthly WasmEdge Community Meeting, the runtime for LLM/AGI</strong></a></li></ul></li><li>2025-11-05 | Virtual (Buffalo, NY, US) | <a href="https://www.meetup.com/buffalo-rust-meetup">Buffalo Rust Meetup</a><ul><li><a href="https://www.meetup.com/buffalo-rust-meetup/events/305304242/"><strong>Buffalo Rust User Group</strong></a></li></ul></li><li>2025-11-05 | Virtual (Indianapolis, IN, US) | <a href="https://www.meetup.com/indyrs">Indy Rust</a><ul><li><a href="https://www.meetup.com/indyrs/events/311574520/"><strong>Indy.rs - with Social Distancing</strong></a></li></ul></li><li>2025-11-05 | Virtual | <a href="https://www.eventbrite.com/o/ardan-labs-7092394651">Ardan Labs</a><ul><li><a href="https://www.eventbrite.com/e/mastering-error-handling-in-rust-from-panics-to-thiserror-anyhow-tickets-1849030121869"><strong>Mastering Error Handling in Rust: From Panics to thiserror &amp; anyhow</strong></a></li></ul></li><li>2025-11-06 | Virtual (Berlin, DE) | <a href="https://www.meetup.com/rust-berlin/events/">Rust Berlin</a><ul><li><a href="https://www.meetup.com/rust-berlin/events/305646021/"><strong>Rust Hack and Learn</strong></a></li></ul></li><li>2025-11-09 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/events/">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/311109175/"><strong>Rust Readers Discord Discussion: Macros</strong></a></li></ul></li><li>2025-11-10 || <a href="https://www.bettercode.eu/">BetterCode</a><ul><li>$<a href="https://dev.events/conferences/better-code-rust-i6inve6t"><strong>betterCode() Industrielle Anwendungen mit Rust</strong></a></li></ul></li><li>2025-11-11 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/events/">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/305361536/"><strong>Second Tuesday</strong></a></li></ul></li><li>2025-11-11 | Virtual (London, UK) | <a href="https://www.meetup.com/women-in-rust/events/">Women in Rust</a><ul><li><a href="https://www.meetup.com/women-in-rust/events/311068632/"><strong>👋 Community Catch Up</strong></a></li></ul></li><li>2025-11-12 | Virtual (Girona, ES) | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/yhe1xrhe"><strong>Sessió setmanal de codificació / Weekly coding session</strong></a></li></ul></li><li>2025-11-13 | Virtual (Nürnberg, DE) | <a href="https://www.meetup.com/rust-noris/events/">Rust Nuremberg</a><ul><li><a href="https://www.meetup.com/rust-noris/events/310849154/"><strong>Rust Nürnberg online</strong></a></li></ul></li><li>2025-11-16 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/events/">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/311109181/"><strong>Rust Readers Discord Discussion: Macros</strong></a></li></ul></li><li>2025-11-18 | Virtual (Washington, DC, US) | <a href="https://www.meetup.com/rustdc/events/">Rust DC</a><ul><li><a href="https://www.meetup.com/rustdc/events/310002262/"><strong>Mid-month Rustful</strong></a></li></ul></li><li>2025-11-19 | Virtual (Girona, ES) | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/l2xukapz"><strong>Sessió setmanal de codificació / Weekly coding session</strong></a></li></ul></li><li>2025-11-19 | Virtual (Vancouver, BC, CA) | <a href="https://www.meetup.com/vancouver-rust/events/">Vancouver Rust</a><ul><li><a href="https://www.meetup.com/vancouver-rust/events/309926564/"><strong>Rust Study/Hack/Hang-out</strong></a></li></ul></li><li>2025-11-20 | Virtual (Berlin, DE) | <a href="https://www.meetup.com/rust-berlin/events/">Rust Berlin</a><ul><li><a href="https://www.meetup.com/rust-berlin/events/306046642/"><strong>Rust Hack and Learn</strong></a></li></ul></li><li>2025-11-20 | Virtual (Charlottesville, VA, US) | <a href="https://www.meetup.com/charlottesville-rust-meetup/events/">Charlottesville Rust Meetup</a><ul><li><a href="https://www.meetup.com/charlottesville-rust-meetup/events/311705915/"><strong>Tock, a Rust based Operating System Part #1</strong></a></li></ul></li><li>2025-11-23 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/events/">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/311109183/"><strong>Rust Readers Discord Discussion: Macros</strong></a></li></ul></li><li>2025-11-25 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/events/">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/305361446/"><strong>Fourth Tuesday</strong></a></li></ul></li><li>2025-11-25 | Virtual (London, UK) | <a href="https://www.meetup.com/women-in-rust/events/">Women in Rust</a><ul><li><a href="https://www.meetup.com/women-in-rust/events/311534469/"><strong>Data-Intensive Systems in Rust: Safety, Speed, Concurrency</strong></a></li></ul></li><li>2025-11-26 | Virtual (Girona, ES) | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/q5tjirkt"><strong>Sessió setmanal de codificació / Weekly coding session</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#africa">Africa</a></h5><ul><li>2025-11-11 | Johannesburg, ZA | <a href="https://www.meetup.com/johannesburg-rust-meetup/events/">Johannesburg Rust Meetup</a><ul><li><a href="https://www.meetup.com/johannesburg-rust-meetup/events/311726345/"><strong>More on Rust types</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#asia">Asia</a></h5><ul><li>2025-11-15 | Bangalore, IN | <a href="https://hasgeek.com/rustbangalore">Rust Bangalore</a><ul><li><a href="https://hasgeek.com/rustbangalore/november-2025-rustacean-meetup//"><strong>November 2025 Rustacean meetup</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#europe">Europe</a></h5><ul><li>2025-10-29 | Dortmund, DE | <a href="https://www.meetup.com/rust-dortmund/events/">Rust Dortmund</a><ul><li><a href="https://www.meetup.com/rust-dortmund/events/311251545/"><strong>Rust Dortmund Meetup October 2025</strong></a></li></ul></li><li>2025-10-29 | London, UK | <a href="https://www.meetup.com/rust-london-user-group/events/">Rust London User Group</a><ul><li><a href="https://www.meetup.com/rust-london-user-group/events/311670686/"><strong>Rust London Code Dojo: Intro to Async Embedded Rust</strong></a></li></ul></li><li>2025-10-30 | Berlin, DE | <a href="https://www.meetup.com/rust-berlin/events/">Rust Berlin</a><ul><li><a href="https://www.meetup.com/rust-berlin/events/311752307/"><strong>Rust Berlin on location 🏳️🌈 - Edition 008</strong></a></li></ul></li><li>2025-10-30 | Copenhagen, DK | <a href="https://www.meetup.com/copenhagen-rust-community">Copenhagen Rust Community</a><ul><li><a href="https://www.meetup.com/copenhagen-rust-community/events/311405044/"><strong>Rust meetup #62 sponsored by Google!</strong></a></li></ul></li><li>2025-10-30 | Prague, CZ | <a href="https://www.meetup.com/rust-prague">Rust Prague</a><ul><li><a href="https://www.meetup.com/rust-prague/events/310967094/"><strong>Rust Meetup Prague (October 2025)</strong></a></li></ul></li><li>2025-11-01 | Stockholm, SE | <a href="https://www.meetup.com/stockholm-rust/events/">Stockholm Rust</a><ul><li><a href="https://www.meetup.com/stockholm-rust/events/311582259/"><strong>Ferris' Fika Forum #19</strong></a></li></ul></li><li>2025-11-02 - 2025-11-04 | Florence, IT | <a href="https://rustlab.it/">Rustlab 2025</a><ul><li>$<a href="https://rustlab.it/"><strong>Rustlab 2025</strong></a></li></ul></li><li>2025-11-03 | Bern, CH | <a href="https://www.meetup.com/it-IT/guild42ch/">Guild42</a><ul><li><a href="https://www.meetup.com/it-IT/guild42ch/events/307260207/"><strong>Moving out of systems programming into Kubernetes: is it time to adopt Rust ?</strong></a></li></ul></li><li>2025-11-04 | Manchester, UK | <a href="https://www.meetup.com/rust-manchester">Rust Manchester</a><ul><li><a href="https://www.meetup.com/rust-manchester/events/310921632/"><strong>Rust Manchester November Talk</strong></a></li></ul></li><li>2025-11-04 | Trondheim, NO | <a href="https://www.meetup.com/rust-trondheim/events/">Rust Trondheim</a><ul><li><a href="https://www.meetup.com/rust-trondheim/events/311595023/"><strong>Optimizing matrix multiplication and building Python packages with Rust</strong></a></li></ul></li><li>2025-11-05 | Girona, ES | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/xl8ob0tn"><strong>Rust Girona Hack &amp; Learn 11 2025</strong></a></li></ul></li><li>2025-11-05 | Oslo, NO | <a href="https://www.meetup.com/rust-oslo">Rust Oslo</a><ul><li><a href="https://www.meetup.com/rust-oslo/events/310601872/"><strong>Rust Hack'n'Learn at Kampen Bistro</strong></a></li></ul></li><li>2025-11-05 | Oxford, UK | <a href="https://www.meetup.com/oxford-rust-meetup-group/events/">Oxford ACCU/Rust Meetup.</a><ul><li><a href="https://www.meetup.com/oxford-rust-meetup-group/events/311569796/"><strong>Halloween special.</strong></a></li></ul></li><li>2025-11-06 | Gdansk, PL | <a href="https://www.meetup.com/rust-gdansk/events/">Rust Gdansk</a><ul><li><a href="https://www.meetup.com/rust-gdansk/events/310924266/"><strong>Rust Gdansk Meetup #11</strong></a></li></ul></li><li>2025-11-06 | Vienna, AT | <a href="https://www.meetup.com/rust-vienna/events/">Rust Vienna</a><ul><li><a href="https://www.meetup.com/rust-vienna/events/311679397/"><strong>Season 2 Kickoff | at metalab 🦀</strong></a></li></ul></li><li>2025-11-11 | London, UK | <a href="https://www.meetup.com/rust-london-user-group/events/">Rust London User Group</a><ul><li><a href="https://www.meetup.com/rust-london-user-group/events/311737021/"><strong>Rust London x Zed Meetup</strong></a></li></ul></li><li>2025-11-12 | Cambridge, UK | <a href="https://www.meetup.com/cambridge-rust-meetup/events/">Cambridge Rust Meetup</a><ul><li><a href="https://www.meetup.com/cambridge-rust-meetup/events/311583721/"><strong>Monthly Rust Meetup</strong></a></li></ul></li><li>2025-11-12 | Reading, UK | <a href="https://www.meetup.com/reading-rust-workshop/events/">Reading Rust Workshop</a><ul><li><a href="https://www.meetup.com/reading-rust-workshop/events/308944050/"><strong>Reading Rust Meetup</strong></a></li></ul></li><li>2025-11-13 | Geneva, CH | <a href="https://www.posttenebraslab.ch/wiki/events/monthly_meeting/rust_meetup">Rust Geneva</a><ul><li><a href="https://www.posttenebraslab.ch/wiki/events/monthly_meeting/rust_meetup"><strong>Rust Meetup Geneva</strong></a></li></ul></li><li>2025-11-13 | Paris, FR | <a href="https://www.meetup.com/rust-paris/events/">Rust Paris</a><ul><li><a href="https://www.meetup.com/rust-paris/events/311461594/"><strong>Rust meetup #80</strong></a></li></ul></li><li>2025-11-18 | Leipzig, SN, DE | <a href="https://www.meetup.com/rust-modern-systems-programming-in-leipzig/events/">Rust - Modern Systems Programming in Leipzig</a><ul><li><a href="https://www.meetup.com/rust-modern-systems-programming-in-leipzig/events/308592257/"><strong>Topic TBD</strong></a></li></ul></li><li>2025-11-20 | Aarhus, DK | <a href="https://www.meetup.com/rust-aarhus/events/">Rust Aarhus</a><ul><li><a href="https://www.meetup.com/rust-aarhus/events/311502123/"><strong>Social Night</strong></a></li></ul></li><li>2025-11-20 | Luzern, CH | [Rust Luzern]((https://www.meetup.com/rust-luzern/)<ul><li><a href="https://www.meetup.com/rust-luzern/events/311410681/"><strong>2025 Rust Talks Luzern #3: Crate Walkthroughs @ Noser Engineering AG</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#north-america">North America</a></h5><ul><li>2025-10-29 | New York, NY, US | <a href="https://www.meetup.com/rust-nyc/events/">Rust NYC</a><ul><li><a href="https://www.meetup.com/rust-nyc/events/311541108/"><strong>Rust NYC: Scalable static analysis: confronting the halting problem</strong></a></li></ul></li><li>2025-10-30 | Atlanta, GA, US | <a href="https://www.meetup.com/rust-atl">Rust Atlanta</a><ul><li><a href="https://www.meetup.com/rust-atl/events/308675988/"><strong>Rust-Atl</strong></a></li></ul></li><li>2025-10-30 | Mountain View, CA, US | <a href="https://www.meetup.com/hackerdojo/events/">Hacker Dojo</a><ul><li><a href="https://www.meetup.com/hackerdojo/events/311273832/"><strong>RUST MEETUP at HACKER DOJO</strong></a></li></ul></li><li>2025-11-01 | Boston, MA, US | <a href="https://www.meetup.com/bostonrust">Boston Rust Meetup</a><ul><li><a href="https://www.meetup.com/bostonrust/events/311039492/"><strong>Chinatown Rust Lunch, Nov 1</strong></a></li></ul></li><li>2025-11-06 | Saint Louis, MO, US | <a href="https://www.meetup.com/stl-rust/events/">STL Rust</a><ul><li><a href="https://www.meetup.com/stl-rust/events/307251982/"><strong>SIUE students on wasm 3D animations</strong></a></li></ul></li><li>2025-11-08 | Boston, MA, US | <a href="https://www.meetup.com/bostonrust/events/">Boston Rust Meetup</a><ul><li><a href="https://www.meetup.com/bostonrust/events/311039501/"><strong>Winter Hill Rust Lunch, Nov 8</strong></a></li></ul></li><li>2025-11-13 | Lehi, UT, US | <a href="https://www.meetup.com/utah-rust/events/">Utah Rust</a><ul><li><a href="https://www.meetup.com/utah-rust/events/311613658/"><strong>Ipmap: Building Desktop Apps with Tauri</strong></a></li></ul></li><li>2025-11-18 | San Francisco, CA, US | <a href="https://www.meetup.com/san-francisco-rust-study-group/events/">San Francisco Rust Study Group</a><ul><li><a href="https://www.meetup.com/san-francisco-rust-study-group/events/308865806/"><strong>Rust Hacking in Person</strong></a></li></ul></li><li>2025-11-20 | Seattle, WA, US | <a href="https://www.meetup.com/join-srug/events/">Seattle Rust User Group</a><ul><li><a href="https://www.meetup.com/seattle-rust-user-group/events/311351673/"><strong>November, 2025 SRUG (Seattle Rust User Group) Meetup</strong></a></li></ul></li><li>2025-11-26 | Austin, TX, US | <a href="https://www.meetup.com/rust-atx/events/">Rust ATX</a><ul><li><a href="https://www.meetup.com/rust-atx/events/310457310/"><strong>Rust Lunch - Fareground</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#oceania">Oceania</a></h5><ul><li>2025-10-29 | Barton, AC, AU | <a href="https://www.meetup.com/rust-canberra/events/">Canberra Rust User Group</a><ul><li><a href="https://www.meetup.com/rust-canberra/events/311234237/"><strong>October Meetup</strong></a></li></ul></li><li>2025-11-11 | Christchurch, NZ | <a href="https://www.meetup.com/christchurch-rustlang-meetup-group/events/">Christchurch Rust Meetup Group</a><ul><li><a href="https://www.meetup.com/christchurch-rustlang-meetup-group/events/311685331/"><strong>Christchurch Rust Meetup</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#south-america">South America</a></h5><ul><li>2025-10-30 | Florianopolis, BR | <a href="https://luma.com/calendar/cal-iOloL5ZqswCO5Mm">Rust Brasil</a><ul><li><a href="https://luma.com/lky7an18"><strong>Rust Floripa</strong></a></li></ul></li></ul><p>If you are running a Rust event please add it to the <a href="https://www.google.com/calendar/embed?src=apd9vmbc22egenmtu5l6c5jbfc%40group.calendar.google.com">calendar</a> to getit mentioned here. Please remember to add a link to the event too.Email the <a href="mailto:community-team@rust-lang.org">Rust Community Team</a> for access.</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#jobs">Jobs</a></h4><p>Please see the latest <a href="https://www.reddit.com/r/rust/comments/1nknaii/official_rrust_whos_hiring_thread_for_jobseekers/">Who's Hiring thread on r/rust</a></p><h3><a class="toclink" href="http://this-week-in-rust.org/atom.xml#quote-of-the-week">Quote of the Week</a></h3><blockquote><p>Petition to add an <code>unwise</code> keyword in Rust</p></blockquote><p>– <a href="https://hachyderm.io/@ponderingpothos/115403971956993021">James Logan on hachyderm.io</a></p><p>Thanks to <a href="https://users.rust-lang.org/t/twir-quote-of-the-week/328/1724">llogiq</a> for the suggestion!</p><p><a href="https://users.rust-lang.org/t/twir-quote-of-the-week/328">Please submit quotes and vote for next week!</a></p><p><em>This Week in Rust is edited by: <a href="https://github.com/nellshamrell">nellshamrell</a>, <a href="https://github.com/llogiq">llogiq</a>, <a href="https://github.com/cdmistman">cdmistman</a>, <a href="https://github.com/ericseppanen">ericseppanen</a>, <a href="https://github.com/extrawurst">extrawurst</a>, <a href="https://github.com/U007D">U007D</a>, <a href="https://github.com/joelmarcey">joelmarcey</a>, <a href="https://github.com/mariannegoldin">mariannegoldin</a>, <a href="https://github.com/bennyvasquez">bennyvasquez</a>, <a href="https://github.com/bdillo">bdillo</a></em></p><p><em>Email list hosting is sponsored by <a href="https://foundation.rust-lang.org/">The Rust Foundation</a></em></p><p><small><a href="https://www.reddit.com/r/rust/comments/1ojr69c/this_week_in_rust_623/">Discuss on r/rust</a></small></p></description> <pubDate>Wed, 29 Oct 2025 04:00:00 +0000</pubDate> <dc:creator>TWiR Contributors</dc:creator></item><item> <title>Mozilla Thunderbird: Mobile Progress Report: September-October 2025</title> <guid isPermaLink="false">https://blog.thunderbird.net/?p=4013</guid> <link>https://blog.thunderbird.net/2025/10/mobile-progress-report-september-october-2025/</link> <description><p><img alt="" class="attachment-640x360 size-640x360 wp-post-image" height="360" src="https://blog.thunderbird.net/files/2025/10/blog-banner-mobile3-768x432.jpg" width="640" /></p><h3>A Brief Self-Introduction</h3> <p>Hello community, it’s a pleasure to be here and help take part in a product I’ve used for many years, but now with the focus on Mobile. I am Jon Bott, and am the new Engineering Manager for the Thunderbird Mobile teams. I am passionate about native mobile development and am excited to be helping both mobile apps moving forward. </p> <h3>Refining our Roadmaps</h3> <p>For now, as we develop, we are refining the roadmap and making more concrete plans for iOS Thunderbird’s Alpha release in a couple of months, and finalizing our initial pass with Account Drawer on the Android (planned for release in the next beta). We also have Notification and Message List improvements under development.</p> <h3>Carpaccio</h3> <p>As a mobile product, we’ve gone through several changes over the last year or so, from large annual releases, to our more recent monthly beta and release process. Our next steps are to start sizing our features so they fit better into that monthly cadence, and you’ll see the benefits of this over the next few months as we simplify our planning &amp; process – breaking our large features into smaller, more frequently delivered pieces. This is based on the Carpaccio method for breaking down features into thin slices with the goal of delivering usable features to our users more quickly, and focusing more on the iterative process helping us take feedback sooner from the community on a feature experience and designs. Not everything will fit in this, of course, but more will go out sooner as we carve away with our larger goals for the platforms.</p> <h3>Stay Tuned</h3> <p>Over the next few weeks we’ll update our timelines and roadmaps, to what pieces we have high confidence in delivering over the next few months, and a 50,000 foot (15,000 meter) view of our larger pieces we hope to tackle in the next year. Ultimately our goal is to more quickly reduce pain points you might have, and keep adding polish to Thunderbird’s mobile experience. </p> <h3>Progress with Thunderbird iOS</h3> <p>We are excited to show the progress we are making in getting the iOS up and running. Some things are connected, others have sample data for now, but it helps us move quickly and start to share what the UI will be like moving forward. Here are the actual screen we’ve coded up:</p> <figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex"><figure class="wp-block-image size-full"><a href="https://blog.thunderbird.net/files/2025/10/Mobile-Progress-Report_-September_October-1.jpg"><img alt="" class="wp-image-4026" height="1311" src="https://blog.thunderbird.net/files/2025/10/Mobile-Progress-Report_-September_October-1.jpg" width="603" /></a></figure> <figure class="wp-block-image size-full"><a href="https://blog.thunderbird.net/files/2025/10/Mobile-Progress-Report_-September_October1-1.jpg"><img alt="" class="wp-image-4032" height="1311" src="https://blog.thunderbird.net/files/2025/10/Mobile-Progress-Report_-September_October1-1.jpg" width="603" /></a></figure> <figure class="wp-block-image size-full"><a href="https://blog.thunderbird.net/files/2025/10/Mobile-Progress-Report_-September_October2.jpg"><img alt="" class="wp-image-4038" height="1311" src="https://blog.thunderbird.net/files/2025/10/Mobile-Progress-Report_-September_October2.jpg" width="603" /></a></figure></figure> <figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex"><figure class="wp-block-image size-full"><a href="https://blog.thunderbird.net/files/2025/10/Mobile-Progress-Report_-September_October3.jpg"><img alt="" class="wp-image-4044" height="1311" src="https://blog.thunderbird.net/files/2025/10/Mobile-Progress-Report_-September_October3.jpg" width="603" /></a></figure> <figure class="wp-block-image size-full"><a href="https://blog.thunderbird.net/files/2025/10/Mobile-Progress-Report_-September_October4.jpg"><img alt="" class="wp-image-4052" height="1311" src="https://blog.thunderbird.net/files/2025/10/Mobile-Progress-Report_-September_October4.jpg" width="603" /></a></figure> <figure class="wp-block-image size-full"><a href="https://blog.thunderbird.net/files/2025/10/Mobile-Progress-Report_-September_October5.jpg"><img alt="" class="wp-image-4049" height="1311" src="https://blog.thunderbird.net/files/2025/10/Mobile-Progress-Report_-September_October5.jpg" width="603" /></a></figure></figure> <p>____</p> <p><strong>Jon Bott</strong></p> <p>Manager, Mobile Apps</p><p>The post <a href="https://blog.thunderbird.net/2025/10/mobile-progress-report-september-october-2025/">Mobile Progress Report: September-October 2025</a> appeared first on <a href="https://blog.thunderbird.net">The Thunderbird Blog</a>.</p></description> <pubDate>Tue, 28 Oct 2025 20:17:45 +0000</pubDate> <dc:creator>Herbal7ea</dc:creator></item><item> <title>Spidermonkey Development Blog: Who needs Graphviz when you can build it yourself?</title> <guid isPermaLink="false">https://spidermonkey.dev/blog/2025/10/28/iongraph-web</guid> <link>https://spidermonkey.dev/blog/2025/10/28/iongraph-web.html</link> <description><p>We recently overhauled our internal tools for visualizing the compilation of JavaScript and WebAssembly. When SpiderMonkey’s optimizing compiler, Ion, is active, we can now produce interactive graphs showing exactly how functions are processed and optimized.</p> <div id="livegraph-available"> <p>You can play with these graphs right here on this page. Simply write some JavaScript code in the <code>test</code> function and see what graph is produced. You can click and drag to navigate, ctrl-scroll to zoom, and drag the slider at the bottom to scrub through the optimization process.</p> <p>As you experiment, take note of how stable the graph layout is, even as the sizes of blocks change or new structures are added. Try clicking a block's title to select it, then drag the slider and watch the graph change while the block remains in place. Or, click an instruction's number to highlight it so you can keep an eye on it across passes.</p></div> <div> <div class="full-width ba" id="livegraph-container"> <div id="js-input"></div> <div id="graph-container-container"> <div id="graph-container"></div> <div id="legend"> <span id="pass-name"> </span> <div class="flex g2"> <button disabled="" id="pass-prev">Prev</button> <input disabled="" id="pass-slider" list="pass-slider-markers" type="range" value="0" /> <datalist id="pass-slider-markers"></datalist> <button disabled="" id="pass-next">Next</button> </div> </div> </div> </div></div> <p><img alt="Example iongraph output" id="livegraph-preview" src="https://spidermonkey.dev/assets/img/iongraph-preview.png" /></p> <p>We are not the first to visualize our compiler’s internal graphs, of course, nor the first to make them interactive. But I was not satisfied with the output of common tools like <a href="https://graphviz.org/">Graphviz</a> or <a href="https://mermaid.js.org/">Mermaid</a>, so I decided to create a layout algorithm specifically tailored to our needs. The resulting algorithm is simple, fast, produces surprisingly high-quality output, and can be implemented in less than a thousand lines of code. The purpose of this article is to walk you through this algorithm and the design concepts behind it.</p> <div id="livegraph-unavailable"> <p><i>Read this post on desktop to see an interactive demo of iongraph.</i></p></div> <h3>Background</h3> <p>As readers of this blog already know, SpiderMonkey has several tiers of execution for JavaScript and WebAssembly code. The highest tier is known as Ion, an optimizing SSA compiler that takes the most time to compile but produces the highest-quality output.</p> <p>Working with Ion frequently requires us to visualize and debug the SSA graph. Since 2011 we have used a tool for this purpose called <a href="https://github.com/sstangl/iongraph">iongraph</a>, built by Sean Stangl. It is a simple Python script that takes a JSON dump of our compiler graphs and uses Graphviz to produce a PDF. It is perfectly adequate, and very much the status quo for compiler authors, but unfortunately the Graphviz output has many problems that make our work tedious and frustrating.</p> <p>The first problem is that the Graphviz output rarely bears any resemblance to the source code that produced it. Graphviz will place nodes wherever it feels will minimize error, resulting in a graph that snakes left and right seemingly at random. There is no visual intuition for how deeply nested a block of code is, nor is it easy to determine which blocks are inside or outside of loops. Consider the following function, and its Graphviz graph:</p> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">foo</span><span class="p">(</span><span class="nx">n</span><span class="p">)</span> <span class="p">{</span> <span class="kd">let</span> <span class="nx">result</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">n</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="o">!!</span><span class="p">(</span><span class="nx">i</span> <span class="o">%</span> <span class="mi">2</span><span class="p">))</span> <span class="p">{</span> <span class="nx">result</span> <span class="o">=</span> <span class="mh">0x600DBEEF</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="nx">result</span> <span class="o">=</span> <span class="mh">0xBADBEEF</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="nx">result</span><span class="p">;</span><span class="p">}</span></code></pre></div></div> <div class="ba" style="background-color: white; display: flex;"> <img src="https://spidermonkey.dev/assets/img/iongraph-example1-orig.svg" /></div> <p>Counterintuitively, the <code class="language-plaintext highlighter-rouge">return</code> appears <em>before</em> the two assignments in the body of the loop. Since this graph mirrors JavaScript control flow, we’d expect to see the return at the bottom. This problem only gets worse as graphs grow larger and more complex.</p> <p>The second, related problem is that Graphviz’s output is unstable. Small changes to the input can result in large changes to the output. As you page through the graphs of each pass within Ion, nodes will jump left and right, true and false branches will swap, loops will run up the right side instead of the left, and so on. This makes it very hard to understand the actual effect of any given pass. Consider the following before and after, and notice how the second graph is almost—but not quite—a mirror image of the first, despite very minimal changes to the graph’s structure:</p> <div> <div class="full-width ba flex-column flex-row-ns" style="overflow: auto; background-color: white; display: flex;"> <img src="https://spidermonkey.dev/assets/img/iongraph-example2-before.svg" style="height: 40rem;" /> <img src="https://spidermonkey.dev/assets/img/iongraph-example2-after.svg" style="height: 40rem;" /> </div></div> <p>None of this felt right to me. Control flow graphs should be able to follow the structure of the program that produced them. After all, a control flow graph has many restrictions that a general-purpose tool would not be aware of: they have very few cycles, all of which are well-defined because they come from loops; furthermore, both JavaScript and WebAssembly have reducible control flow, meaning all loops have only one entry, and it is not possible to jump directly into the middle of a loop. This information could be used to our advantage.</p> <p>Beyond that, a static PDF is far from ideal when exploring complicated graphs. Finding the inputs or uses of a given instruction is a tedious and frustrating exercise, as is following arrows from block to block. Even just zooming in and out is difficult. I eventually concluded that we ought to just build an interactive tool to overcome these limitations.</p> <h3>How hard could layout be?</h3> <p>I had one false start with graph layout, with an algorithm that attempted to sort blocks into vertical “tracks”. This broke down quickly on a variety of programs and I was forced to go back to the drawing board—in fact, back to the source of the very tool I was trying to replace.</p> <p>The algorithm used by <code class="language-plaintext highlighter-rouge">dot</code>, the typical hierarchical layout mode for Graphviz, is known as the Sugiyama layout algorithm, from a 1981 paper by Sugiyama et al. As introduction, I found a short series of <a href="https://www.youtube.com/watch?v=3_FbSCWLC3A&amp;list=PLubYOWSl9mIvoXDwf_Wqcrvlg15N_AWQE&amp;index=38">lectures</a> that broke down the Sugiyama algorithm into 5 steps:</p> <ol> <li><strong>Cycle breaking</strong>, where the direction of some edges are flipped in order to produce a <a href="https://en.wikipedia.org/wiki/Directed_acyclic_graph">DAG</a>.</li> <li><strong>Leveling</strong>, where vertices are assigned into horizontal layers according to their depth in the graph, and dummy vertices are added to any edge that crosses multiple layers.</li> <li><strong>Crossing minimization</strong>, where vertices on a layer are reordered in order to minimize the number of edge crossings.</li> <li><strong>Vertex positioning</strong>, where vertices are horizontally positioned in order to make the edges as straight as possible.</li> <li><strong>Drawing</strong>, where the final graph is rendered to the screen.</li></ol> <p><img alt="A screenshot from the lectures, showing the five steps above" src="https://spidermonkey.dev/assets/img/kindermann.png" /></p> <p>These steps struck me as surprisingly straightforward, and provided useful opportunities to insert our own knowledge of the problem:</p> <ul> <li>Cycle breaking would be trivial for us, since the only cycles in our data are loops, and loop backedges are explicitly labeled. We could simply ignore backedges when laying out the graph.</li> <li>Leveling would be straightforward, and could easily be modified to better mimic the source code. Specifically, any blocks coming after a loop in the source code could be artificially pushed down in the layout, solving the confusing early-exit problem.</li> <li>Permuting vertices to reduce edge crossings was actually just a bad idea, since our goal was stability from graph to graph. The true and false branches of a condition should always appear in the same order, for example, and a few edge crossings is a small price to pay for this stability.</li> <li>Since reducible control flow ensures that a program’s loops form a tree, vertex positioning could ensure that loops are always well-nested in the final graph.</li></ul> <p>Taken all together, these simplifications resulted in a remarkably straightforward algorithm, with the <a href="https://github.com/mozilla-spidermonkey/iongraph/blob/fc27ee3e8f3bd3c020aaf2498de9a260da089bc1/src/Graph.ts">initial implementation</a> being just 1000 lines of JavaScript. (See this <a href="https://x.com/its_bvisness/status/1957565307809329465?s=46">demo</a> for what it looked like at the time.) It also proved to be very efficient, since it avoided the most computationally complex parts of the Sugiyama algorithm.</p> <h3>iongraph from start to finish</h3> <p>We will now go through the entire iongraph layout algorithm. Each section contains explanatory diagrams, in which rectangles are basic blocks and circles are dummy nodes. Loop header blocks (the single entry point to each loop) are additionally colored green.</p> <p>Be aware that the block positions in these diagrams are not representative of the actual computed layout position at each point in the process. For example, vertical positions are not calculated until the very end, but it would be hard to communicate what the algorithm was doing if all blocks were drawn on a single line!</p> <h4>Step 1: Layering</h4> <p>We first sort the basic blocks into horizontal tracks called “layers”. This is very simple; we just start at layer 0 and recursively walk the graph, incrementing the layer number as we go. As we go, we track the “height” of each loop, not in pixels, but in layers.</p> <p>We also take this opportunity to vertically position nodes “inside” and “outside” of loops. Whenever we see an edge that exits a loop, we defer the layering of the destination block until we are done layering the loop contents, at which point we know the loop’s height.</p> <p>A note on implementation: nodes are visited multiple times throughout the process, not just once. This can produce a quadratic explosion for large graphs, but I find that an early-out is sufficient to avoid this problem in practice.</p> <p>The animation below shows the layering algorithm in action. Notice how the final block in the graph is visited twice, once after each loop that branches to it, and in each case, the block is deferred until the entire loop has been layered, rather than processed immediately after its predecessor block. The final position of the block is below the entirety of both loops, rather than directly below one of its predecessors as Graphviz would do. (Remember, horizontal and vertical positions have not yet been computed; the positions of the blocks in this diagram are hardcoded for demonstration purposes.)</p> <details>Implementation pseudocode<div></div></details> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/*CODEBLOCK=layering*/</span><span class="kd">function</span> <span class="nx">layerBlock</span><span class="p">(</span><span class="nx">block</span><span class="p">,</span> <span class="nx">layer</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Omitted for clarity: special handling of our "backedge blocks"</span> <span class="c1">// Early out if the block would not be updated</span> <span class="k">if</span> <span class="p">(</span><span class="nx">layer</span> <span class="o">&lt;=</span> <span class="nx">block</span><span class="p">.</span><span class="nx">layer</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span><span class="p">;</span> <span class="p">}</span> <span class="c1">// Update the layer of the current block</span> <span class="nx">block</span><span class="p">.</span><span class="nx">layer</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="nx">block</span><span class="p">.</span><span class="nx">layer</span><span class="p">,</span> <span class="nx">layer</span><span class="p">);</span> <span class="c1">// Update the heights of all loops containing the current block</span> <span class="kd">let</span> <span class="nx">header</span> <span class="o">=</span> <span class="nx">block</span><span class="p">.</span><span class="nx">loopHeader</span><span class="p">;</span> <span class="k">while</span> <span class="p">(</span><span class="nx">header</span><span class="p">)</span> <span class="p">{</span> <span class="nx">header</span><span class="p">.</span><span class="nx">loopHeight</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="nx">header</span><span class="p">.</span><span class="nx">loopHeight</span><span class="p">,</span> <span class="nx">block</span><span class="p">.</span><span class="nx">layer</span> <span class="o">-</span> <span class="nx">header</span><span class="p">.</span><span class="nx">layer</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span> <span class="nx">header</span> <span class="o">=</span> <span class="nx">header</span><span class="p">.</span><span class="nx">parentLoopHeader</span><span class="p">;</span> <span class="p">}</span> <span class="c1">// Recursively layer successors</span> <span class="k">for</span> <span class="p">(</span><span class="kd">const</span> <span class="nx">succ</span> <span class="k">of</span> <span class="nx">block</span><span class="p">.</span><span class="nx">successors</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="nx">succ</span><span class="p">.</span><span class="nx">loopDepth</span> <span class="o">&lt;</span> <span class="nx">block</span><span class="p">.</span><span class="nx">loopDepth</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Outgoing edges from the current loop will be layered later</span> <span class="nx">block</span><span class="p">.</span><span class="nx">loopHeader</span><span class="p">.</span><span class="nx">outgoingEdges</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">succ</span><span class="p">);</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="nx">layerBlock</span><span class="p">(</span><span class="nx">succ</span><span class="p">,</span> <span class="nx">layer</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="c1">// Layer any outgoing edges only after the contents of the loop have</span> <span class="c1">// been processed</span> <span class="k">if</span> <span class="p">(</span><span class="nx">block</span><span class="p">.</span><span class="nx">isLoopHeader</span><span class="p">())</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kd">const</span> <span class="nx">succ</span> <span class="k">of</span> <span class="nx">block</span><span class="p">.</span><span class="nx">outgoingEdges</span><span class="p">)</span> <span class="p">{</span> <span class="nx">layerBlock</span><span class="p">(</span><span class="nx">succ</span><span class="p">,</span> <span class="nx">layer</span> <span class="o">+</span> <span class="nx">block</span><span class="p">.</span><span class="nx">loopHeight</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span><span class="p">}</span></code></pre></div></div> <div class="ba" id="layeranim" style="background-color: white; width: 476px; height: 410px;"> <svg id="layerarrows" style="width: 100%; height: 100%;" xmlns="http://www.w3.org/2000/svg"></svg></div> <h4>Step 2: Create dummy nodes</h4> <p>Any time an edge crosses a layer, we create a dummy node. This allows edges to be routed across layers without overlapping any blocks. Unlike in traditional Sugiyama, we always put downward dummies on the left and upward dummies on the right, producing a consistent “counter-clockwise” flow. This also makes it easy to read long vertical edges, whose direction would otherwise be ambiguous. (Recall how the loop backedge flipped from the right to the left in the “unstable layout” Graphviz example from before.)</p> <p>In addition, we coalesce any edges that are going to the same destination by merging their dummy nodes. This heavily reduces visual noise.</p> <div class="ba" id="dummydiagram" style="background-color: white; width: 344px; height: 478px;"> <svg id="dummyarrows" style="width: 100%; height: 100%;" xmlns="http://www.w3.org/2000/svg"></svg></div> <h4>Step 3: Straighten edges</h4> <p>This is the fuzziest and most ad-hoc part of the process. Basically, we run lots of small passes that walk up and down the graph, aligning layout nodes with each other. Our edge-straightening passes include:</p> <ul> <li>Pushing nodes to the right of their loop header to “indent” them.</li> <li>Walking a layer left to right, moving children to the right to line up with their parents. If any nodes overlap as a result, they are pushed further to the right.</li> <li>Walking a layer right to left, moving parents to the right to line up with their children. This version is more conservative and will not move a node if it would overlap with another. This cleans up most issues from the first pass.</li> <li>Straightening runs of dummy nodes so we have clean vertical lines.</li> <li>“Sucking in” dummy runs on the left side of the graph if there is room for them to move to the right.</li> <li>Straighten out any edges that are “nearly straight”, according to a chosen threshold. This makes the graph appear less wobbly. We do this by repeatedly “combing” the graph upward and downward, aligning parents with children, then children with parents, and so on.</li></ul> <p>It is important to note that dummy nodes participate fully in this system. If for example you have two side-by-side loops, straightening the left loop’s backedge will push the right loop to the side, avoiding overlaps and preserving the graph’s visual structure.</p> <p>We do not reach a fixed point with this strategy, nor do we attempt to. I find that if you continue to repeatedly apply these particular layout passes, nodes will wander to the right forever. Instead, the layout passes are hand-tuned to produce decent-looking results for most of the graphs we look at on a regular basis. That said, this could certainly be improved, especially for larger graphs which do benefit from more iterations.</p> <p>At the end of this step, all nodes have a fixed X-coordinate and will not be modified further.</p> <div class="ba" id="edgediagram" style="background-color: white; width: 384px; height: 498px;"> <svg id="edgearrows" style="width: 100%; height: 100%;" xmlns="http://www.w3.org/2000/svg"></svg></div> <h4>Step 4: Track horizontal edges</h4> <p>Edges may overlap visually as they run horizontally between layers. To resolve this, we sort edges into parallel “tracks”, giving each a vertical offset. After tracking all the edges, we record the total height of the tracks and store it on the preceding layer as its “track height”. This allows us to leave room for the edges in the final layout step.</p> <p>We first sort edges by their starting position, left to right. This produces a consistent arrangement of edges that has few vertical crossings in practice. Edges are then placed into tracks from the “outside in”, stacking rightward edges on top and leftward edges on the bottom, creating a new track if the edge would overlap with or cross any other edge.</p> <p>The diagram below is interactive. Click and drag the blocks to see how the horizontal edges get assigned to tracks.</p> <details>Implementation pseudocode<div></div></details> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/*CODEBLOCK=tracks*/</span><span class="kd">function</span> <span class="nx">trackHorizontalEdges</span><span class="p">(</span><span class="nx">layer</span><span class="p">)</span> <span class="p">{</span> <span class="kd">const</span> <span class="nx">TRACK_SPACING</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span> <span class="c1">// Gather all edges on the layer, and sort left to right by starting coordinate</span> <span class="kd">const</span> <span class="nx">layerEdges</span> <span class="o">=</span> <span class="p">[];</span> <span class="k">for</span> <span class="p">(</span><span class="kd">const</span> <span class="nx">node</span> <span class="k">of</span> <span class="nx">layer</span><span class="p">.</span><span class="nx">nodes</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kd">const</span> <span class="nx">edge</span> <span class="k">of</span> <span class="nx">node</span><span class="p">.</span><span class="nx">edges</span><span class="p">)</span> <span class="p">{</span> <span class="nx">layerEdges</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">edge</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="nx">layerEdges</span><span class="p">.</span><span class="nx">sort</span><span class="p">((</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">a</span><span class="p">.</span><span class="nx">startX</span> <span class="o">-</span> <span class="nx">b</span><span class="p">.</span><span class="nx">startX</span><span class="p">);</span> <span class="c1">// Assign edges to "tracks" based on whether they overlap horizontally with</span> <span class="c1">// each other. We walk the tracks from the outside in and stop if we ever</span> <span class="c1">// overlap with any other edge.</span> <span class="kd">const</span> <span class="nx">rightwardTracks</span> <span class="o">=</span> <span class="p">[];</span> <span class="c1">// [][]Edge</span> <span class="kd">const</span> <span class="nx">leftwardTracks</span> <span class="o">=</span> <span class="p">[];</span> <span class="c1">// [][]Edge</span> <span class="nl">nextEdge</span><span class="p">:</span> <span class="k">for</span> <span class="p">(</span><span class="kd">const</span> <span class="nx">edge</span> <span class="k">of</span> <span class="nx">layerEdges</span><span class="p">)</span> <span class="p">{</span> <span class="kd">const</span> <span class="nx">trackSet</span> <span class="o">=</span> <span class="nx">edge</span><span class="p">.</span><span class="nx">endX</span> <span class="o">-</span> <span class="nx">edge</span><span class="p">.</span><span class="nx">startX</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="p">?</span> <span class="nx">rightwardTracks</span> <span class="p">:</span> <span class="nx">leftwardTracks</span><span class="p">;</span> <span class="kd">let</span> <span class="nx">lastValidTrack</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span> <span class="c1">// []Edge | null</span> <span class="c1">// Iterate through the tracks in reverse order (outside in)</span> <span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">i</span> <span class="o">=</span> <span class="nx">trackSet</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span><span class="o">--</span><span class="p">)</span> <span class="p">{</span> <span class="kd">const</span> <span class="nx">track</span> <span class="o">=</span> <span class="nx">trackSet</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span> <span class="kd">let</span> <span class="nx">overlapsWithAnyInThisTrack</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="kd">const</span> <span class="nx">otherEdge</span> <span class="k">of</span> <span class="nx">track</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="nx">edge</span><span class="p">.</span><span class="nx">dst</span> <span class="o">===</span> <span class="nx">otherEdge</span><span class="p">.</span><span class="nx">dst</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Assign the edge to this track to merge arrows</span> <span class="nx">track</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">edge</span><span class="p">);</span> <span class="k">continue</span> <span class="nx">nextEdge</span><span class="p">;</span> <span class="p">}</span> <span class="kd">const</span> <span class="nx">al</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">(</span><span class="nx">edge</span><span class="p">.</span><span class="nx">startX</span><span class="p">,</span> <span class="nx">edge</span><span class="p">.</span><span class="nx">endX</span><span class="p">);</span> <span class="kd">const</span> <span class="nx">ar</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="nx">edge</span><span class="p">.</span><span class="nx">startX</span><span class="p">,</span> <span class="nx">edge</span><span class="p">.</span><span class="nx">endX</span><span class="p">);</span> <span class="kd">const</span> <span class="nx">bl</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">(</span><span class="nx">otherEdge</span><span class="p">.</span><span class="nx">startX</span><span class="p">,</span> <span class="nx">otherEdge</span><span class="p">.</span><span class="nx">endX</span><span class="p">);</span> <span class="kd">const</span> <span class="nx">br</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="nx">otherEdge</span><span class="p">.</span><span class="nx">startX</span><span class="p">,</span> <span class="nx">otherEdge</span><span class="p">.</span><span class="nx">endX</span><span class="p">);</span> <span class="kd">const</span> <span class="nx">overlaps</span> <span class="o">=</span> <span class="nx">ar</span> <span class="o">&gt;=</span> <span class="nx">bl</span> <span class="o">&amp;&amp;</span> <span class="nx">al</span> <span class="o">&lt;=</span> <span class="nx">br</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="nx">overlaps</span><span class="p">)</span> <span class="p">{</span> <span class="nx">overlapsWithAnyInThisTrack</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="nx">overlapsWithAnyInThisTrack</span><span class="p">)</span> <span class="p">{</span> <span class="k">break</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="nx">lastValidTrack</span> <span class="o">=</span> <span class="nx">track</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="nx">lastValidTrack</span><span class="p">)</span> <span class="p">{</span> <span class="nx">lastValidTrack</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">edge</span><span class="p">);</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="nx">trackSet</span><span class="p">.</span><span class="nx">push</span><span class="p">([</span><span class="nx">edge</span><span class="p">]);</span> <span class="p">}</span> <span class="p">}</span> <span class="c1">// Use track info to apply offsets to each edge for rendering.</span> <span class="kd">const</span> <span class="nx">tracksHeight</span> <span class="o">=</span> <span class="nx">TRACK_SPACING</span> <span class="o">*</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">rightwardTracks</span><span class="p">.</span><span class="nx">length</span> <span class="o">+</span> <span class="nx">leftwardTracks</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="p">);</span> <span class="kd">let</span> <span class="nx">trackOffset</span> <span class="o">=</span> <span class="o">-</span><span class="nx">tracksHeight</span> <span class="o">/</span> <span class="mi">2</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="kd">const</span> <span class="nx">track</span> <span class="k">of</span> <span class="p">[...</span><span class="nx">rightwardTracks</span><span class="p">.</span><span class="nx">toReversed</span><span class="p">(),</span> <span class="p">...</span><span class="nx">leftwardTracks</span><span class="p">])</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kd">const</span> <span class="nx">edge</span> <span class="k">of</span> <span class="nx">track</span><span class="p">)</span> <span class="p">{</span> <span class="nx">edge</span><span class="p">.</span><span class="nx">offset</span> <span class="o">=</span> <span class="nx">trackOffset</span><span class="p">;</span> <span class="p">}</span> <span class="nx">trackOffset</span> <span class="o">+=</span> <span class="nx">TRACK_SPACING</span><span class="p">;</span> <span class="p">}</span><span class="p">}</span></code></pre></div></div> <div class="ba" id="trackdiagram" style="background-color: white; width: 303px; height: 180px;"> <svg id="trackarrows" style="width: 100%; height: 100%;" xmlns="http://www.w3.org/2000/svg"></svg></div> <h4>Step 5: Verticalize</h4> <p>Finally, we assign each node a Y-coordinate. Starting at a Y-coordinate of zero, we iterate through the layers, repeatedly adding the layer’s height and its track height, where the layer height is the maximum height of any node in the layer. All nodes within a layer receive the same Y-coordinate; this is simple and easier to read than Graphviz’s default of vertically centering nodes within a layer.</p> <p>Now that every node has both an X and Y coordinate, the layout process is complete.</p> <details>Implementation pseudocode<div></div></details> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/*CODEBLOCK=verticalize*/</span><span class="kd">function</span> <span class="nx">verticalize</span><span class="p">(</span><span class="nx">layers</span><span class="p">)</span> <span class="p">{</span> <span class="kd">let</span> <span class="nx">layerY</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="kd">const</span> <span class="nx">layer</span> <span class="k">of</span> <span class="nx">layers</span><span class="p">)</span> <span class="p">{</span> <span class="kd">let</span> <span class="nx">layerHeight</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="kd">const</span> <span class="nx">node</span> <span class="k">of</span> <span class="nx">layer</span><span class="p">.</span><span class="nx">nodes</span><span class="p">)</span> <span class="p">{</span> <span class="nx">node</span><span class="p">.</span><span class="nx">y</span> <span class="o">=</span> <span class="nx">layerY</span><span class="p">;</span> <span class="nx">layerHeight</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="nx">layerHeight</span><span class="p">,</span> <span class="nx">node</span><span class="p">.</span><span class="nx">height</span><span class="p">);</span> <span class="p">}</span> <span class="nx">layerY</span> <span class="o">+=</span> <span class="nx">layerHeight</span><span class="p">;</span> <span class="nx">layerY</span> <span class="o">+=</span> <span class="nx">layer</span><span class="p">.</span><span class="nx">trackHeight</span><span class="p">;</span> <span class="p">}</span><span class="p">}</span></code></pre></div></div> <div class="ba" id="verticalizediagram" style="background-color: white; width: 384px; height: 518px;"> <svg id="verticalizearrows" style="width: 100%; height: 100%;" xmlns="http://www.w3.org/2000/svg"></svg></div> <h4>Step 6: Render</h4> <p>The details of rendering are out of scope for this article, and depend on the specific application. However, I wish to highlight a stylistic decision that I feel makes our graphs more readable.</p> <p>When rendering edges, we use a style inspired by <a href="https://en.wikipedia.org/wiki/Syntax_diagram">railroad diagrams</a>. These have many advantages over the Bézier curves employed by Graphviz. First, straight lines feel more organized and are easier to follow when scrolling up and down. Second, they are easy to route (vertical when crossing layers, horizontal between layers). Third, they are easy to coalesce when they share a destination, and the junctions provide a clear indication of the edge’s direction. Fourth, they always cross at right angles, improving clarity and reducing the need to avoid edge crossings in the first place.</p> <p>Consider the following example. There are several edge crossings that may traditionally be considered undesirable—yet the edges and their directions remain clear. Of particular note is the vertical junction highlighted in red on the left: not only is it immediately clear that these edges share a destination, but the junction itself signals that the edges are flowing downward. I find this much more pleasant than the “rat’s nest” that Graphviz tends to produce.</p> <p><img alt="Examples of railroad-diagram edges" src="https://spidermonkey.dev/assets/img/iongraph-edge-examples-highlighted.png" width="716" /></p> <h3>Why does this work?</h3> <p>It may seem surprising that such a simple (and stupid) layout algorithm could produce such readable graphs, when more sophisticated layout algorithms struggle. However, I feel that the algorithm succeeds <em>because</em> of its simplicity.</p> <p>Most graph layout algorithms are optimization problems, where error is minimized on some chosen metrics. However, these metrics seem to correlate poorly to readability in practice. For example, it seems good in theory to rearrange nodes to minimize edge crossings. But a predictable order of nodes seems to produce more sensible results overall, and simple rules for edge routing are sufficient to keep things tidy. (As a bonus, this also gives us layout stability from pass to pass.) Similarly, layout rules like “align parents with their children” produce more readable results than “minimize the lengths of edges”.</p> <p>Furthermore, by rejecting the optimization problem, a human author gains more control over the layout. We are able to position nodes “inside” of loops, and push post-loop content down in the graph, <em>because</em> we reject this global constraint-solver approach. Minimizing “error” is meaningless compared to a human <em>maximizing</em> meaning through thoughtful design.</p> <p>And finally, the resulting algorithm is simply more efficient. All the layout passes in iongraph are easy to program and scale gracefully to large graphs because they run in roughly linear time. It is better, in my view, to run a fixed number of layout iterations according to your graph complexity and time budget, rather than to run a complex constraint solver until it is “done”.</p> <p>By following this philosophy, even the worst graphs become tractable. Below is a screenshot of a zlib function, compiled to WebAssembly, and rendered using the old tool.</p> <p><img alt="spaghetti nightmare!!" src="https://spidermonkey.dev/assets/img/iongraph-spaghetti-nightmare.png" /></p> <p>It took about <strong>ten minutes</strong> for Graphviz to produce this spaghetti nightmare. By comparison, iongraph can now lay out this function in <strong>20 milliseconds</strong>. The result is still not particularly beautiful, but it renders thousands of times faster <em>and</em> is much easier to navigate.</p> <p><img alt="better spaghetti" src="https://spidermonkey.dev/assets/img/iongraph-zlib.png" /></p> <p>Perhaps programmers ought to put less trust into magic optimizing systems, especially when a human-friendly result is the goal. Simple (and stupid) algorithms can be very effective when applied with discretion and taste.</p> <h3>Future work</h3> <p>We have already integrated iongraph into the Firefox profiler, making it easy for us to view the graphs of the most expensive or impactful functions we find in our performance work. Unfortunately, this is only available in specific builds of the SpiderMonkey shell, and is not available in full browser builds. This is due to architectural differences in how profiling data is captured and the flags with which the browser and shell are built. I would love for Firefox users to someday be able to view these graphs themselves, but at the moment we have no plans to expose this to the browser. However, one bug tracking some related work can be found <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1987005">here</a>.</p> <p>We will continue to sporadically update iongraph with more features to aid us in our work. We have several ideas for new features, including <a href="https://github.com/mozilla-spidermonkey/iongraph/issues/9">richer navigation</a>, search, and visualization of <a href="https://github.com/mozilla-spidermonkey/iongraph/issues/4">register allocation info</a>. However, we have no explicit roadmap for when these features may be released.</p> <p>To experiment with iongraph locally, you can run a debug build of the SpiderMonkey shell with <code class="language-plaintext highlighter-rouge">IONFLAGS=logs</code>; this will dump information to <code class="language-plaintext highlighter-rouge">/tmp/ion.json</code>. This file can then be loaded into the <a href="https://mozilla-spidermonkey.github.io/iongraph/">standalone deployment of iongraph</a>. Please be aware that the user experience is rough and unpolished in its current state.</p> <p>The source code for iongraph can be found on <a href="https://github.com/mozilla-spidermonkey/iongraph">GitHub</a>. If this subject interests you, we would welcome contributions to iongraph and its integration into the browser. The best place to reach us is our <a href="https://chat.mozilla.org/#/room/#spidermonkey:mozilla.org">Matrix chat</a>.</p> <hr /> <p><em>Thanks to Matthew Gaudet, Asaf Gartner, and Colin Davidson for their feedback on this article.</em></p></description> <pubDate>Tue, 28 Oct 2025 17:00:00 +0000</pubDate> <dc:creator>Ben Visness</dc:creator></item><item> <title>Will Kahn-Greene: Open Source Project Maintenance 2025</title> <guid isPermaLink="true">https://bluesock.org/~willkg/blog/dev/maintenance_2025.html</guid> <link>https://bluesock.org/~willkg/blog/dev/maintenance_2025.html</link> <description><div><p>Every October, I do a maintenance pass on all my projects. At a minimum, thatinvolves dropping support for whatever Python version is no longer supportedand adding support for the most recently released Python version. While doingthat, I go through the issue tracker, answer questions, and fix whatever I canfix. Then I release new versions. Then I think about which projects I shoulddeprecate and figure out a deprecation plan for them.</p><p>This post covers the 2025 round.</p><p>TL;DR</p><ul class="simple"><li><p><a class="reference external" href="https://pypi.org/project/sphinx-js/">sphinx-js</a> -- transferred to<a class="reference external" href="https://github.com/pyodide">pyodide organization</a></p></li><li><p><a class="reference external" href="https://pypi.org/project/crashstats-tools/">crashstats-tools</a> and<a class="reference external" href="https://pypi.org/project/siggen/">siggen</a> -- transferred to the Mozillacrash ingestion team, which I'm no longer on</p></li><li><p><a class="reference external" href="https://pypi.org/project/paul-mclendahand/">paul-mclendahand</a> -- deprecated and archived</p></li><li><p><a class="reference external" href="https://github.com/willkg/pip-stale/">pip-stale</a> -- deprecated and archived</p></li><li><p><a class="reference external" href="https://pypi.org/project/everett/">everett</a> -- released v3.5.0, then deprecated and archived</p></li><li><p><a class="reference external" href="https://pypi.org/project/fillmore/">fillmore</a> -- released v2.2.0, then deprecated and archived</p></li><li><p><a class="reference external" href="https://pypi.org/project/kent/">kent</a> -- released v2.2.0</p></li><li><p><a class="reference external" href="https://pypi.org/project/markus/">markus</a> -- released v5.2.0</p></li><li><p><a class="reference external" href="https://pypi.org/project/bleach/">bleach</a> -- released v6.3.0</p></li></ul><p><a href="https://bluesock.org/~willkg/blog/dev/maintenance_2025.html">Read more…</a> (7 min remaining to read)</p></div></description> <pubDate>Tue, 28 Oct 2025 14:00:00 +0000</pubDate> <dc:creator>Will Kahn-Greene</dc:creator></item><item> <title>Mozilla Attack & Defense: Firefox Security & Privacy Newsletter 2025 Q3</title> <guid isPermaLink="false">https://attackanddefense.dev/2025/10/28/firefox-security-privacy-newsletter-2025-q3</guid> <link>https://attackanddefense.dev/2025/10/28/firefox-security-privacy-newsletter-2025-q3.html</link> <description><p>Welcome to the Q3 2025 edition of the Firefox Security and Privacy newsletter!</p> <p>Security and Privacy on the web are the cornerstones of <a href="https://www.mozilla.org/en-US/about/manifesto/">Mozilla’s manifesto</a>, and they influence how we operate and build our products. Following are the highlights of our work from Q3 2025, grouped into the following categories:</p> <ul> <li><strong>Firefox Product Security &amp; Privacy</strong>, showcasing new Security &amp; Privacy Features and Integrations in Firefox.</li> <li><strong>Firefox for Enterprise</strong>, highlighting security &amp; privacy updates for administrative features, like Enterprise policies.</li> <li><strong>Core Security</strong>, outlining Security and Hardening efforts within the Firefox Platform.</li> <li><strong>Web Security and Standards</strong>, allowing websites to better protect themselves against online threats.</li></ul> <h3>Preface</h3> <p>Note: Some of the bugs linked below might not be accessible to the general public and restricted to specific work groups. <a href="https://firefox-source-docs.mozilla.org/bug-mgmt/processes/fixing-security-bugs.html#keeping-private-information-private">We de-restrict fixed security bugs after a grace-period</a>, until the majority of our user population have received Firefox updates. If a link does not work for you, please accept this as a precaution for the safety of all Firefox users.</p> <h3>Firefox Product Security &amp; Privacy</h3> <ul> <li>As a follow-up to our <a href="https://attackanddefense.dev/2025/07/17/firefox-security-privacy-newsletter-2025-q2.html">last newsletter</a>, <strong>Firefox has won a “Speedrunner” Award</strong> by the TrendMicro Zero Day Initiative for being consistently fast to patch security vulnerabilities. This is the second consecutive year, in which Firefox is recognized for the speedy delivery of security updates.</li> <li><strong>Protecting against Fingerprinting-based tracking:</strong> With Firefox 143, we’ve introduced new defenses against online fingerprinting. Our analysis of the most frequently exploited user data shows that it’s possible to significantly lower the success rate of fingerprinting attacks, without compromising a user’s browsing experience. Specifically, Firefox now standardizes how it reports device attributes such as CPU core count, screen size, and touch input capabilities. By unifying these values across our entire user base, we cut the share of Firefox users who appear unique to fingerprinting scripts from roughly 35% to just 20%.</li> <li><strong>Strict Tracking Protection with web compatibility in mind:</strong> When users set Firefox’s tracking protection to strict, we already warn them that stricter blocking may result in missing content or broken websites. As of Firefox 142, we are providing a list of exceptions that may <a href="https://support.mozilla.org/en-US/kb/manage-enhanced-tracking-protection-exceptions">help unbreak popular websites</a> without compromising the protection. The list of exceptions is transparently shared on <a href="https://etp-exceptions.mozilla.org/">https://etp-exceptions.mozilla.org/</a>.</li> <li><strong>DoH on Android</strong>: We have landed opt-in support for DoH Android in Firefox 143. Opt-in available in Firefox preferences UI, Firefox Android users can enable DoH with <a href="https://support.mozilla.org/en-US/kb/configure-dns-over-https-protection-levels-firefox-android#w_protection-levels-explained">Increased or Max Protection settings</a> to prevent network observers from tracking their browsing behaviour.</li> <li><strong>Improved TLS Error Pages:</strong> We improved non-overridable TLS error pages to provide more context for end users. Starting in Fx140, Firefox contains more information on why a connection was blocked, highlighting that Firefox is not causing the problem but rather that the website has a security problem and Firefox is actually keeping the user safe.</li> <li><strong>SafeBrowsing v5</strong>: Firefox Nightly now supports the <a href="https://developers.google.com/safe-browsing/reference">SafeBrowsing v5 protocol</a>, which protects against threats like phishing or malware sites, in preparation for the upcoming decommissioning of SafeBrowsing v4 server.</li> <li><strong>Private Downloads in Private Browsing:</strong> When downloading a file in Private Browsing mode, Firefox 143 now <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1981504">asks</a> whether to keep or delete the files after that session ends. You can adjust this behavior in Settings, if desired.</li> <li><strong>Improved Video sharing:</strong> As of Firefox 143, the browser permission dialog will now show a preview of the selected Video camera, making it much easier to see and decide what is being shared before providing camera permissions to a page.</li></ul> <h3>Firefox for Enterprise</h3> <ul> <li><strong>Updated Enterprise Policy for Tracking Protection:</strong> The <a href="https://mozilla.github.io/policy-templates/#enabletrackingprotection">EnableTrackingProtection</a> policy has been updated to allow you to set the category to either <code class="language-plaintext highlighter-rouge">strict</code> or <code class="language-plaintext highlighter-rouge">standard</code>. When the category is set using this policy, the user cannot change it. The <a href="https://mozilla.github.io/policy-templates/#enabletrackingprotection">EnableTrackingProtection</a> policy has also been updated to allow you to set control Suspected fingerprinters. For more information, see <a href="https://support.mozilla.org/kb/firefox-protection-against-fingerprinting#w_suspected-fingerprinters">this SUMO page</a>.</li> <li><strong>Improved Control over SVG, MathML, WebGL, CSP reporting and Fingerprinting Protection:</strong> The <a href="https://mozilla.github.io/policy-templates/#preferences">Preferences</a> policy has been updated to allow setting the preferences <code class="language-plaintext highlighter-rouge">mathml.disabled</code>, <code class="language-plaintext highlighter-rouge">svg.context-properties.content.enabled</code>, <code class="language-plaintext highlighter-rouge">svg.disabled</code>, <code class="language-plaintext highlighter-rouge">webgl.disabled</code>, <code class="language-plaintext highlighter-rouge">webgl.force-enabled</code>, <code class="language-plaintext highlighter-rouge">xpinstall.enabled</code>, and <code class="language-plaintext highlighter-rouge">security.csp.reporting.enabled</code> as well as prefs beginning with <code class="language-plaintext highlighter-rouge">privacy.baselineFingerprintingProtection</code> or <code class="language-plaintext highlighter-rouge">privacy.fingerprintingProtection.</code></li></ul> <h3>Core Security</h3> <ul> <li><strong>CRLite on Desktop and Mobile</strong>: CRLite is a faster, more reliable and privacy-protecting certificate revocation check mechanism, as compared to the traditional OCSP (Online Certificate Status Protocol). CRLite is available in Desktop versions since Firefox 142 and on Firefox for Android in Firefox 145. Read details on CRLite in the blogpost: <a href="https://hacks.mozilla.org/2025/08/crlite-fast-private-and-comprehensive-certificate-revocation-checking-in-firefox/">CRLite: Fast, private, and comprehensive certificate revocation checking in Firefox</a>.</li> <li><strong>Supporting Certificate Compression in QUIC</strong>: Certificate compression reduces the size of certificate chains during a Transport Layer Security (TLS) handshake, which improves performance by lowering latency and bandwidth consumption. The three compression algorithms zlib, brotli, and zstd are available in QUIC starting with Firefox 143.</li></ul> <h3>Web Security &amp; Standards</h3> <ul> <li><strong>Improved Cache removal:</strong> When a website uses the <code class="language-plaintext highlighter-rouge">"cache"</code> directive of the <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Clear-Site-Data"><code class="language-plaintext highlighter-rouge">Clear-Site-Data</code></a> response header, Firefox 141 now also clears the backwards-forwards cache (<a href="https://developer.mozilla.org/en-US/docs/Glossary/bfcache">bfcache</a>). This allows a site to ensure that private session details can be removed, even if a user uses the browser back button. (<a href="https://bugzil.la/1930501">bug 1930501</a>).</li> <li><strong>Easy URL Pattern Matching</strong>: The <a href="https://developer.mozilla.org/en-US/docs/Web/API/URL_Pattern_API">URL Pattern API</a> is fully supported as of Firefox 142, enabling you to match and parse URLs using a standardized pattern syntax. (<a href="https://bugzil.la/1731418">bug 1731418</a>).</li></ul> <h3>Going Forward</h3> <p>As a Firefox user, you will automatically benefit from all the mentioned security and privacy benefits with the enabled auto-updates in Firefox. If you aren’t a Firefox user yet, you can <a href="https://www.mozilla.org/firefox/new/?_gl=1*3c2zyd*_ga*MTkzMzM4MjE2NC4xNjc0NzM5NDMy*_ga_X4N05QV93S*MTc0NTg0NzU4Ny4xODIuMS4xNzQ1ODQ3NjM5LjAuMC4w">download Firefox</a> to experience a fast and safe browsing experience while supporting Mozilla’s mission of a healthy, safe and accessible web for everyone.</p> <p>Thanks to everyone who helps make Firefox and the open web more secure and privacy-respecting.</p> <p>See you next time with the Q4 2025 Report!<br />- Firefox Security and Privacy Teams.</p></description> <pubDate>Tue, 28 Oct 2025 13:06:37 +0000</pubDate> <dc:creator>Frederik Braun, Christoph Kerschbaumer</dc:creator></item><item> <title>The Rust Programming Language Blog: Project goals for 2025H2</title> <guid isPermaLink="true">https://blog.rust-lang.org/2025/10/28/project-goals-2025h2/</guid> <link>https://blog.rust-lang.org/2025/10/28/project-goals-2025h2/</link> <description><p>On Sep 9, we merged <a href="https://github.com/rust-lang/rfcs/pull/3849">RFC 3849</a>, declaring our goals for the "second half" of 2025H2 -- well, the last 3 months, at least, since "yours truly" ran a bit behind getting the goals program organized.</p><h4><a class="anchor" href="https://blog.rust-lang.org/2025/10/28/project-goals-2025h2/#flagship-themes"></a>Flagship themes</h4><p>In prior goals programs, we had a few major flagship goals, but since many of these goals were multi-year programs, it was hard to see what progress had been made. This time we decided to organize things a bit differently. We established four flagship <em>themes</em>, each of which covers a number of more specific goals. These themes cover the goals we expect to be the most impactful and constitute our major focus as a Project for the remainder of the year. The four themes identified in the RFC are as follows:</p><ul><li><strong>Beyond the <code>&amp;</code></strong>, making it possible to create user-defined smart pointers that are as ergonomic as Rust's built-in references <code>&amp;</code>.</li><li><strong>Unblocking dormant traits</strong>, extending the core capabilities of Rust's trait system to unblock long-desired features for language interop, lending iteration, and more.</li><li><strong>Flexible, fast(er) compilation</strong>, making it faster to build Rust programs and improving support for specialized build scenarios like embedded usage and sanitizers.</li><li><strong>Higher-level Rust</strong>, making higher-level usage patterns in Rust easier.</li></ul><h5><a class="anchor" href="https://blog.rust-lang.org/2025/10/28/project-goals-2025h2/#beyond-the"></a>"Beyond the <code>&amp;</code>"</h5><table><thead><tr><th style="text-align: left;">Goal</th><th style="text-align: left;">Point of contact</th><th style="text-align: left;">Team(s) and Champion(s)</th></tr></thead><tbody><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/autoreborrow-traits.html">Reborrow traits</a></td><td style="text-align: left;"><a href="https://github.com/aapoalas">Aapo Alasuutari</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a> (<a href="https://github.com/oli-obk">Oliver Scherer</a>), <a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/tmandry">Tyler Mandry</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/field-projections.html">Design a language feature to solve Field Projections</a></td><td style="text-align: left;"><a href="https://github.com/BennoLossin">Benno Lossin</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/tmandry">Tyler Mandry</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/pin-ergonomics.html">Continue Experimentation with Pin Ergonomics</a></td><td style="text-align: left;"><a href="https://github.com/frank-king">Frank King</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a> (<a href="https://github.com/oli-obk">Oliver Scherer</a>), <a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/traviscross">TC</a>)</td></tr></tbody></table><p>One of Rust's core value propositions is that it's a "library-based language"—libraries can build abstractions that feel built-in to the language even when they're not. Smart pointer types like <code>Rc</code> and <code>Arc</code> are prime examples, implemented purely in the standard library yet feeling like native language features. However, Rust's built-in reference types (<code>&amp;T</code> and <code>&amp;mut T</code>) have special capabilities that user-defined smart pointers cannot replicate. This creates a "second-class citizen" problem where custom pointer types can't provide the same ergonomic experience as built-in references.</p><p>The "Beyond the <code>&amp;</code>" initiative aims to share the special capabilities of <code>&amp;</code>, allowing library authors to create smart pointers that are truly indistinguishable from built-in references in terms of syntax and ergonomics. This will enable more ergonomic smart pointers for use in cross-language interop (e.g., references to objects in other languages like C++ or Python) and for low-level projects like Rust for Linux that use smart pointers to express particular data structures.</p><h5><a class="anchor" href="https://blog.rust-lang.org/2025/10/28/project-goals-2025h2/#unblocking-dormant-traits"></a>"Unblocking dormant traits"</h5><table><thead><tr><th style="text-align: left;">Goal</th><th style="text-align: left;">Point of contact</th><th style="text-align: left;">Team(s) and Champion(s)</th></tr></thead><tbody><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/evolving-traits.html">Evolving trait hierarchies</a></td><td style="text-align: left;"><a href="https://github.com/cramertj">Taylor Cramer</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a>, <a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/cramertj">Taylor Cramer</a>), <a href="https://www.rust-lang.org/governance/teams">libs-api</a>, <a href="https://github.com/rust-lang/types-team">types</a> (<a href="https://github.com/oli-obk">Oliver Scherer</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/in-place-initialization.html">In-place initialization</a></td><td style="text-align: left;"><a href="https://github.com/Darksonn">Alice Ryhl</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/cramertj">Taylor Cramer</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/next-solver.html">Next-generation trait solver</a></td><td style="text-align: left;"><a href="https://github.com/lcnr">lcnr</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/types-team">types</a> (<a href="https://github.com/lcnr">lcnr</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/polonius.html">Stabilizable Polonius support on nightly</a></td><td style="text-align: left;"><a href="https://github.com/lqd">Rémy Rakic</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/types-team">types</a> (<a href="https://github.com/jackh726">Jack Huey</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/scalable-vectors.html">SVE and SME on AArch64</a></td><td style="text-align: left;"><a href="https://github.com/davidtwco">David Wood</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a> (<a href="https://github.com/davidtwco">David Wood</a>), <a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/nikomatsakis">Niko Matsakis</a>), <a href="https://github.com/rust-lang/libs-team">libs</a> (<a href="https://github.com/Amanieu">Amanieu d'Antras</a>), <a href="https://github.com/rust-lang/types-team">types</a></td></tr></tbody></table><p>Rust's trait system is one of its most powerful features, but it has a number of longstanding limitations that are preventing us from adopting new patterns. The goals in this category unblock a number of new capabilities:</p><ul><li><a href="https://rust-lang.github.io/rust-project-goals/2025h2/./polonius.html">Polonius</a> will enable new borrowing patterns, and in particular <a href="https://github.com/rust-lang/rust/issues/92985">unblock "lending iterators"</a>. Over the last few goal periods, we have identified an "alpha" version of Polonius that addresses the most important cases while being relatively simple and optimizable. Our goal for 2025H2 is to implement this algorithm in a form that is ready for stabilization in 2026.</li><li>The <a href="https://rust-lang.github.io/rust-project-goals/2025h2/./next-solver.html">next-generation trait solver</a> is a refactored trait solver that unblocks better support for numerous language features (implied bounds, negative impls, the list goes on) in addition to closing a number of existing bugs and sources of unsoundness. Over the last few goal periods, the trait solver went from being an early prototype to being in production use for coherence checking. The goal for 2025H2 is to prepare it for stabilization.</li><li>The work on <a href="https://rust-lang.github.io/rust-project-goals/2025h2/./evolving-traits.html">evolving trait hierarchies</a> will make it possible to refactor some parts of an existing trait into a new supertrait so they can be used on their own. This unblocks a number of features where the existing trait is insufficiently general, in particular stabilizing support for custom receiver types, a prior Project goal that wound up blocked on this refactoring. This will also make it safer to provide stable traits in the standard library while preserving the ability to evolve them in the future.</li><li>The work to <a href="https://rust-lang.github.io/rust-project-goals/2025h2/./scalable-vectors.html">expand Rust's <code>Sized</code> hierarchy</a> will permit us to express types that are neither <code>Sized</code> nor <code>?Sized</code>, such as extern types (which have no size) or Arm's Scalable Vector Extension (which have a size that is known at runtime but not at compilation time). This goal builds on <a href="https://github.com/rust-lang/rfcs/pull/3729">RFC #3729</a> and <a href="https://github.com/rust-lang/rfcs/pull/3838">RFC #3838</a>, authored in previous Project goal periods.</li><li><a href="https://rust-lang.github.io/rust-project-goals/2025h2/./in-place-initialization.html">In-place initialization</a> allows creating structs and values that are tied to a particular place in memory. While useful directly for projects doing advanced C interop, it also unblocks expanding <code>dyn Trait</code> to support <code>async fn</code> and <code>-&gt; impl Trait</code> methods, as compiling such methods requires the ability for the callee to return a future whose size is not known to the caller.</li></ul><h5><a class="anchor" href="https://blog.rust-lang.org/2025/10/28/project-goals-2025h2/#flexible-fast-er-compilation"></a>"Flexible, fast(er) compilation"</h5><table><thead><tr><th style="text-align: left;">Goal</th><th style="text-align: left;">Point of contact</th><th style="text-align: left;">Team(s) and Champion(s)</th></tr></thead><tbody><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/build-std.html">build-std</a></td><td style="text-align: left;"><a href="https://github.com/davidtwco">David Wood</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/cargo">cargo</a> (<a href="https://github.com/ehuss">Eric Huss</a>), <a href="http://github.com/rust-lang/compiler-team">compiler</a> (<a href="https://github.com/davidtwco">David Wood</a>), <a href="https://github.com/rust-lang/libs-team">libs</a> (<a href="https://github.com/Amanieu">Amanieu d'Antras</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/parallel-front-end.html">Promoting Parallel Front End</a></td><td style="text-align: left;"><a href="https://github.com/SparrowLii">Sparrow Li</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a></td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/production-ready-cranelift.html">Production-ready cranelift backend</a></td><td style="text-align: left;"><a href="https://github.com/folkertdev">Folkert de Vries</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a>, <a href="https://github.com/rust-lang/rustc-perf">wg-compiler-performance</a></td></tr></tbody></table><p>The "Flexible, fast(er) compilation" initiative focuses on improving Rust's build system to better serve both specialized use cases and everyday development workflows:</p><ul><li>We are improving compilation performance through (1) <a href="https://rust-lang.github.io/rust-project-goals/2025h2/./parallel-front-end.html">parallel compilation in the compiler front-end</a>, which delivers 20-30% faster builds, and (2) <a href="https://rust-lang.github.io/rust-project-goals/2025h2/./production-ready-cranelift.html">making the Cranelift backend production-ready for development use</a>, offering roughly 20% faster code generation compared to LLVM for debug builds.</li><li>We are working to <a href="https://rust-lang.github.io/rust-project-goals/2025h2/./build-std.html">stabilize a core MVP of the <code>-Zbuild-std</code> feature</a>, which allows developers to rebuild the standard library from source with custom compiler flags. This unblocks critical use cases for embedded developers and low-level projects like Rust for Linux while also enabling improvements like using sanitizers with the standard library or building <code>std</code> with debug information.</li></ul><h5><a class="anchor" href="https://blog.rust-lang.org/2025/10/28/project-goals-2025h2/#higher-level-rust"></a>"Higher-level Rust"</h5><table><thead><tr><th style="text-align: left;">Goal</th><th style="text-align: left;">Point of contact</th><th style="text-align: left;">Team(s) and Champion(s)</th></tr></thead><tbody><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/cargo-script.html">Stabilize cargo-script</a></td><td style="text-align: left;"><a href="https://github.com/epage">Ed Page</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/cargo">cargo</a> (<a href="https://github.com/epage">Ed Page</a>), <a href="http://github.com/rust-lang/compiler-team">compiler</a>, <a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/joshtriplett">Josh Triplett</a>), <a href="https://www.rust-lang.org/governance/teams">lang-docs</a> (<a href="https://github.com/joshtriplett">Josh Triplett</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/ergonomic-rc.html">Ergonomic ref-counting: RFC decision and preview</a></td><td style="text-align: left;"><a href="https://github.com/nikomatsakis">Niko Matsakis</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a> (<a href="https://github.com/spastorino">Santiago Pastorino</a>), <a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/nikomatsakis">Niko Matsakis</a>)</td></tr></tbody></table><p>People generally start using Rust for foundational use cases, where the requirements for performance or reliability make it an obvious choice. But once they get used to it, they often find themselves turning to Rust even for higher-level use cases, like scripting, web services, or even GUI applications. Rust is often "surprisingly tolerable" for these high-level use cases -- except for some specific pain points that, while they impact everyone using Rust, hit these use cases particularly hard. We plan two flagship goals this period in this area:</p><ul><li>We aim to stabilize <a href="https://rust-lang.github.io/rust-project-goals/2025h2/./cargo-script.html">cargo script</a>, a feature that allows single-file Rust programs that embed their dependencies, making it much easier to write small utilities, share code examples, and create reproducible bug reports without the overhead of full Cargo projects.</li><li>We aim to finalize the design of <a href="https://rust-lang.github.io/rust-project-goals/2025h2/./ergonomic-rc.html">ergonomic ref-counting</a> and to finalize the experimental impl feature so it is ready for beta testing. Ergonomic ref-counting makes it less cumbersome to work with ref-counted types like <code>Rc</code> and <code>Arc</code>, particularly in closures.</li></ul><h4><a class="anchor" href="https://blog.rust-lang.org/2025/10/28/project-goals-2025h2/#what-to-expect-next"></a>What to expect next</h4><p>For the remainder of 2025 you can expect monthly blog posts covering the major progress on the Project goals.</p><p>Looking at the broader picture, we have now done three iterations of the goals program, and we want to judge how it should be run going forward. To start, Nandini Sharma from CMU has been conducting interviews with various Project members to help us see what's working with the goals program and what could be improved. We expect to spend some time discussing what we should do and to be launching the next iteration of the goals program next year. Whatever form that winds up taking, Tomas Sedovic, the <a href="https://blog.rust-lang.org/inside-rust/2025/06/30/program-management-update-2025-06/">Rust program manager</a> hired by the Leadership Council, will join me in running the program.</p><h3><a class="anchor" href="https://blog.rust-lang.org/2025/10/28/project-goals-2025h2/#appendix-full-list-of-project-goals"></a>Appendix: Full list of Project goals.</h3><details>Read the full slate of Rust Project goals.<p>The full slate of Project goals is as follows. These goals all have identified points of contact who will drive the work forward as well as a viable work plan.</p><p><strong>Invited goals.</strong> Some of the goals below are "invited goals", meaning that for that goal to happen we need someone to step up and serve as a point of contact. To find the invited goals, look for the <strong>"Help wanted"</strong> badge in the table below. Invited goals have reserved capacity for teams and a mentor, so if you are someone looking to help Rust progress, they are a great way to get involved.</p><table><thead><tr><th style="text-align: left;">Goal</th><th style="text-align: left;">Point of contact</th><th style="text-align: left;">Team(s) and Champion(s)</th></tr></thead><tbody><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/FLS-up-to-date-capabilities.html">Develop the capabilities to keep the FLS up to date</a></td><td style="text-align: left;"><a href="https://github.com/PLeVasseur">Pete LeVasseur</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/rust">bootstrap</a> (<a href="https://github.com/kobzol">Jakub Beránek</a>), <a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/nikomatsakis">Niko Matsakis</a>), <a href="https://github.com/rust-lang/opsem-team">opsem</a>, <a href="https://github.com/rust-lang/spec">spec</a> (<a href="https://github.com/PLeVasseur">Pete LeVasseur</a>), <a href="https://github.com/rust-lang/types-team">types</a></td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/Rust-for-Linux-compiler.html">Getting Rust for Linux into stable Rust: compiler features</a></td><td style="text-align: left;"><a href="https://github.com/tomassedovic">Tomas Sedovic</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a> (<a href="https://github.com/WesleyWiser">Wesley Wiser</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/Rust-for-Linux-language.html">Getting Rust for Linux into stable Rust: language features</a></td><td style="text-align: left;"><a href="https://github.com/tomassedovic">Tomas Sedovic</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/joshtriplett">Josh Triplett</a>), <a href="https://www.rust-lang.org/governance/teams">lang-docs</a> (<a href="https://github.com/traviscross">TC</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/a-mir-formality.html">Borrow checking in a-mir-formality</a></td><td style="text-align: left;"><a href="https://github.com/nikomatsakis">Niko Matsakis</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/types-team">types</a> (<a href="https://github.com/nikomatsakis">Niko Matsakis</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/autoreborrow-traits.html">Reborrow traits</a></td><td style="text-align: left;"><a href="https://github.com/aapoalas">Aapo Alasuutari</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a> (<a href="https://github.com/oli-obk">Oliver Scherer</a>), <a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/tmandry">Tyler Mandry</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/build-std.html">build-std</a></td><td style="text-align: left;"><a href="https://github.com/davidtwco">David Wood</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/cargo">cargo</a> (<a href="https://github.com/ehuss">Eric Huss</a>), <a href="http://github.com/rust-lang/compiler-team">compiler</a> (<a href="https://github.com/davidtwco">David Wood</a>), <a href="https://github.com/rust-lang/libs-team">libs</a> (<a href="https://github.com/Amanieu">Amanieu d'Antras</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/cargo-build-analysis.html">Prototype Cargo build analysis</a></td><td style="text-align: left;"><a href="https://github.com/weihanglo">Weihang Lo</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/cargo">cargo</a> (<a href="https://github.com/weihanglo">Weihang Lo</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/cargo-build-dir-layout.html">Rework Cargo Build Dir Layout</a></td><td style="text-align: left;"><a href="https://github.com/ranger-ross">Ross Sullivan</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/cargo">cargo</a> (<a href="https://github.com/weihanglo">Weihang Lo</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/cargo-plumbing.html">Prototype a new set of Cargo "plumbing" commands</a></td><td style="text-align: left;"><img alt="Help Wanted" src="https://img.shields.io/badge/Help%20wanted-yellow" /></td><td style="text-align: left;"><a href="https://github.com/rust-lang/cargo">cargo</a></td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/cargo-script.html">Stabilize cargo-script</a></td><td style="text-align: left;"><a href="https://github.com/epage">Ed Page</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/cargo">cargo</a> (<a href="https://github.com/epage">Ed Page</a>), <a href="http://github.com/rust-lang/compiler-team">compiler</a>, <a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/joshtriplett">Josh Triplett</a>), <a href="https://www.rust-lang.org/governance/teams">lang-docs</a> (<a href="https://github.com/joshtriplett">Josh Triplett</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/cargo-semver-checks.html">Continue resolving <code>cargo-semver-checks</code> blockers for merging into cargo</a></td><td style="text-align: left;"><a href="https://github.com/obi1kenobi">Predrag Gruevski</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/cargo">cargo</a> (<a href="https://github.com/epage">Ed Page</a>), <a href="https://github.com/rust-lang/rust">rustdoc</a> (<a href="https://github.com/adotinthevoid">Alona Enraght-Moony</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/codegen_retags.html">Emit Retags in Codegen</a></td><td style="text-align: left;"><a href="https://github.com/icmccorm">Ian McCormack</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a> (<a href="https://github.com/RalfJung">Ralf Jung</a>), <a href="https://github.com/rust-lang/opsem-team">opsem</a> (<a href="https://github.com/RalfJung">Ralf Jung</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/comprehensive-niche-checks.html">Comprehensive niche checks for Rust</a></td><td style="text-align: left;"><a href="https://github.com/1c3t3a">Bastian Kersting</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a> (<a href="https://github.com/saethlin">Ben Kimock</a>), <a href="https://github.com/rust-lang/opsem-team">opsem</a> (<a href="https://github.com/saethlin">Ben Kimock</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/const-generics.html">Const Generics</a></td><td style="text-align: left;"><a href="https://github.com/BoxyUwU">Boxy</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/nikomatsakis">Niko Matsakis</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/ergonomic-rc.html">Ergonomic ref-counting: RFC decision and preview</a></td><td style="text-align: left;"><a href="https://github.com/nikomatsakis">Niko Matsakis</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a> (<a href="https://github.com/spastorino">Santiago Pastorino</a>), <a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/nikomatsakis">Niko Matsakis</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/evolving-traits.html">Evolving trait hierarchies</a></td><td style="text-align: left;"><a href="https://github.com/cramertj">Taylor Cramer</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a>, <a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/cramertj">Taylor Cramer</a>), <a href="https://www.rust-lang.org/governance/teams">libs-api</a>, <a href="https://github.com/rust-lang/types-team">types</a> (<a href="https://github.com/oli-obk">Oliver Scherer</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/field-projections.html">Design a language feature to solve Field Projections</a></td><td style="text-align: left;"><a href="https://github.com/BennoLossin">Benno Lossin</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/tmandry">Tyler Mandry</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/finishing-gpu-offload.html">Finish the std::offload module</a></td><td style="text-align: left;"><a href="https://github.com/ZuseZ4">Manuel Drehwald</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a> (<a href="https://github.com/ZuseZ4">Manuel Drehwald</a>), <a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/traviscross">TC</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/gcc-backend-tests.html">Run more tests for GCC backend in the Rust's CI</a></td><td style="text-align: left;"><a href="https://github.com/GuillaumeGomez">Guillaume Gomez</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a> (<a href="https://github.com/WesleyWiser">Wesley Wiser</a>), <a href="https://github.com/rust-lang/infra-team">infra</a> (<a href="https://github.com/marcoieni">Marco Ieni</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/in-place-initialization.html">In-place initialization</a></td><td style="text-align: left;"><a href="https://github.com/Darksonn">Alice Ryhl</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/cramertj">Taylor Cramer</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/interop-problem-map.html">C++/Rust Interop Problem Space Mapping</a></td><td style="text-align: left;"><a href="https://github.com/baumanj">Jon Bauman</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a> (<a href="https://github.com/oli-obk">Oliver Scherer</a>), <a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/tmandry">Tyler Mandry</a>), <a href="https://github.com/rust-lang/libs-team">libs</a> (<a href="https://github.com/dtolnay">David Tolnay</a>), <a href="https://github.com/rust-lang/opsem-team">opsem</a></td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/libtest-json.html">Finish the libtest json output experiment</a></td><td style="text-align: left;"><a href="https://github.com/epage">Ed Page</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/cargo">cargo</a> (<a href="https://github.com/epage">Ed Page</a>), <a href="https://www.rust-lang.org/governance/teams">libs-api</a>, <a href="https://www.rust-lang.org/governance/teams">testing-devex</a></td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/mir-move-elimination.html">MIR move elimination</a></td><td style="text-align: left;"><a href="https://github.com/Amanieu">Amanieu d'Antras</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a>, <a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/Amanieu">Amanieu d'Antras</a>), <a href="https://github.com/rust-lang/opsem-team">opsem</a>, <a href="https://forge.rust-lang.org/compiler/working-areas.html">wg-mir-opt</a></td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/next-solver.html">Next-generation trait solver</a></td><td style="text-align: left;"><a href="https://github.com/lcnr">lcnr</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/types-team">types</a> (<a href="https://github.com/lcnr">lcnr</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/open-namespaces.html">Implement Open API Namespace Support</a></td><td style="text-align: left;"><img alt="Help Wanted" src="https://img.shields.io/badge/Help%20wanted-yellow" /></td><td style="text-align: left;"><a href="https://github.com/rust-lang/cargo">cargo</a> (<a href="https://github.com/epage">Ed Page</a>), <a href="http://github.com/rust-lang/compiler-team">compiler</a> (<a href="https://github.com/b-naber">b-naber</a>), <a href="https://github.com/rust-lang/crates.io">crates-io</a> (<a href="https://github.com/carols10cents">Carol Nichols</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/parallel-front-end.html">Promoting Parallel Front End</a></td><td style="text-align: left;"><a href="https://github.com/SparrowLii">Sparrow Li</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a></td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/pin-ergonomics.html">Continue Experimentation with Pin Ergonomics</a></td><td style="text-align: left;"><a href="https://github.com/frank-king">Frank King</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a> (<a href="https://github.com/oli-obk">Oliver Scherer</a>), <a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/traviscross">TC</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/polonius.html">Stabilizable Polonius support on nightly</a></td><td style="text-align: left;"><a href="https://github.com/lqd">Rémy Rakic</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/types-team">types</a> (<a href="https://github.com/jackh726">Jack Huey</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/production-ready-cranelift.html">Production-ready cranelift backend</a></td><td style="text-align: left;"><a href="https://github.com/folkertdev">Folkert de Vries</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a>, <a href="https://github.com/rust-lang/rustc-perf">wg-compiler-performance</a></td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/pub-priv.html">Stabilize public/private dependencies</a></td><td style="text-align: left;"><img alt="Help Wanted" src="https://img.shields.io/badge/Help%20wanted-yellow" /></td><td style="text-align: left;"><a href="https://github.com/rust-lang/cargo">cargo</a> (<a href="https://github.com/epage">Ed Page</a>), <a href="http://github.com/rust-lang/compiler-team">compiler</a></td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/reference-expansion.html">Expand the Rust Reference to specify more aspects of the Rust language</a></td><td style="text-align: left;"><a href="https://github.com/joshtriplett">Josh Triplett</a></td><td style="text-align: left;"><a href="https://www.rust-lang.org/governance/teams">lang-docs</a> (<a href="https://github.com/joshtriplett">Josh Triplett</a>), <a href="https://github.com/rust-lang/spec">spec</a> (<a href="https://github.com/joshtriplett">Josh Triplett</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/reflection-and-comptime.html">reflection and comptime</a></td><td style="text-align: left;"><a href="https://github.com/oli-obk">Oliver Scherer</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a> (<a href="https://github.com/oli-obk">Oliver Scherer</a>), <a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/scottmcm">Scott McMurray</a>), <a href="https://github.com/rust-lang/libs-team">libs</a> (<a href="https://github.com/joshtriplett">Josh Triplett</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/relink-dont-rebuild.html">Relink don't Rebuild</a></td><td style="text-align: left;"><a href="https://github.com/yaahc">Jane Lusby</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/cargo">cargo</a>, <a href="http://github.com/rust-lang/compiler-team">compiler</a></td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/rust-vision-doc.html">Rust Vision Document</a></td><td style="text-align: left;"><a href="https://github.com/nikomatsakis">Niko Matsakis</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/leadership-council">leadership-council</a></td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/rustc-perf-improvements.html">rustc-perf improvements</a></td><td style="text-align: left;"><a href="https://github.com/Jamesbarford">James</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a>, <a href="https://github.com/rust-lang/infra-team">infra</a></td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/rustdoc-doc-cfg.html">Stabilize rustdoc <code>doc_cfg</code> feature</a></td><td style="text-align: left;"><a href="https://github.com/GuillaumeGomez">Guillaume Gomez</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/rust">rustdoc</a> (<a href="https://github.com/GuillaumeGomez">Guillaume Gomez</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/rustdoc-team-charter.html">Add a team charter for rustdoc team</a></td><td style="text-align: left;"><a href="https://github.com/GuillaumeGomez">Guillaume Gomez</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/rust">rustdoc</a> (<a href="https://github.com/GuillaumeGomez">Guillaume Gomez</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/scalable-vectors.html">SVE and SME on AArch64</a></td><td style="text-align: left;"><a href="https://github.com/davidtwco">David Wood</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a> (<a href="https://github.com/davidtwco">David Wood</a>), <a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/nikomatsakis">Niko Matsakis</a>), <a href="https://github.com/rust-lang/libs-team">libs</a> (<a href="https://github.com/Amanieu">Amanieu d'Antras</a>), <a href="https://github.com/rust-lang/types-team">types</a></td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/stabilization-of-sanitizer-support.html">Rust Stabilization of MemorySanitizer and ThreadSanitizer Support</a></td><td style="text-align: left;"><a href="https://github.com/jakos-sec">Jakob Koschel</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/rust">bootstrap</a>, <a href="http://github.com/rust-lang/compiler-team">compiler</a>, <a href="https://github.com/rust-lang/infra-team">infra</a>, <a href="https://github.com/rust-lang/project-exploit-mitigations">project-exploit-mitigations</a></td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/typesystem-docs.html">Type System Documentation</a></td><td style="text-align: left;"><a href="https://github.com/BoxyUwU">Boxy</a></td><td style="text-align: left;"><a href="https://github.com/rust-lang/types-team">types</a> (<a href="https://github.com/BoxyUwU">Boxy</a>)</td></tr><tr><td style="text-align: left;"><a href="https://rust-lang.github.io/rust-project-goals/2025h2/unsafe-fields.html">Unsafe Fields</a></td><td style="text-align: left;"><a href="https://github.com/jswrenn">Jack Wrenn</a></td><td style="text-align: left;"><a href="http://github.com/rust-lang/compiler-team">compiler</a> (<a href="https://github.com/jswrenn">Jack Wrenn</a>), <a href="http://github.com/rust-lang/lang-team">lang</a> (<a href="https://github.com/scottmcm">Scott McMurray</a>)</td></tr></tbody></table></details></description> <pubDate>Tue, 28 Oct 2025 00:00:00 +0000</pubDate> <dc:creator>Niko Matsakis</dc:creator></item><item> <title>The Mozilla Blog: Better search suggestions in Firefox</title> <guid isPermaLink="false">https://blog.mozilla.org/?p=82407</guid> <link>https://blog.mozilla.org/en/firefox/better-search-suggestions/</link> <description><p>We’re working on a new feature to display direct results in your address bar as you type, so that you can skip the results page and get to the right site or answer faster.</p> <p>Every major browser today supports a feature known as “search suggestions.” As you type in the address bar, your chosen search engine offers real-time suggestions for searches you might want to perform.</p> <div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img alt="A Firefox browser window with a gray gradient background. The Google search bar shows “mozilla.” Google suggestions below include “mozilla firefox,” “mozilla thunderbird,” “mozilla careers,” “mozilla vpn,” and “mozilla foundation.”" class="wp-image-82408" height="310" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/ss1-1024x310.png" style="width: 675px;" width="1024" /></figure></div> <p>This is a helpful feature, but these suggestions always take you to a search engine results page, not necessarily the information or website you’re ultimately looking for. This is ideal for the search provider, but not always best for the user.</p> <p>For example, flight status summaries on a search results page are convenient, but it would be <em>more</em> convenient to show that information directly in the address bar:</p> <div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img alt="A Firefox browser window with an orange gradient background. The Google search bar shows “ac 8170.” The result displays an Air Canada flight from Victoria (YYJ) to Vancouver (YVR), showing departure and arrival times and that it’s “In flight” or “On time.”" class="wp-image-82418" height="394" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/ss2-1024x394.png" style="width: 675px;" width="1024" /></figure></div> <p>Similarly, people commonly search for a website when they don’t know or remember the exact URL. Why not skip the search?</p> <div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img alt="A Firefox browser window with a green gradient background. The Google search bar shows “mdn.” Below, the top result is “Mozilla Developer Network — Your blueprint for a better internet,” with Google suggestions like “mdn web docs,” “mdn array,” and “mdn fetch.”" class="wp-image-82428" height="394" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/ss3-1024x394.png" style="width: 675px;" width="1024" /></figure></div> <p>Another common use case is searching for recommendations, where Firefox can show highly relevant results from sources around the web:</p> <div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img alt="A Firefox browser window with a gradient pink-to-purple background. The Google search bar shows the query “bike repair boston.” Below it, Google suggestions and a featured result for “Ballantine Bike Shop” appear, showing address, rating, and hours." class="wp-image-82438" height="394" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/ss4-1024x394.png" style="width: 675px;" width="1024" /></figure></div> <p>The truth is, browser address bars today are largely a conduit to your search engine. And while search engines are very useful, a single and centralized source for finding everything online is not how we want the web to work. Firefox is proudly independent, and our address bar should be too.</p> <p>We experimented with the concept several years ago, but didn’t ship it<sup>1</sup> because we have an extremely high standard for privacy and weren’t satisfied with any design that would send your raw queries directly to us. Even though these are already sent to your search engine, Firefox is built on the <a href="https://firefox-source-docs.mozilla.org/contributing/data-collection.html#browsing-data">principle</a> that even Mozilla should not be able to learn what you do online. Unlike most search engines, we don’t want to know who’s searching for what, and we want to enable anyone in the world to verify that we couldn’t know even if we tried.</p> <p>We now have the technical architecture to meet that bar. When Firefox requests suggestions, it encrypts your query using a new protocol we helped design called <a href="https://support.mozilla.org/en-US/kb/ohttp-explained">Oblivious HTTP</a>. The encrypted request goes to a relay <a href="https://blog.mozilla.org/en/firefox/partnership-ohttp-prio/">operated by Fastly</a>, which can see your IP address but not the text. Mozilla can see the text, but not who it came from. We can then return a result directly or fetch one from a specialized search service. No single party can connect what you type to who you are.</p> <div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img alt="A simple black-and-white diagram with three rounded rectangles labeled “Firefox,” “Relay (Operated by Fastly),” and “Mozilla.” Double arrows connect them, showing a two-way flow between Firefox ↔ Relay ↔ Mozilla." class="wp-image-82448" height="131" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/ss5-1024x131.png" style="width: 675px;" width="1024" /></figure></div> <p>Firefox will continue to show traditional search suggestions for all queries and add direct results only when we have high confidence they match your intent. As with search engines, some of these results may be sponsored to support Firefox, but only if they’re highly relevant, and neither we nor the sponsor will know who they’re for. We expect this to be useful to users and, hopefully, help level the playing field by allowing Mozilla to work directly with independent sites rather than mediating all web discovery through the search engine.</p> <p>Running this at scale is not trivial. We need the capacity to handle the volume and servers close to people to avoid introducing noticeable latency. To keep things smooth, we are starting in the United States and will evaluate expanding into other geographies as we learn from this experience and observe how the system performs. The feature is still in development and testing and will roll out gradually over the coming year.<sup>2</sup></p> <hr class="wp-block-separator has-alpha-channel-opacity" /> <p><sup>1 </sup>We did ship an experimental version that users could enable in settings, as well as a small set of locally-matched suggestions in some regions. Unfortunately, the former had too little reach to be worth building features for, and the latter had very poor relevance and utility due to the technical limitations (most notably, the size of the local database).</p> <p><sup>2</sup> Where the feature is available, you can disable it by unchecking “Retrieve suggestions as you type” in the “Search” pane in Firefox settings. If this box is not yet available in your version of Firefox, you can pre-emptively disable it by setting <em>browser.urlbar.quicksuggest.online.enabled</em> to <em>false</em> in about:config.</p> <a class="ft-c-inline-cta" href="https://www.mozilla.org/firefox/new/?utm_source=blog.mozilla.org&amp;utm_medium=referral&amp;utm_campaign=blog-nav"> <div class="ft-c-inline-cta__media"> <img alt="" class="attachment-1x1 size-1x1" height="800" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2021/10/Visual-Guidelines-800x800.png" width="800" /> </div> <div class="ft-c-inline-cta__content"> <h3>Take control of your internet</h3> <span>Download Firefox</span> </div></a><p>The post <a href="https://blog.mozilla.org/en/firefox/better-search-suggestions/">Better search suggestions in Firefox</a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p></description> <pubDate>Mon, 27 Oct 2025 20:59:01 +0000</pubDate> <dc:creator>Bobby Holley</dc:creator></item><item> <title>Firefox Nightly: Extensions UI Improvements and More – These Weeks in Firefox: Issue 191</title> <guid isPermaLink="false">https://blog.nightly.mozilla.org/?p=1915</guid> <link>https://blog.nightly.mozilla.org/2025/10/27/extensions-ui-improvements-and-more-these-weeks-in-firefox-issue-191/</link> <description><h3>Highlights</h3><ul><li>As part of improvements to the extensions panel, an empty state UI has been introduced to help users to understand why their installed extensions may not be listed in the panel (e.g. when opening a private browsing window or enabling permanent private browsing mode).</li></ul><div class="wp-caption aligncenter" id="attachment_1911" style="width: 786px;"><img alt="The Firefox Extensions UI panel encouraging users to find more extensions." class="size-full wp-image-1911" height="760" src="https://blog.nightly.mozilla.org/files/2025/10/image2.png" width="776" /><p class="wp-caption-text" id="caption-attachment-1911">Empty state shown when no extensions are currently installed.</p></div><div class="wp-caption aligncenter" id="attachment_1910" style="width: 868px;"><img alt="The Firefox Extensions panel UI explaining why no extensions are displayed in private browsing mode." class="size-full wp-image-1910" height="820" src="https://blog.nightly.mozilla.org/files/2025/10/image1.png" width="858" /><p class="wp-caption-text" id="caption-attachment-1910">Empty state shown when extensions are already installed but not allowed to access private browsing tabs.</p></div><ul><li>The checkbox for allowing extensions to run in private browsing windows is going to be <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1987183">enabled by default when installing an extension with permanent private browsing mode enabled</a>.<ul><li>Thanks to Pier Angelo Vendrame from the Tor project for this enhancement.</li></ul></li></ul><p><img alt="A Firefox extension popup during the installation process with a checkbox enabled for the option &quot;Allow extension to run in private windows&quot;" class="aligncenter size-full wp-image-1913" height="260" src="https://blog.nightly.mozilla.org/files/2025/10/image1-1.png" width="848" /></p><ul><li>Daisuke <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979826">improved keyboard support for the Unified Search button in the Address Bar</a>, allowing it to open using Enter, Space or Down.</li></ul><h3>Friends of the Firefox team</h3><h4><a href="https://bugzilla.mozilla.org/buglist.cgi?title=Resolved%20bugs%20(excluding%20employees)&amp;quicksearch=1892101%2C1969417%2C1979919%2C1689380%2C1982968%2C1984296%2C1982767%2C1981384%2C1984788%2C1813675%2C1583902%2C1956493%2C1984661%2C1679997%2C1787457%2C1984872">Resolved bugs (excluding employees)</a></h4><h4>Volunteers that fixed more than one bug</h4><ul><li>Khalid AlHaddad</li><li>Kyler Riggs [:kylr]</li><li>Michael van Straten [:michael]</li><li>Pier Angelo Vendrame</li></ul><h4>New contributors (🌟 = first patch)</h4><ul><li>Mag Mukendi:<ul><li>🌟<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982207">Console.log() is capitalizing ‘l’ characters in a url string</a></li></ul></li><li>Khalid AlHaddad:<ul><li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1975161">[wdspec] Cookie tests for WebDriver classic can leave set cookies behind causing failures in later tests</a></li><li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1882718">[wdspec] Rename “add_cookie” fixture to “add_document_cookie”</a></li></ul></li><li>PhuongNam:<ul><li>🌟<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1968398">about:about doesn’t list about:firefoxview</a></li></ul></li><li>Kyler Riggs [:kylr]:<ul><li>🌟 <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1974265">“Turn on Vertical Tabs” option should be present in tab strip context menus invoked from draggable spaces</a></li><li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1955241">Menu Bar context menu has an extra divider</a></li></ul></li><li>Jim Gong:<ul><li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1886894">Clear sessionStorage in browsingData.remove() for parity with “Clear Cookies and Site Data”</a></li></ul></li></ul><h3>Project Updates</h3><h4>Add-ons / Web Extensions</h4><h4>Addon Manager &amp; about:addons</h4><ul><li>In addition to the new empty state UI, users without add-ons will be introduced to extensions instead. – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982225">Bug 1982225</a> / <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1992179">Bug 1992179</a> / <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1778684">Bug 1778684</a> / <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1814871">Bug 1814871</a> (along with <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1994180">Bug 1994180</a> that will be following up with a tweak to a couple of the localized strings).</li></ul><h5>WebExtension APIs</h5><ul><li>Thanks to the enhancement contributed by Jim Gong, starting from Firefox 146 the browsingData.remove API will also allow extensions to clear the sessionStorage WebAPI data – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1886894">Bug 1886894</a></li><li>Valentin Gosu introduced masque proxy support to the WebExtensions proxy API in Firefox 145 – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1988988">Bug 1988988</a></li><li>Investigated and fixed a crash triggered by storing deeply nested JSON data in the storage.sync WebExtensions API backend (introduced in Firefox 135 as a side-effect of changes introduced on the storage.sync backend side by <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1888472">Bug 1888472</a>), fix landed in Firefox 145 and has been uplifted to Firefox 144 beta, Firefox 143.0.3 release and Firefox ESR 140.0.3 – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1989840">Bug 1989840</a></li><li>Landed new Glean probe to assess real world impact of the storage.local API IndexedDB corruption issues of the underlying sqlite3 data store (investigated as part of <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979997">Bug 1979997</a> and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1885297">Bug 1885297</a>)<ul><li>NOTE: a new hidden boolean about:config pref extensions.webextensions.keepStorageOnCorrupted.storageLocal which does automatically reset the storage.local IndexedDB database when the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979997">Bug 1979997</a> corruption database issue is detected, and prevents browser.storage.local.clear API calls from failing when <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1885297">Bug 1885297</a> corrupted key is being hit.</li><li>NOTE: We intent to keep the auto-reset behaviors disabled by default for a few more nightly cycles to review the new telemetry before enabling the auto-reset behaviors on all channels (follow up tracked by <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1992973">Bug 1992973</a>)</li></ul></li></ul><h4>DevTools</h4><ul><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=778199">Mag Mukendi</a> removed the italic font style on links in the Console (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982207">#1982207</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=283262">Alexandre Poirot [:ochameau]</a> added automatic pretty print for minified code in the Debugger (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1917012">#1917012</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=559949">Julian Descottes [:jdescottes]</a> fixed an issue that was preventing to set event listener breakpoints in the Debugger (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1992769">#1992769</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=557153">Nicolas Chevobbe [:nchevobbe]</a> recovered a performance regression in the Inspector (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1991119">#1991119</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=283262">Alexandre Poirot [:ochameau]</a> fixed a couple leaks in DevTools (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1993262">#1993262</a>)</li></ul><h4>Lint, Docs and Workflow</h4><ul><li>ESLint<ul><li>The <a href="https://eslint.org/docs/latest/rules/no-case-declarations">ESLint rule no-case-declarations</a> has now been <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1881270">rolled out everywhere</a> (reduces warnings from ~850 -&gt; ~450)</li></ul></li><li>StyleLint<ul><li>New rules added for <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1984177">font-size</a> and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1988859">font-weight</a> tokens.</li></ul></li></ul><h4>Search and Navigation</h4><ul><li>Address Bar<ul><li>Drew enabled Important Dates feature in Germany, France and Italy for English locales. <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1992811">Bug 1992811</a></li><li>Dale made the new redesigned Identity panel show the expected icon for local files. <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1989844">Bug 1989844</a></li><li>Dharma landed new search onboarding strings to be used in Nimbus experiments. <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982132">Bug 1982132</a></li></ul></li><li>Places<ul><li>Marco has fixed a TopCrash related to fetching favicons affecting Firefox 143, fix is in Firefox 144</li><li>Emilio <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1991410">fixed cases where bookmarks favicons were not painted in menus</a>.</li></ul></li><li>Search<ul><li>Pier Angelo Vendrame fixed origin attribute use for OpenSearch and engine icons. <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1987600">Bug 1987600</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1993166">Bug 1993166</a></li><li>Florian optimized searchconfig xpcshell tests to use a lot less cpu time.</li></ul></li></ul></description> <pubDate>Mon, 27 Oct 2025 19:12:32 +0000</pubDate> <dc:creator>Katherine Patenio</dc:creator></item><item> <title>Mike Taylor: A new, new logo for the W3C</title> <guid isPermaLink="true">https://miketaylr.com/posts/2025/10/new-new-logo-for-w3c.html</guid> <link>https://miketaylr.com/posts/2025/10/new-new-logo-for-w3c.html</link> <description><p>In an effort to pivot this site into a full on graphic design side business after 2 blog posts about logos in a row (hit me up exclusivly on <a href="https://fishbrain.com/anglers/miketaylr">FB</a> to request a consultation), I thought I would reveal my new, new logo for the W3C.</p> <p>It turns out they recently launched a new one, but <a href="https://lists.w3.org/Archives/Public/www-archive/2025Oct/thread.html">some folks don’t love it</a>. As an artist, it’s not my job to critique other art, but instead to offer my own compelling vision for the web.</p> <p><img alt="a shitty drawing of a w, the word three spelled out, and followed by a period and the letter c" src="https://miketaylr.com/posts/assets/w3c.png" style="border: 1px solid gray;" /></p> <p>I shouldn’t have to explain why I went with the classic dark blue and asparagus colors—that much is obvious. And of course, turning c into a file extension as a reminder that NCSA Mosaic was written in C (I didn’t go with <a href="https://en.wikipedia.org/wiki/WorldWideWeb">WorldWideWeb</a> because that was written in Objective C and <code class="language-plaintext highlighter-rouge">.m</code> kinda messes it all up).</p></description> <pubDate>Sat, 25 Oct 2025 04:00:00 +0000</pubDate> <dc:creator>Mike Taylor</dc:creator></item><item> <title>Mozilla Localization (L10N): Localizer spotlight: Bogo</title> <guid isPermaLink="false">https://blog.mozilla.org/l10n/?p=1789</guid> <link>https://blog.mozilla.org/l10n/2025/10/24/localizer-spotlight-bogo/</link> <description><p><strong>About you</strong></p><p>My name is <a href="https://pontoon.mozilla.org/contributors/bogomil/">Bogomil</a> but people call me Bogo, and I am a translator for the Bulgarian locale. I think I got involved with the Mozilla project back in 2005 when I wrote a small search add-on/script. I became more active around 2008-2009 and with just a few gaps until this day.</p><p>I am European. I was born in Bulgaria, but I have been living for a long time in the Czech Republic. Bulgarian is my main language, but sometimes I contribute to localization projects in Turkish, Romanian, Macedonian and Czech.</p><p><a href="https://blog.mozilla.org/l10n/files/2025/10/image2.jpg"><img alt="" class="aligncenter wp-image-1790 size-large" height="338" src="https://blog.mozilla.org/l10n/files/2025/10/image2-600x338.jpg" width="600" /></a></p><p><strong>Q&amp;A</strong></p><p><em><strong>Q:</strong> What inspired you to join the Mozilla localization community?</em></p><p><strong>A:</strong> As I mentioned <a href="https://www.thunderbird.net/participate/">here</a> I decided to start localizing software because I knew some people had trouble using it in other languages. I believe everyone deserves the right to use software in a language they understand which helps them to get the maximum value out of it. As for Mozilla in particular I believe in <a href="https://www.mozilla.org/mission/">the mission</a> and this is the most efficient way for me to contribute.</p><p><em><strong>Q:</strong> How do you solve challenges like bugs or workflow hiccups, especially when collaborating virtually?</em></p><p><strong>A:</strong> Since we are a small team for the Bulgarian localizations we are almost always in sync on how to translate the strings. <span class="notranslate">We are following some basic rules, such as using a common dictionary and instructions on how to localize software in Bulgarian (shared across multiple FOSS projects),</span> set 15+ years ago and that are still relevant. When we have a conflict, I usually count on the team managers to share their wisdom, because they have a bit more knowledge than the rest of us.</p><p><em><strong>Q:</strong> Which projects or new product features were you most excited about this year, and why?</em></p><p><strong>A:</strong> In the last year I contributed mainly to the Thunderbird project. The items that are most exciting to me are:</p><ul><li>That finally we decided to remove the word “Junk” and replace it with “Spam”, I think this is self-explanatory 🙂</li><li>The new <a href="https://blog.thunderbird.net/2025/04/video-the-new-account-hub/">Account Hub</a> which improves significantly the consumer’s experience and their onboarding into the beautiful world of the free email. Free as in Freedom.</li><li>I am also excited about all the things in the <a href="https://developer.thunderbird.net/planning/roadmap">roadmap</a> to come.</li></ul><p><em><strong>Q:</strong> What tips, tools, or habits help you succeed as a localizer?</em></p><p><strong>A:</strong> If you look at my Pontoon <a href="https://pontoon.mozilla.org/contributors/bogomil/">profile</a>, you will see that for the last 2 months I contributed every day. I find this habit very useful for me, because it keeps me focused on my goal for consistently improving the localized experience.</p><p>Another item is that I like to provide a better experience to the mobile users. I often test and fix labels in <a href="https://play.google.com/store/apps/details?id=net.thunderbird.android">Thunderbird for Android</a> which, even translated correctly, are too long for a mobile phone UI.</p><p>And lastly, I love to engage with the community and ask them for help when we finish a section or a product. Last year we asked the Bulgarian community to help us validate a localization available in the beta version and we got some very helpful feedback.</p><p><strong>Something fun</strong></p><p><em><strong>Q:</strong> Could you share a few fun or unexpected facts about yourself that people might not know?</em></p><ul><li>I ran for the European Parliament in 2009 with the intention to fight for our digital rights.</li><li>I was on almost every media in the world in 2012 when I bought the data of millions of users for $5! <a href="https://www.forbes.com/sites/andygreenberg/2012/10/25/facebook-investigating-how-bulgarian-man-bought-1-1-million-users-email-addresses-for-five-dollars/">This</a> is the Forbes article.</li><li>I am a heavy metal fan and you can find me in underground clubs, enjoying bands you have never heard of.</li><li>Apart from technology I am an artist – I produced and performed my own theater play and shot a movie in Prague.</li><li>I realized my dream to have an opening talk at <a href="https://fosdem.org/">FOSDEM</a>. I was opening the Sunday session… but still!</li></ul><p><a href="https://blog.mozilla.org/l10n/files/2025/10/image3.jpg"><img alt="" class="aligncenter wp-image-1791 size-large" height="338" src="https://blog.mozilla.org/l10n/files/2025/10/image3-600x338.jpg" width="600" /></a></p></description> <pubDate>Fri, 24 Oct 2025 20:54:52 +0000</pubDate> <dc:creator>Delphine</dc:creator></item><item> <title>Mozilla Thunderbird: Your Workflow, Supercharged</title> <guid isPermaLink="false">https://blog.thunderbird.net/?p=3983</guid> <link>https://blog.thunderbird.net/2025/10/your-workflow-supercharged/</link> <description><p><img alt="" class="attachment-640x360 size-640x360 wp-post-image" height="319" src="https://blog.thunderbird.net/files/2025/10/Screenshot-2025-10-24-at-12.46.53 PM.png" width="640" /></p><p>Extensions make <a href="https://www.thunderbird.net/en-US/">Thunderbird</a> truly yours, moving at your pace and reflecting your priorities. Thunderbird’s flexibility means you can tailor the app to how you actually work. We’ll cover tools for efficiency, consistency, and visibility so every send is faster and better informed, your future self will thank you. </p> <h3><strong>Clippings</strong></h3> <p>We’ve all been there, retyping the same line for the hundredth time and wondering if there’s a better way. <a href="https://services.addons.thunderbird.net/eN-US/thunderbird/addon/clippings-tb/">Clippings</a> lets you save text once and reuse it anywhere you compose in Thunderbird. You can organize by folders, apply color labels, and search by name with autocomplete, so the right text is always a couple of keystrokes away.</p> <p>When you paste a clipping, you can include fill‑in prompts for names, dates, or custom notes, and even keep simple HTML formatting and images when needed. It’s like a spellbook for your inbox–summon, swap, send. </p> <p>Below is a quick glance at how Clippings can help you: </p> <ul><li>Save and paste reusable snippets anywhere you write—no more repeat typing.<br /></li> <li>Include prompts for names, dates, or custom notes; HTML and inline images.<br /></li> <li>Organize with folders and labels; find snippets fast with autocomplete.<br /></li> <li>Paste instantly with keyboard shortcuts; import, export, or sync your library.</li></ul> <div class="wp-block-image is-style-default"><figure class="alignleft size-large is-resized"><a href="https://services.addons.thunderbird.net/eN-US/thunderbird/addon/clippings-tb/"><img alt="Link to Thunderbird Add-on library." class="wp-image-4000" height="217" src="https://blog.thunderbird.net/files/2025/10/Screenshot-2025-10-24-at-12.40.49 PM-1-600x217.png" style="width: 144px; height: auto;" title="TB Add-on Link" width="600" /></a></figure></div> <p><br /><br /><br />With the content process streamlined, now for a sign‑off that keeps your tone on track. <br /></p> <h3><strong>Signature Switch</strong></h3> <p>We rotate hats as we write: buttoned‑up for clients, warm for teammates, and careful punctuation for legal. <a href="https://addons.thunderbird.net/en-US/thunderbird/addon/signature-switch/">Signature Switch</a> helps you with that. Keep multiple signatures, and swap them in with a click or shortcut right from the composer. Turn a signature off entirely, pick from your saved set, or append a different one without retyping a thing.<br /><br />Use plain text for simplicity, or HTML with images and links for a more professional finish. Because everything is accessible while you write, choosing the right signature doesn’t break your flow—and it helps keep branding and tone consistent across messages. One click and your signature goes from handshake to high‑five.</p> <p>Below is a quick glance at how Signature Switch can help you: </p> <ul><li>Switch signatures on/off or choose from your saved set, no retyping.<br /></li> <li>Match by recipient, account, or context; keep tone aligned.<br /></li> <li>Use plain text or polished HTML with images and links.<br /></li> <li>Access quickly from the composer toolbar or menu while you write.</li></ul> <div class="wp-block-image is-style-default"><figure class="alignleft size-large is-resized"><a href="https://addons.thunderbird.net/en-US/thunderbird/addon/signature-switch/"><img alt="Link to Thunderbird Add-on library." class="wp-image-4000" height="217" src="https://blog.thunderbird.net/files/2025/10/Screenshot-2025-10-24-at-12.40.49 PM-1-600x217.png" style="width: 144px; height: auto;" title="TB Add-on Link" width="600" /></a></figure></div> <p><br /><br /><br />With the sign‑off sorted, now let’s measure the results. </p> <h3><strong>ThirdStat</strong>s</h3> <p>Looking for a way to interpret email trends on more than just vibes alone? <a href="https://addons.thunderbird.net/en-US/thunderbird/addon/thirdstats/">ThirdStats</a> turns your mailbox into clear, local analytics that reveal how your email work actually behaves, when volume spikes, which hours are busiest, how response times trend, and which folders see the most activity. Interactive charts make patterns easy to spot at a glance. </p> <p>You can compare accounts side by side, adjust date ranges to see changes over time, and focus on a specific folder for deeper context. All processing happens on your device with read‑only access, so your data isn’t transmitted elsewhere. It’s a simple, private way to understand your workload and time your effort better. </p> <p>Below is a quick glance at how ThirdStats can help you: </p> <ul><li>Visualize volume, peak hours, response times, and folder activity with interactive charts.<br /></li> <li>Compare accounts side by side; filter by date ranges; view by folder.<br /></li> <li>Keep it private: analysis runs locally with read‑only access, no external transmission.</li></ul> <div class="wp-block-image is-style-default"><figure class="alignleft size-large is-resized"><a href="https://addons.thunderbird.net/en-US/thunderbird/addon/thirdstats/"><img alt="Link to Thunderbird Add-on library." class="wp-image-4000" height="217" src="https://blog.thunderbird.net/files/2025/10/Screenshot-2025-10-24-at-12.40.49 PM-1-600x217.png" style="width: 144px; height: auto;" title="TB Add-on Link" width="600" /></a></figure></div> <p><br /><br /><br />Do you have a favorite extension? Share it with us in the comments below. </p> <p>To learn more about add-ons check out <a href="http://Maximize Your Day: Extend Your Productivity with Add-ons">Maximize Your Day: Extend Your Productivity with Add-ons</a>.</p> <p>Your workflow deserves a client that adapts to it. Add what accelerates you, trim the rest, and keep improving. When you’re ready to go further, the <a href="https://addons.thunderbird.net/en-US/thunderbird/">Thunderbird Add-ons Catalog </a>is the fastest path to new features. Check what’s popular, discover up‑and‑coming tools, and install directly from the page with built‑in version compatibility checks. Thanks for reading.</p><p>The post <a href="https://blog.thunderbird.net/2025/10/your-workflow-supercharged/">Your Workflow, Supercharged</a> appeared first on <a href="https://blog.thunderbird.net">The Thunderbird Blog</a>.</p></description> <pubDate>Fri, 24 Oct 2025 20:00:11 +0000</pubDate> <dc:creator>David Hathaway</dc:creator></item><item> <title>The Servo Blog: This month in Servo: experimental mode, Trusted Types, strokeText(), and more!</title> <guid isPermaLink="true">https://servo.org/blog/2025/10/24/this-month-in-servo/</guid> <link>https://servo.org/blog/2025/10/24/this-month-in-servo/</link> <description><p>September was another busy month for Servo, with a bunch of new features landing in our nightly builds:</p><ul><li>the <strong>Trusted Types</strong> API is now stable (<a href="https://github.com/TimvdLippe">@TimvdLippe</a>, <a href="https://github.com/servo/servo/pull/39281">#39281</a>, <a href="https://github.com/servo/servo/pull/39263">#39263</a>)</li><li><strong>strokeText()</strong> on CanvasRenderingContext2D (<a href="https://github.com/sagudev">@sagudev</a>, <a href="https://github.com/servo/servo/pull/39183">#39183</a>)</li><li><strong>invertSelf()</strong> on DOMMatrix (<a href="https://github.com/lumiscosity">@lumiscosity</a>, <a href="https://github.com/servo/servo/pull/39148">#39148</a>)</li><li><strong>getType()</strong> and <strong>supports()</strong> on ClipboardItem (<a href="https://github.com/Gae24">@Gae24</a>, <a href="https://github.com/servo/servo/pull/39296">#39296</a>)</li><li><strong>getAll()</strong> and <strong>getAllKeys()</strong> on IDBObjectStore (<a href="https://github.com/arihant2math">@arihant2math</a>, <a href="https://github.com/servo/servo/pull/38885">#38885</a>)</li><li><strong>scrollParent</strong> property on HTMLElement (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/servo/servo/pull/39110">#39110</a>)</li><li><strong>sizes</strong> property on HTMLImageElement (<a href="https://github.com/tharkum">@tharkum</a>, <a href="https://github.com/servo/servo/pull/39466">#39466</a>)</li></ul><figure> <img alt="servoshell nightly showing new support for the strokeText() method on CanvasRenderingContext2D" src="https://servo.org/img/blog/2025-10-diffie.jpg" /></figure><p>servoshell now has a new <strong>experimental mode button</strong> (☢).Turning on experimental mode has the same effect as running Servo with <code>--enable-experimental-web-platform-features</code>: it enables all engine features, even those that may not be stable or complete.This works much like Chromium’s option with the same name, and it can be useful when a page is not functioning correctly, since it may allow the page to make further progress.</p><figure> <img alt="servoshell nightly showing the new experimental mode button (☢), which enables experimental web platform features" src="https://servo.org/img/blog/2025-10-experimental.png" /> &lt;figcaption&gt;Top to bottom: experimental mode off, experimental mode on.&lt;/figcaption&gt;</figure><p><strong>Viewport meta</strong> tags are now enabled on mobile devices only, fixing a bug where they were enabled on desktop (<a href="https://github.com/shubhamg13">@shubhamg13</a>, <a href="https://github.com/servo/servo/pull/39133">#39133</a>).You can still enable them if needed with <code>--pref viewport_meta_enabled</code> (<a href="https://github.com/shubhamg13">@shubhamg13</a>, <a href="https://github.com/servo/servo/pull/39207">#39207</a>).</p><p>Servo now supports <strong>‘<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Encoding">Content-Encoding</a>: <a href="https://en.wikipedia.org/wiki/Zstd">zstd</a>’</strong> (<a href="https://github.com/webbeef">@webbeef</a>, <a href="https://github.com/servo/servo/pull/36530">#36530</a>), and we’ve fixed a bug causing spurious credentials prompts when a HTTP 401 has no ‘WWW-Authenticate’ header (<a href="https://github.com/simonwuelker">@simonwuelker</a>, <a href="https://github.com/servo/servo/pull/39215">#39215</a>).We’ve also made a bunch of progress on <strong>AbortController</strong> (<a href="https://github.com/TimvdLippe">@TimvdLippe</a>, <a href="https://github.com/servo/servo/pull/39290">#39290</a>, <a href="https://github.com/servo/servo/pull/39295">#39295</a>, <a href="https://github.com/servo/servo/pull/39374">#39374</a>, <a href="https://github.com/servo/servo/pull/39406">#39406</a>) and <strong>&lt;link rel=preload&gt;</strong> (<a href="https://github.com/TimvdLippe">@TimvdLippe</a>, <a href="https://github.com/jdm">@jdm</a>, <a href="https://github.com/servo/servo/pull/39033">#39033</a>, <a href="https://github.com/servo/servo/pull/39034">#39034</a>, <a href="https://github.com/servo/servo/pull/39052">#39052</a>, <a href="https://github.com/servo/servo/pull/39146">#39146</a>, <a href="https://github.com/servo/servo/pull/39167">#39167</a>).</p><p><strong>‘Content-Security-Policy: sandbox’</strong> now <strong>disables scripting</strong> unless <strong>‘allow-scripts’</strong> is given (<a href="https://github.com/TimvdLippe">@TimvdLippe</a>, <a href="https://github.com/servo/servo/pull/39163">#39163</a>), and <strong>crypto.subtle.exportKey()</strong> can now export HMAC keys in <code>raw</code> format (<a href="https://github.com/arihant2math">@arihant2math</a>, <a href="https://github.com/servo/servo/pull/39059">#39059</a>).</p><p>The <strong>scrollIntoView()</strong> method on Element now works with shadow DOM (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/servo/servo/pull/39144">#39144</a>), and recurses to parent iframes if they are same origin (<a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/39475">#39475</a>, <a href="https://github.com/servo/servo/pull/39397">#39397</a>, <a href="https://github.com/servo/servo/pull/39153">#39153</a>).</p><p>Several types of <strong>DOM exceptions can now have error messages</strong> (<a href="https://github.com/arihant2math">@arihant2math</a>, <a href="https://github.com/rodio">@rodio</a>, <a href="https://github.com/excitablesnowball">@excitablesnowball</a>, <a href="https://github.com/servo/servo/pull/39056">#39056</a>, <a href="https://github.com/servo/servo/pull/39394">#39394</a>, <a href="https://github.com/servo/servo/pull/39535">#39535</a>), and we’ve also fixed a bug where links often need to be clicked twice (<a href="https://github.com/yezhizhen">@yezhizhen</a>, <a href="https://github.com/servo/servo/pull/39326">#39326</a>), and fixed bugs affecting &lt;img&gt; attribute changes (<a href="https://github.com/tharkum">@tharkum</a>, <a href="https://github.com/servo/servo/pull/39483">#39483</a>), the ‘:defined’ selector (<a href="https://github.com/mukilan">@mukilan</a>, <a href="https://github.com/servo/servo/pull/39325">#39325</a>, <a href="https://github.com/servo/servo/pull/39390">#39390</a>), invertSelf() on DOMMatrix (<a href="https://github.com/lumiscosity">@lumiscosity</a>, <a href="https://github.com/servo/servo/pull/39113">#39113</a>), and the ‘href’ setter on Location (<a href="https://github.com/arihant2math">@arihant2math</a>, <a href="https://github.com/sagudev">@sagudev</a>, <a href="https://github.com/servo/servo/pull/39051">#39051</a>).</p><p>One complex part of Servo isn’t even written in Rust, it’s written in Python!<a href="https://github.com/servo/servo/blob/25d3c5a157e781db8813071a5ba647463546d0cd/components/script_bindings/codegen/codegen.py"><strong>codegen.py</strong></a>, which describes how to generate Rust code with bindings for every known DOM interface from the WebIDL, is now <strong>fully type annotated</strong> (<a href="https://github.com/jerensl">@jerensl</a>, <a href="https://github.com/mukilan">@mukilan</a>, <a href="https://github.com/servo/servo/pull/39070">#39070</a>, <a href="https://github.com/servo/servo/pull/38998">#38998</a>).</p><h3>Embedding and automation <a class="header-anchor" href="https://servo.org/blog/2025/10/24/this-month-in-servo/#embedding-and-automation"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><p>Servo now requires <strong>Rust 1.86</strong> to build (<a href="https://github.com/sagudev">@sagudev</a>, <a href="https://github.com/servo/servo/pull/39185">#39185</a>).</p><p><strong>Keyboard scrolling</strong> is now automatically implemented by Servo (<a href="https://github.com/delan">@delan</a>, <a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/39371">#39371</a>, <a href="https://github.com/servo/servo/pull/39469">#39469</a>), so embedders <a href="https://github.com/servo/servo/pull/39371/files#diff-24ced12025398fd76b233d19f4507362ae8b3848157577d8041effc4c4a229ae">no longer</a> need to translate <strong>arrow keys</strong>, <strong>Home</strong>, <strong>End</strong>, <strong>Page Up</strong>, and <strong>Page Down</strong> to WebView API calls.This change also improves the behaviour of those keys, scrolling the element or &lt;iframe&gt; that was focused or most recently clicked (or a nearby ancestor).</p><p><code><a href="https://doc.servo.org/servo_config/opts/struct.DebugOptions.html">DebugOptions</a>::convert_mouse_to_touch</code> (<code>-Z convert-mouse-to-touch</code>) has been removed (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/39352">#39352</a>), with no replacement.Touch event simulation continues to be available in servoshell as <code>--simulate-touch-events</code>.</p><p><code><a href="https://doc.servo.org/servo_config/opts/struct.DebugOptions.html">DebugOptions</a>::webrender_stats</code> (<code>-Z wr-stats</code> in servoshell) has been removed (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/39331">#39331</a>); instead call <code><a href="https://doc.servo.org/servo/struct.WebView.html#method.toggle_webrender_debugging">toggle_webrender_debugging</a>(<a href="https://doc.servo.org/servo/enum.WebRenderDebugOption.html#variant.Profiler">Profiler</a>)</code> on a WebView (or press <strong>Ctrl</strong>+<strong>F12</strong> in servoshell).</p><p><code><a href="https://doc.servo.org/servo_config/opts/struct.DebugOptions.html">DebugOptions</a>::trace_layout</code> (<code>-Z trace-layout</code>) has been removed (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/39332">#39332</a>), since it had no effect.</p><p>We’ve improved the docs for <code><a href="https://doc.servo.org/servo/trait.WebViewDelegate.html">WebViewDelegate</a>::<a href="https://doc.servo.org/servo/trait.WebViewDelegate.html#method.notify_history_changed">notify_history_changed</a></code> (<a href="https://github.com/Narfinger">@Narfinger</a>, <a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/yezhizhen">@yezhizhen</a>, <a href="https://github.com/servo/servo/pull/39134">#39134</a>).</p><p>When automating servoshell with <strong>WebDriver</strong>, commands <strong>targeting elements</strong> now correctly <strong>scroll into view</strong> if needed (<a href="https://github.com/PotatoCP">@PotatoCP</a>, <a href="https://github.com/yezhizhen">@yezhizhen</a>, <a href="https://github.com/servo/servo/pull/38508">#38508</a>, <a href="https://github.com/servo/servo/pull/39265">#39265</a>), allowing <strong>Element Click</strong>, <strong>Element Send Keys</strong>, <strong>Element Clear</strong>, and <strong>Take Element Screenshot</strong> to work properly when the element is outside the viewport.</p><p><strong>WebDriver mouse inputs</strong> now work correctly with <strong>HiDPI scaling</strong> on more platforms (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/39472">#39472</a>), and we’ve improved the reliability of <strong>Take Screenshot</strong>, <strong>Take Element Screenshot</strong> (<a href="https://github.com/yezhizhen">@yezhizhen</a>, <a href="https://github.com/servo/servo/pull/39499">#39499</a>, <a href="https://github.com/servo/servo/pull/39539">#39539</a>, <a href="https://github.com/servo/servo/pull/39543">#39543</a>), <strong>Switch To Frame</strong> (<a href="https://github.com/yezhizhen">@yezhizhen</a>, <a href="https://github.com/servo/servo/pull/39086">#39086</a>), <strong>Switch To Window</strong> (<a href="https://github.com/yezhizhen">@yezhizhen</a>, <a href="https://github.com/servo/servo/pull/39241">#39241</a>), and <strong>New Session</strong> (<a href="https://github.com/yezhizhen">@yezhizhen</a>, <a href="https://github.com/servo/servo/pull/39040">#39040</a>).</p><p>These improvements have enabled us to run the <strong>WebDriver conformance tests</strong> in CI by default (<a href="https://github.com/PotatoCP">@PotatoCP</a>, <a href="https://github.com/servo/servo/pull/39087">#39087</a>), and also mean we’re closer than ever to running <a href="https://web-platform-tests.org/writing-tests/testdriver.html">WebDriver-based Web Platform Tests</a>.</p><h3>servoshell <a class="header-anchor" href="https://servo.org/blog/2025/10/24/this-month-in-servo/#servoshell"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><p><strong>Favicons</strong> now update correctly when you <strong>navigate back and forward</strong> (<a href="https://github.com/webbeef">@webbeef</a>, <a href="https://github.com/servo/servo/pull/39575">#39575</a>), not just when you load a new page.</p><p>servoshell’s <strong>command line argument parsing</strong> has been reworked (<a href="https://github.com/Narfinger">@Narfinger</a>, <a href="https://github.com/servo/servo/pull/37194">#37194</a>, <a href="https://github.com/servo/servo/pull/39316">#39316</a>), which should fix the confusing behaviour of some options.</p><p>On mobile devices, servoshell now resizes the webview correctly when the available space changes (<a href="https://github.com/blueguy1">@blueguy1</a>, <a href="https://github.com/yjx">@yjx</a>, <a href="https://github.com/yezhizhen">@yezhizhen</a>, <a href="https://github.com/servo/servo/pull/39507">#39507</a>).</p><p>On macOS, telling servoshell to <a href="https://w3c.github.io/webdriver/#screen-capture"><strong>take a screenshot</strong></a> no longer hides the window (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/39500">#39500</a>).This does not affect taking a screenshot in headless mode (<code>--headless</code>), where there continues to be no window at all.</p><h3>Performance <a class="header-anchor" href="https://servo.org/blog/2025/10/24/this-month-in-servo/#performance"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><p>Servo currently runs in <strong>single-process mode</strong> unless you opt in to <code>--multiprocess</code> mode, and we’ve landed a few perf improvements in that default mode.For one, in single-process mode, script can now <strong>communicate with the embedder directly</strong> for reduced latency (<a href="https://github.com/jschwe">@jschwe</a>, <a href="https://github.com/servo/servo/pull/39039">#39039</a>).We also create one thread pool for the image cache now, rather than one pool per origin (<a href="https://github.com/rodio">@rodio</a>, <a href="https://github.com/servo/servo/pull/38783">#38783</a>).</p><p>Many components of Servo that <em>would</em> be <a href="https://book.servo.org/architecture/overview.html#architecture">separated by a process boundary</a> in multiprocess mode, now use <a href="https://docs.rs/crossbeam-channel/0.5.15/crossbeam_channel/">crossbeam channels</a> in single-process mode, rather than using <a href="https://docs.rs/ipc-channel/0.20.2/ipc_channel/">IPC channels</a> in both modes (<a href="https://github.com/jschwe">@jschwe</a>, <a href="https://github.com/servo/servo/pull/39073">#39073</a>, <a href="https://github.com/servo/servo/pull/39076">#39076</a>, <a href="https://github.com/servo/servo/pull/39345">#39345</a>, <a href="https://github.com/servo/servo/pull/39347">#39347</a>, <a href="https://github.com/servo/servo/pull/39348">#39348</a>, <a href="https://github.com/servo/servo/pull/39074">#39074</a>).<a href="https://docs.rs/ipc-channel/0.20.2/ipc_channel/">IPC channels</a> are required when communicating with another process, but they’re more expensive, because they require serialising and deserialising each message, plus resources from the operating system.</p><p>We’ve started working on an optimisation for string handling in Servo’s DOM layer (<a href="https://github.com/Narfinger">@Narfinger</a>, <a href="https://github.com/servo/servo/pull/39480">#39480</a>, <a href="https://github.com/servo/servo/pull/39481">#39481</a>, <a href="https://github.com/servo/servo/pull/39504">#39504</a>).Strings in our DOM have historically been represented as <a href="https://doc.rust-lang.org/std/string/struct.String.html">ordinary Rust strings</a>, but they often come from SpiderMonkey, where they use <a href="https://searchfox.org/firefox-main/rev/8e5d58cfed616cb90586c614e53d8ab1ffc8af27/js/src/vm/StringType.h#83">a variety of representations</a>, none of which are entirely compatible.SpiderMonkey strings would continue to need conversion to Servo strings, but the idea we’re working towards is to <strong>make the conversion lazy</strong>, in the hope that many strings will never end up being converted at all.</p><p>We now use a faster hash algorithm for internal hashmaps that are not security-critical (<a href="https://github.com/Narfinger">@Narfinger</a>, <a href="https://github.com/servo/servo/pull/39106">#39106</a>, <a href="https://github.com/servo/servo/pull/39166">#39166</a>, <a href="https://github.com/servo/servo/pull/39202">#39202</a>, <a href="https://github.com/servo/servo/pull/39233">#39233</a>, <a href="https://github.com/servo/servo/pull/39244">#39244</a>, <a href="https://github.com/servo/servo/pull/39168">#39168</a>).These changes also switch that faster algorithm from <a href="https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function">FNV</a> to an <a href="https://docs.rs/rustc-hash/2.1.1/rustc_hash/">even simpler polynomial hash</a>, following in the footsteps of <a href="https://github.com/rust-lang/rust/pull/37229">Rust</a> and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1477628">Stylo</a>.</p><p>We’ve also landed a few more self-contained perf improvements:</p><ul><li>speeding up accesses to the event loop (<a href="https://github.com/Narfinger">@Narfinger</a>, <a href="https://github.com/servo/servo/pull/39274">#39274</a>, <a href="https://github.com/servo/servo/pull/39275">#39275</a>)</li><li>avoviding new display lists while loading CSS images (<a href="https://github.com/coding-joedow">@coding-joedow</a>, <a href="https://github.com/servo/servo/pull/39201">#39201</a>)</li><li>reducing memory usage (<a href="https://github.com/ritoban23">@ritoban23</a>, <a href="https://github.com/servo/servo/pull/39351">#39351</a>)</li><li>reducing binary size (<a href="https://github.com/lumiscosity">@lumiscosity</a>, <a href="https://github.com/Narfinger">@Narfinger</a>, <a href="https://github.com/servo/servo/pull/39437">#39437</a>, <a href="https://github.com/servo/servo/pull/39567">#39567</a>)</li></ul><h3>Donations <a class="header-anchor" href="https://servo.org/blog/2025/10/24/this-month-in-servo/#donations"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><p>Thanks again for your generous support!We are now receiving <strong>5654 USD/month</strong> (+1.8% over August) in recurring donations.</p><p>This helps us cover the cost of our <strong><a href="https://ci0.servo.org/">speedy</a> <a href="https://ci1.servo.org/">CI</a> <a href="https://ci2.servo.org/">and</a> <a href="https://ci3.servo.org/">benchmarking</a> <a href="https://ci4.servo.org/">servers</a></strong>, one of our latest <strong><a href="https://www.outreachy.org/alums/2025-06/#:~:text=Servo">Outreachy interns</a></strong>, and funding <strong><a href="https://servo.org/blog/2025/09/17/your-donations-at-work-funding-jdm/">maintainer work</a></strong> that helps more people contribute to Servo.Keep an eye out for <a href="https://github.com/servo/servo/issues/38141">further CI improvements</a> in the coming months, including <a href="https://github.com/servo/servo/pull/39900">faster pull request checks</a> and <a href="https://github.com/servo/ci-runners/issues/21">ten-minute WPT builds</a>.</p><p>Servo is also on <a href="https://thanks.dev/">thanks.dev</a>, and already <strong>28 GitHub users</strong> (±13 from August) that depend on Servo are sponsoring us there.If you use Servo libraries like <a href="https://crates.io/crates/url/reverse_dependencies">url</a>, <a href="https://crates.io/crates/html5ever/reverse_dependencies">html5ever</a>, <a href="https://crates.io/crates/selectors/reverse_dependencies">selectors</a>, or <a href="https://crates.io/crates/cssparser/reverse_dependencies">cssparser</a>, signing up for <a href="https://thanks.dev/">thanks.dev</a> could be a good way for you (or your employer) to give back to the community.</p><figure class="_fig" style="width: 100%; margin: 1em 0;"><div class="_flex"> <div style="text-align: right;"> <div><strong>5654</strong> USD/month</div> <div></div> <div></div> <div style="padding-right: 1em;"><strong>10000</strong></div> </div> <progress max="10000" value="5654"></progress></div></figure><p>Use of donations is decided transparently via the Technical Steering Committee’s public <strong><a href="https://github.com/servo/project/blob/main/FUNDING_REQUEST.md">funding request process</a></strong>, and active proposals are tracked in <a href="https://github.com/servo/project/issues/187">servo/project#187</a>.For more details, head to our <a href="https://servo.org/sponsorship/">Sponsorship page</a>.</p><h3>Conference talks <a class="header-anchor" href="https://servo.org/blog/2025/10/24/this-month-in-servo/#conference-talks"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><p><strong><a href="https://ke.segmentfault.com/course/1650000043885605/section/1500000047216580">MiniApps Design and Servo</a></strong> (starting at ~2:37:00; <a href="https://www.w3.org/2024/01/webevolve-series-events/annual-2025/slides/gregory-terzian.pdf">slides</a>) — Gregory Terzian (<a href="https://github.com/gterzian">@gterzian</a>) spoke about how Servo can be used as a web engine for mini-app platforms at <a href="https://www.w3.org/2024/01/webevolve-series-events/annual-2025/high-perf.en.html">WebEvolve 2025</a></p><p><strong><a href="https://ke.segmentfault.com/course/1650000043885605/section/1500000047216580">独⽴的,轻量级,模块化与并⾏处理架构的Web引擎开发</a></strong> [zh] / <strong>Developing an independent, light-weight, modular and parallel web-engine</strong> [en] (starting at ~5:49:00; <a href="https://www.w3.org/2024/01/webevolve-series-events/annual-2025/slides/jonathan-schwender.pdf">slides</a>) — Jonathan Schwender (<a href="https://github.com/jschwe">@jschwe</a>) spoke about Servo’s goals and status at <a href="https://www.w3.org/2024/01/webevolve-series-events/annual-2025/high-perf.en.html">WebEvolve 2025</a></p><p><strong>Servo: A new web engine written in Rust</strong>* (<a href="https://docs.google.com/presentation/d/1t15UKit4UPkZ-4ankkvsTJdpQWdBCmeTXLALeLk9n34">slides</a>; <a href="https://blogs.igalia.com/mrego/servo-a-new-web-engine-written-in-rust/">transcript</a>) — Manuel Rego (<a href="https://github.com/rego">@rego</a>) spoke about the Servo project at <a href="https://hangzhou2025.gosim.org/">GOSIM Hangzhou 2025</a></p><p><strong>Driving Innovation with Servo and OpenHarmony: Unified Rendering and WebDriver</strong>* (<a href="https://servo.org/files/2025-09-13-driving-innovation-with-servo-and-openharmony-unified-rendering-and-webdriver.pdf">slides</a>) — Jingshi Shangguan &amp; Zhizhen Ye (<a href="https://github.com/yezhizhen">@yezhizhen</a>) spoke about a new OpenHarmony rendering backend and WebDriver support in Servo at <a href="https://hangzhou2025.gosim.org/">GOSIM Hangzhou 2025</a></p><p><strong>The Joy and Value of Embedded Servo Systems</strong>* (<a href="https://servo.org/files/2025-09-13-the-joy-and-value-of-embedded-servo-systems.pdf">slides</a>) — Gregory Terzian (<a href="https://github.com/gterzian">@gterzian</a>) spoke about embedding Servo at <a href="https://hangzhou2025.gosim.org/">GOSIM Hangzhou 2025</a></p><p><strong>A Dive Into the Servo Layout System</strong>* (<a href="https://servo.org/files/2025-09-13-a-dive-into-the-servo-layout-system.pdf">slides</a>) — Martin Robinson (<a href="https://github.com/mrobinson">@mrobinson</a>) &amp; Oriol Brufau (<a href="https://github.com/obrufau">@obrufau</a>) spoke about the architecture of Servo’s parallel and incremental layout system at <a href="https://hangzhou2025.gosim.org/">GOSIM Hangzhou 2025</a></p><p><small>* video coming soon; go to our <a href="https://servo.org/about/">About page</a> for updates</small></p></description> <pubDate>Fri, 24 Oct 2025 00:00:00 +0000</pubDate></item><item> <title>Mozilla Addons Blog: Announcing data collection consent changes for new Firefox extensions</title> <guid isPermaLink="false">https://blog.mozilla.org/addons/?p=9265</guid> <link>https://blog.mozilla.org/addons/2025/10/23/data-collection-consent-changes-for-new-firefox-extensions/</link> <description><p>As of November 3rd 2025, all <b>new</b> Firefox extensions will be required to <a href="https://extensionworkshop.com/documentation/develop/firefox-builtin-data-consent/#specifying-data-types">specify if they collect or transmit personal data</a> in their <code>manifest.json</code> file using the <code>browser_specific_settings.gecko.data_collection_permissions key</code>. This will apply to new extensions only, and <b>not new versions of existing extensions</b>. Extensions that do not collect or transmit any personal data are required to specify this by setting the none required data collection permission in this property.</p><p>This information will then be displayed to the user when they start to install the extension, alongside any permissions it requests.</p><p><a href="https://blog.mozilla.org/addons/files/2025/10/data-collection-permissions-prompt-install.460b7848.webp"><img alt="Screenshot of example Firefox extension installation prompt showing data that the extension collects" class="size-medium wp-image-9267 aligncenter" height="418" src="https://blog.mozilla.org/addons/files/2025/10/data-collection-permissions-prompt-install.460b7848-580x418.webp" width="580" /></a> <a href="https://blog.mozilla.org/addons/files/2025/10/data-collection-permissions-prompt-install-no-transmission.66cdd978.webp"><img alt="Screenshot of example Firefox extension installation prompt showing that the extension claims it collects no data" class="size-medium wp-image-9266 aligncenter" height="402" src="https://blog.mozilla.org/addons/files/2025/10/data-collection-permissions-prompt-install-no-transmission.66cdd978-580x402.webp" width="580" /></a></p><p>This information will also be displayed on the <a href="http://addons.mozilla.org">addons.mozilla.org</a> page, if it is publicly listed, and in the <i>Permissions and Data</i> section of the Firefox about:addons page for that extension. If an extension supports versions of Firefox prior to 140 for Desktop, or 142 for Android, then the developer will need to continue to provide the user with a clear way to control the add-on’s data collection and transmission immediately after installation of the add-on.</p><p>Once any extension starts using these <code>data_collection_permissions</code> keys in a new version, it will need to continue using them for all subsequent versions. Extensions that do not have this property set correctly, and are required to use it, will be prevented from being submitted to <a href="http://addons.mozilla.org">addons.mozilla.org</a> for signing with a message explaining why.</p><p>In the first half of 2026, Mozilla will require all extensions to adopt this framework. But don’t worry, we’ll give plenty of notice via the add-ons blog. We’re also developing some new features to ease this transition for both extension developers and users, which we will announce here.</p><p>The post <a href="https://blog.mozilla.org/addons/2025/10/23/data-collection-consent-changes-for-new-firefox-extensions/">Announcing data collection consent changes for new Firefox extensions</a> appeared first on <a href="https://blog.mozilla.org/addons">Mozilla Add-ons Community Blog</a>.</p></description> <pubDate>Thu, 23 Oct 2025 10:57:39 +0000</pubDate> <dc:creator>Alan Byrne</dc:creator></item><item> <title>Niko Matsakis: Explicit capture clauses</title> <guid isPermaLink="false">https://smallcultfollowing.com/babysteps/blog/2025/10/22/explicit-capture-clauses/</guid> <link>https://smallcultfollowing.com/babysteps/blog/2025/10/22/explicit-capture-clauses/?utm_source=atom_feed</link> <description><p>In my previous post about Ergonomic Ref Counting, I talked about how, whatever else we do, we need a way to have explicit handle creation that is ergonomic. The next few posts are going to explore a few options for how we might do that.</p><p>This post focuses on <strong>explicit capture clauses</strong>, which would permit closures to be annotated with an explicit set of captured places. My take is that explicit capture clauses are a no brainer, for reasons that I’ll cover below, and we should definitely do them; but they may not be enough to be considered <em>ergonomic</em>, so I’ll explore more proposals afterwards.</p><h3>Motivation</h3><p>Rust closures today work quite well but I see a few problems:</p><ul><li>Teaching and understanding closure desugaring is difficult because it lacks an explicit form. Users have to learn to desugar in their heads to understand what’s going on.</li><li>Capturing the “clone” of a value (or possibly other transformations) has no concise syntax.</li><li>For long closure bodies, it is hard to determine precisely which values are captured and how; you have to search the closure body for references to external variables, account for shadowing, etc.</li><li>It is hard to develop an intuition for when <code>move</code> is required. I find myself adding it when the compiler tells me to, but that’s annoying.</li></ul><h3>Let’s look at a strawperson proposal</h3><p>Some time ago, I wrote a proposal for explicit capture clauses. I actually see a lot of flaws with this proposal, but I’m still going to explain it: right now it’s the only solid proposal I know of, and it’s good enough to explain how an explicit capture clause <em>could be seen</em> as a solution to the “explicit <em>and</em> ergonomic” goal. I’ll then cover some of the things I like about the proposal and what I don’t.</p><h3>Begin with <code>move</code></h3><p>The proposal begins by extending the <code>move</code> keyword with a list of places to capture:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">closure</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">.</span><span class="n">c</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">.</span><span class="n">y</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">do_something</span><span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">.</span><span class="n">c</span><span class="p">.</span><span class="n">d</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">.</span><span class="n">y</span><span class="p">)</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w"></span></span></span></code></pre></div><p>The closure will then take ownership of those two places; references to those places in the closure body will be replaced by accesses to these captured fields. So that example would desugar to something like</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">closure</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">struct</span> <span class="nc">MyClosure</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">a_b_c</span>: <span class="nc">Foo</span><span class="p">,</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">x_y</span>: <span class="nc">Bar</span><span class="p">,</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">impl</span><span class="w"> </span><span class="nb">FnOnce</span><span class="o">&lt;</span><span class="p">()</span><span class="o">&gt;</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">MyClosure</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">fn</span> <span class="nf">call_once</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Baz</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">do_something</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">a_b_c</span><span class="p">.</span><span class="n">d</span><span class="p">,</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">x_y</span><span class="p">)</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// ---------- --------</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// The place `a.b.c` is |</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// rewritten to the field |</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// `self.a_b_c` |</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// Same here but for `x.y`</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">MyClosure</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">a_b_c</span>: <span class="nc">self</span><span class="p">.</span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">.</span><span class="n">c</span><span class="p">,</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">x_y</span>: <span class="nc">self</span><span class="p">.</span><span class="n">x</span><span class="p">.</span><span class="n">y</span><span class="p">,</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w"></span></span></span></code></pre></div><p>When using a simple list like this, attempts to reference other places that were not captured result in an error:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">closure</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">.</span><span class="n">c</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">.</span><span class="n">y</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">do_something</span><span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">.</span><span class="n">c</span><span class="p">.</span><span class="n">d</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">.</span><span class="n">z</span><span class="p">)</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// ------- ---</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// OK Error: `x.z` not captured</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">};</span><span class="w"></span></span></span></code></pre></div><h3>Capturing with rewrites</h3><p>It is also possible to capture a custom expression by using an <code>=</code> sign. So for example, you could rewrite the above closure as follows:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">closure</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="p">(</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">.</span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">.</span><span class="n">c</span><span class="p">.</span><span class="n">clone</span><span class="p">(),</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">x</span><span class="p">.</span><span class="n">y</span><span class="p">,</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">do_something</span><span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">.</span><span class="n">c</span><span class="p">.</span><span class="n">d</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">.</span><span class="n">z</span><span class="p">)</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w"></span></span></span></code></pre></div><p>and it would desugar to:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">closure</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">struct</span> <span class="nc">MyClosure</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="cm">/* as before */</span><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">impl</span><span class="w"> </span><span class="nb">FnOnce</span><span class="o">&lt;</span><span class="p">()</span><span class="o">&gt;</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">MyClosure</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="cm">/* as before */</span><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">MyClosure</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">a_b_c</span>: <span class="nc">self</span><span class="p">.</span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">.</span><span class="n">c</span><span class="p">.</span><span class="n">clone</span><span class="p">(),</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// ------------------</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">x_y</span>: <span class="nc">self</span><span class="p">.</span><span class="n">x</span><span class="p">.</span><span class="n">y</span><span class="p">,</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w"></span></span></span></code></pre></div><p>When using this form, the expression assigned to <code>a.b.c</code> must have the same type as <code>a.b.c</code> in the surrounding scope. So this would be an error:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">closure</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="p">(</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">.</span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">22</span><span class="p">,</span><span class="w"> </span><span class="c1">// Error: `i32` is not `Foo`</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">x</span><span class="p">.</span><span class="n">y</span><span class="p">,</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="cm">/* ... */</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w"></span></span></span></code></pre></div><h3>Shorthands and capturing by reference</h3><p>You can understand <code>move(a.b)</code> as sugar for <code>move(a.b = a.b)</code>. We support other convenient shorthands too, such as</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">move</span><span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">.</span><span class="n">clone</span><span class="p">())</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="o">..</span><span class="p">.}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// == anything that ends in a method call becomes ==&gt;</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">move</span><span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">.</span><span class="n">clone</span><span class="p">())</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="o">..</span><span class="p">.}</span><span class="w"></span></span></span></code></pre></div><p>and two kinda special shorthands:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">move</span><span class="p">(</span><span class="o">&amp;</span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">..</span><span class="p">.</span><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">move</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">..</span><span class="p">.</span><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span></code></pre></div><p>These are special because the captured value is indeed <code>&amp;a.b</code> and <code>&amp;mut a.b</code> – but that by itself wouldn’t work, because the type doesn’t match. So we rewrite each access to <code>a.b</code> to desugar to a dereference of the <code>a_b</code> field, like <code>*self.a_b</code>:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">move</span><span class="p">(</span><span class="o">&amp;</span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">foo</span><span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// desugars to</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">struct</span> <span class="nc">MyStruct</span><span class="o">&lt;</span><span class="na">'l</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">a_b</span>: <span class="kp">&amp;</span><span class="na">'l</span> <span class="nc">Foo</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">impl</span><span class="w"> </span><span class="nb">FnOnce</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">MyStruct</span><span class="o">&lt;</span><span class="nb">'_</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">fn</span> <span class="nf">call_once</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">foo</span><span class="p">(</span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">a_b</span><span class="p">)</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// ---------</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// we insert the `*` too</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">MyStruct</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">a_b</span>: <span class="kp">&amp;</span><span class="nc">a</span><span class="p">.</span><span class="n">b</span><span class="p">,</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">move</span><span class="p">(</span><span class="o">&amp;</span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">foo</span><span class="p">(</span><span class="o">*</span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span></code></pre></div><p>There’s a lot of precedence for this sort of transform: it’s precisely what we do for the <code>Deref</code> trait and for existing closure captures.</p><h3>Fresh variables</h3><p>We should also allow you to define fresh variables. These can have arbitrary types. The values are evaluated at closure creation time and stored in the closure metadata:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">move</span><span class="p">(</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">load_data</span><span class="p">(),</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">y</span><span class="p">,</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">take</span><span class="p">(</span><span class="o">&amp;</span><span class="n">data</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="p">)</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"></span></span></span></code></pre></div><h3>Open-ended captures</h3><p>All of our examples so far fully enumerated the captured variables. But Rust closures today infer the set of captures (and the style of capture) based on the paths that are used. We should permit that as well. I’d permit that with a <code>..</code> sugar, so these two closures are equivalent:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">c2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="cm">/* closure */</span><span class="p">;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// ---- capture anything that is used,</span></span></span><span class="line"><span class="cl"><span class="c1">// taking ownership</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kd">let</span><span class="w"> </span><span class="n">c1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="p">(</span><span class="o">..</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="cm">/* closure */</span><span class="p">;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// ---- capture anything else that is used,</span></span></span><span class="line"><span class="cl"><span class="c1">// taking ownership</span></span></span></code></pre></div><p>Of course you can combine:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="p">(</span><span class="n">x</span><span class="p">.</span><span class="n">y</span><span class="p">.</span><span class="n">clone</span><span class="p">(),</span><span class="w"> </span><span class="o">..</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w"></span></span></span></code></pre></div><p>And you could write <code>ref</code> to get the equivalent of <code>||</code> closures:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">c2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="cm">/* closure */</span><span class="p">;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// -- capture anything that is used,</span></span></span><span class="line"><span class="cl"><span class="c1">// using references if possible</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">let</span><span class="w"> </span><span class="n">c1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="p">(</span><span class="k">ref</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="cm">/* closure */</span><span class="p">;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// --- capture anything else that is used,</span></span></span><span class="line"><span class="cl"><span class="c1">// using references if possible</span></span></span></code></pre></div><p>This lets you</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="p">(</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">.</span><span class="n">clone</span><span class="p">(),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">c</span><span class="p">,</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">ref</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">combine</span><span class="p">(</span><span class="o">&amp;</span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">c</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">z</span><span class="p">)</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// --- - -</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// | | |</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// | | This will be captured by reference</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// | | since it is used by reference</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// | | and is not explicitly named.</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// | |</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// | This will be captured by value</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// | since it is explicitly named.</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// |</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// We will capture a clone of this because</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// the user wrote `a.b.clone()`</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span><span class="w"></span></span></span></code></pre></div><h3>Frequently asked questions</h3><h4>How does this help with our motivation?</h4><p>Let’s look at the motivations I named:</p><h5>Teaching and understanding closure desugaring is difficult</h5><p>There’s a lot of syntax there, but it also gives you an explicit form that you can use to do explanations. To see what I mean, consider the difference between these two closures (<a href="http://smallcultfollowing.com/babysteps/atom.xml">playground</a>).</p><p>The first closure uses <code>||</code>:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="p">;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">c_attached</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">std</span>::<span class="n">mem</span>::<span class="n">replace</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="n">j</span><span class="p">)</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">..</span><span class="p">.</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"></span></span></span></code></pre></div><p>While the second closure uses <code>move</code>:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="p">;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">c_detached</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">std</span>::<span class="n">mem</span>::<span class="n">replace</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="n">j</span><span class="p">)</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w"></span></span></span></code></pre></div><p>These are in fact pretty different, <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2024&amp;gist=fec374e4055a99aa3dda9e66a5c03495">as you can see in this playground</a>. But why? Well, the first closure desugars to capture a reference:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="p">;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">c_attached</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="p">(</span><span class="o">&amp;</span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="o">..</span><span class="p">.};</span><span class="w"></span></span></span></code></pre></div><p>and the second captures by value:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="p">;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">c_attached</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="p">(</span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="o">..</span><span class="p">.};</span><span class="w"></span></span></span></code></pre></div><p>Before, to explain that, I had to resort to desugaring to structs.</p><h5>Capturing a clone is painful</h5><p>If you have a closure that wants to capture the clone of something today, you have to introduce a fresh variable. So something like this:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">closure</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">begin_actor</span><span class="p">(</span><span class="n">data</span><span class="p">,</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">tx</span><span class="p">.</span><span class="n">clone</span><span class="p">())</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w"></span></span></span></code></pre></div><p>becomes</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">closure</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">self_tx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">tx</span><span class="p">.</span><span class="n">clone</span><span class="p">();</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">move</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">begin_actor</span><span class="p">(</span><span class="n">data</span><span class="p">,</span><span class="w"> </span><span class="n">self_tx</span><span class="p">.</span><span class="n">clone</span><span class="p">())</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w"></span></span></span></code></pre></div><p>This is awkward. Under this proposal, it’s possible to point-wise replace specific items:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">closure</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">tx</span><span class="p">.</span><span class="n">clone</span><span class="p">(),</span><span class="w"> </span><span class="o">..</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">begin_actor</span><span class="p">(</span><span class="n">data</span><span class="p">,</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">tx</span><span class="p">.</span><span class="n">clone</span><span class="p">())</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w"></span></span></span></code></pre></div><h5>For long closure bodies, it is hard to determine precisely which values are captured and how</h5><p>Quick! What variables does this closure use from the environment?</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="p">.</span><span class="n">flat_map</span><span class="p">(</span><span class="k">move</span><span class="w"> </span><span class="o">|</span><span class="p">(</span><span class="n">severity</span><span class="p">,</span><span class="w"> </span><span class="n">lints</span><span class="p">)</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">parse_tt_as_comma_sep_paths</span><span class="p">(</span><span class="n">lints</span><span class="p">,</span><span class="w"> </span><span class="n">edition</span><span class="p">)</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">into_iter</span><span class="p">()</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">flat_map</span><span class="p">(</span><span class="k">move</span><span class="w"> </span><span class="o">|</span><span class="n">lints</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Rejoin the idents with `::`, so we have no spaces in between.</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">lints</span><span class="p">.</span><span class="n">into_iter</span><span class="p">().</span><span class="n">map</span><span class="p">(</span><span class="k">move</span><span class="w"> </span><span class="o">|</span><span class="n">lint</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">(</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">lint</span><span class="p">.</span><span class="n">segments</span><span class="p">().</span><span class="n">filter_map</span><span class="p">(</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">|</span><span class="n">segment</span><span class="o">|</span><span class="w"> </span><span class="n">segment</span><span class="p">.</span><span class="n">name_ref</span><span class="p">()</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">).</span><span class="n">join</span><span class="p">(</span><span class="s">"::"</span><span class="p">).</span><span class="n">into</span><span class="p">(),</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">severity</span><span class="p">,</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">)</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">})</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">})</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">})</span><span class="w"></span></span></span></code></pre></div><p>No idea? Me either. What about this one?</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="p">.</span><span class="n">flat_map</span><span class="p">(</span><span class="k">move</span><span class="p">(</span><span class="n">edition</span><span class="p">)</span><span class="w"> </span><span class="o">|</span><span class="p">(</span><span class="n">severity</span><span class="p">,</span><span class="w"> </span><span class="n">lints</span><span class="p">)</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="cm">/* same as above */</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">})</span><span class="w"></span></span></span></code></pre></div><p>Ah, pretty clear! I find that once a closure moves beyond a couple of lines, it can make a function kind of hard to read, because it’s hard to tell what variables it may be accessing. I’ve had functions where it’s important to correctness for one reason or another that a particular closure only accesses a subset of the values around it, but I have no way to indicate that right now. Sometimes I make separate functions, but it’d be nicer if I could annotate the closure’s captures explicitly.</p><h5>It is hard to develop an intuition for when <code>move</code> is required</h5><p>Hmm, actually, I don’t think this notation helps with that at all! More about this below.</p><p>Let me cover some of the questions you may have about this design.</p><h4>Why allow the “capture clause” to specify an entire place, like <code>a.b.c</code>?</h4><p>Today you can write closures that capture places, like <code>self.context</code> below:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">closure</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">send_data</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">context</span><span class="p">,</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">other_field</span><span class="p">)</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w"></span></span></span></code></pre></div><p>My goal was to be able to take such a closure and to add annotations that change how particular places are captured, without having to do deep rewrites in the body:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">closure</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">context</span><span class="p">.</span><span class="n">clone</span><span class="p">(),</span><span class="w"> </span><span class="o">..</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// --------------------------</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// the only change</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">send_data</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">context</span><span class="p">,</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">other_field</span><span class="p">)</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w"></span></span></span></code></pre></div><p>This definitely adds some complexity, because it means we have to be able to “remap” a place like <code>a.b.c</code> that has multiple parts. But it makes the explicit capture syntax far more powerful and convenient.</p><h4>Why do you keep the type the same for places like <code>a.b.c</code>?</h4><p>I want to ensure that the type of <code>a.b.c</code> is the same wherever it is type-checked, it’ll simplify the compiler somewhat and just generally makes it easier to move code into and out of a closure.</p><h4>Why the move keyword?</h4><p>Because it’s there? To be honest, I don’t like the choice of <code>move</code> because it’s so <em>operational</em>. I think if I could go back, I would try to refashion our closures around two concepts</p><ul><li><em>Attached</em> closures (what we now call <code>||</code>) would <em>always</em> be tied to the enclosing stack frame. They’d always have a lifetime even if they don’t capture anything.</li><li><em>Detached</em> closures (what we now call <code>move ||</code>) would capture by-value, like <code>move</code> today.</li></ul><p>I think this would help to build up the intuition of “use <code>detach ||</code> if you are going to return the closure from the current stack frame and use <code>||</code> otherwise”.</p><h4>What would a max-min explicit capture proposal look like?</h4><p>A maximally minimal explicit capture close proposal would probably <em>just</em> let you name specific variables and not “subplaces”:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">move</span><span class="p">(</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">a_b_c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a</span><span class="p">.</span><span class="n">b</span><span class="p">.</span><span class="n">c</span><span class="p">,</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">x_y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="n">x</span><span class="p">.</span><span class="n">y</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">*</span><span class="n">x_y</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">a_b_c</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"></span></span></span></code></pre></div><p>I think you can see though that this makes introducing an explicit form a lot less pleasant to use and hence isn’t really going to do anything to support ergonomic RC.</p><h3>Conclusion: Explicit closure clauses make things better, but not great</h3><p>I think doing explicit capture clauses is a good idea – I generally think we should have explicit syntax for everything in Rust, for teaching and explanatory purposes if nothing else; I didn’t always think this way, but it’s something I’ve come to appreciate over time.</p><p>I’m not sold on this specific proposal – but I think working through it is useful, because it (a) gives you an idea of what the benefits would be and (b) gives you an idea of how much hidden complexity there is.</p><p>I think the proposal shows that adding explicit capture clauses goes <em>some</em> way towards making things explicit <em>and</em> ergonomic. Writing <code>move(a.b.c.clone())</code> is definitely better than having to create a new binding.</p><p>But for me, it’s not really nice <em>enough</em>. It’s still quite a mental distraction to have to find the start of the closure, insert the <code>a.b.c.clone()</code> call, and it makes the closure header very long and unwieldy. Particularly for short closures the overhead is very high.</p><p>This is why I’d like to look into other options. Nonetheless, it’s useful to have discussed a proposal for an explicit form: if nothing else, it’ll be useful to explain the precise semantics of other proposals later on.</p></description> <pubDate>Wed, 22 Oct 2025 10:08:27 +0000</pubDate></item><item> <title>This Week In Rust: This Week in Rust 622</title> <guid isPermaLink="false">tag:this-week-in-rust.org,2025-10-22:/blog/2025/10/22/this-week-in-rust-622/</guid> <link>https://this-week-in-rust.org/blog/2025/10/22/this-week-in-rust-622/</link> <description><p>Hello and welcome to another issue of <em>This Week in Rust</em>!<a href="https://www.rust-lang.org/">Rust</a> 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<a href="https://bsky.app/profile/thisweekinrust.bsky.social">@thisweekinrust.bsky.social</a> on Bluesky or<a href="https://mastodon.social/@thisweekinrust">@ThisWeekinRust</a> on mastodon.social, or<a href="https://github.com/rust-lang/this-week-in-rust">send us a pull request</a>.Want to get involved? <a href="https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md">We love contributions</a>.</p><p><em>This Week in Rust</em> is openly developed <a href="https://github.com/rust-lang/this-week-in-rust">on GitHub</a> and archives can be viewed at <a href="https://this-week-in-rust.org/">this-week-in-rust.org</a>.If you find any errors in this week's issue, <a href="https://github.com/rust-lang/this-week-in-rust/pulls">please submit a PR</a>.</p><p>Want TWIR in your inbox? <a href="https://this-week-in-rust.us11.list-manage.com/subscribe?u=fd84c1c757e02889a9b08d289&amp;id=0ed8b72485">Subscribe here</a>.</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#updates-from-rust-community">Updates from Rust Community</a></h4> <h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#official">Official</a></h5><ul><li><a href="https://blog.rust-lang.org/2025/10/15/announcing-the-new-rust-project-directors-2025/">Announcing the New Rust Project Directors</a></li><li><a href="https://blog.rust-lang.org/2025/10/16/docsrs-changed-default-targets/">docs.rs: changed default targets</a></li><li><a href="https://blog.rust-lang.org/inside-rust/2025/10/16/infrastructure-team-q3-recap-and-q4-plan/">Infrastructure Team 2025 Q3 Recap and Q4 Plan</a></li><li><a href="https://blog.rust-lang.org/inside-rust/2025/10/16/renaming-the-default-branch-of-rust-langrust/">Renaming the default branch of rust-lang/rust</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#newsletters">Newsletters</a></h5><ul><li><a href="https://scientificcomputing.rs/monthly/2025-10">Scientific Computing in Rust #11 (October 2025)</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#projecttooling-updates">Project/Tooling Updates</a></h5><ul><li><a href="https://www.sea-ql.org/blog/2025-10-20-sea-orm-2.0/">SeaORM 2.0: new entity format and relational capabilities</a></li><li><a href="https://slint.dev/blog/slint-1.14-released">Slint 1.14 Released</a></li><li><a href="https://danube-docs.dev-state.com/architecture/persistence/">Danube Messaging - new topic persistence architecture (Wal + Cloud)</a></li><li><a href="https://tqwewe.com/blog/building-sierradb/">SierraDB: A Distributed Event Store Built in Rust</a></li><li><a href="https://immunant.com/blog/2025/10/c2rust_release/">Announcing C2Rust v0.21</a></li><li><a href="https://maguire.tech/posts/shove/"><code>Shove</code> Project Writeup</a></li><li><a href="https://news.ycombinator.com/item?id=45624186">ServiceRadar - Open Source Network Management and Observability</a> </li><li><a href="https://github.com/kyu08/fzf-make/releases/tag/v0.65.0">fzf-make v0.65.0 is released! (A command line tool that executes commands using fuzzy finder)</a></li><li><a href="https://diesel.rs/assets/NGICore%20Diesel%20penetration%20test%20report%202025%201.0.pdf">Diesel Code Audit Report</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#observationsthoughts">Observations/Thoughts</a></h5><ul><li><a href="https://lwn.net/SubscriberLink/1042172/c7e1cdef4a518cc3/">Git considers SHA-256, Rust, LLMs, and more</a></li><li><a href="https://lwn.net/SubscriberLink/1041095/2ef0281b0fec4d9d/">DebugFS on Rust</a></li><li><a href="https://medium.com/google-cloud/python-and-rust-interoperability-a-walkthrough-for-building-a-high-performance-mcp-server-56c04e4b651b">Python and Rust interoperability</a></li><li><a href="https://smallcultfollowing.com/babysteps/blog/2025/10/21/move-destruct-leak/">Controlled Destruction in Rust: Towards Async Drop and Safer Resource Management</a></li><li><a href="https://daymare.net/blogs/everbody-so-creative/">Everybody's so Creative!</a></li><li><a href="https://blog.goose.love/posts/organizing-a-feature-freeze/">How we organized the Rust Clippy feature freeze</a></li><li><a href="https://alexsaveau.dev/blog/tips/generalizing-over-mutability-in-rust">Generalizing over mutability in Rust</a></li><li>[audio] <a href="https://netstack.fm/#episode-10">Netstack.FM Episode 10 – zerocopy with Joshua Liebow-Feeser</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-walkthroughs">Rust Walkthroughs</a></h5><ul><li><a href="https://blog.vega.io/posts/partial_stream/">Real-Time Results in a Federated Query Engine</a></li><li><a href="https://crustyengineer.com/blog/axum-multi-tenancy-abstract-repository-layer/">Axum: Multi-tenancy (with Hexarch) and Abstracting the Repository</a></li><li><a href="https://tweedegolf.nl/en/blog/196/fixing-rust-lang-stdarch-issues-in-llvm">Fixing rust-lang stdarch issues in LLVM - Blog - Tweede golf</a></li><li><a href="https://jorgeortiz.dev/posts/rust_unit_testing_test_doubles_spy/">Rust unit testing: spies and dummy test doubles</a></li><li><a href="https://blog.0xshadow.dev/posts/backend-engineering-with-axum/axum-refresh-token-rotation/">Axum Backend Series: Refresh Token Rotation and Reuse Detection</a></li><li><a href="https://medium.com/@carlmkadie/vibe-validation-with-lean-chatgpt-5-claude-4-5-part-1-c57b430b3d7a">Vibe Validation with Lean, ChatGPT-5, &amp; Claude 4.5: Nine Rules for Proving (Rust) Algorithms Correct Without Knowing Formal Methods (Part 1)</a></li><li><a href="https://rvarago.github.io/typed-evaluator-in-rust/">A Typed Evaluator in Rust</a></li><li><a href="https://orxfun.github.io/orxfun-notes/#/zero-cost-composition-2025-10-15">Zero Cost Composition and the Power of GATs</a></li><li><a href="https://www.unwoundstack.com/blog/integration-testing-rust-binaries.html">Integration Testing Rust Binary Crates</a></li><li>[video] <a href="https://www.youtube.com/watch?v=hpGDCbO31Rg">Build with Naz : How to speed up Rust compiler for different workflows</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#miscellaneous">Miscellaneous</a></h5><ul><li><a href="https://filtra.io/rust/jobs-report/sep-25">September 2025 Rust Jobs Report</a></li></ul><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#crate-of-the-week">Crate of the Week</a></h4><p>This week's crate is <a href="https://docs.rs/extend_mut">extend_mut</a>, a library to safely extend the lifetime of an exclusive reference under some constraints.P</p><p>Thanks to <a href="https://users.rust-lang.org/t/crate-of-the-week/2704/1482">Oleksandr Babak</a> for the self-suggestion!</p><p><a href="https://users.rust-lang.org/t/crate-of-the-week/2704">Please submit your suggestions and votes for next week</a>!</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#calls-for-testing">Calls for Testing</a></h4><p>An important step for RFC implementation is for people to experiment with theimplementation and give feedback, especially before stabilization.</p><p>If you are a feature implementer and would like your RFC to appear in this list, add a<code>call-for-testing</code> label to your RFC along with a comment providing testing instructions and/orguidance on which aspect(s) of the feature need testing.</p><p><a href="https://github.com/rust-lang/cargo/labels/call-for-testing">Cargo</a>* <a href="https://github.com/rust-lang/cargo/issues/12207">Tracking Issue for cargo-script RFC 3424</a> * <a href="https://github.com/rust-lang/cargo/issues/12207#issuecomment-3412997290">Testing Steps</a></p><ul><li><em>No calls for testing were issued this week by <a href="https://github.com/rust-lang/rust/labels/call-for-testing">Rust</a>, <a href="https://github.com/rust-lang/rfcs/issues?q=label%3Acall-for-testing">Rust language RFCs</a> or <a href="https://github.com/rust-lang/rustup/labels/call-for-testing">Rustup</a>.</em></li></ul><p><a href="https://github.com/rust-lang/this-week-in-rust/issues">Let us know</a> if you would like your feature to be tracked as a part of this list.</p><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rfcs"></a><a href="https://github.com/rust-lang/rfcs/issues?q=label%3Acall-for-testing">RFCs</a></h5><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust"></a><a href="https://github.com/rust-lang/rust/labels/call-for-testing">Rust</a></h5><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rustup"></a><a href="https://github.com/rust-lang/rustup/labels/call-for-testing">Rustup</a></h5><p>If you are a feature implementer and would like your RFC to appear on the above list, add the new <code>call-for-testing</code>label to your RFC along with a comment providing testing instructions and/or guidance on which aspect(s) of the featureneed testing.</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#call-for-participation-projects-and-speakers">Call for Participation; projects and speakers</a></h4><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cfp-projects">CFP - Projects</a></h5><p>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!</p><p>Some of these tasks may also have mentors available, visit the task page for more information.</p> <ul><li><a href="https://github.com/diesel-rs/diesel/issues/4764">Diesel - Improve documentation for Postgres loading modes</a></li><li><a href="https://github.com/diesel-rs/diesel/issues/4216">Diesel - Add support for currently unsupported postgres json/jsonb functions</a></li></ul><p>If you are a Rust project owner and are looking for contributors, please submit tasks <a href="https://github.com/rust-lang/this-week-in-rust?tab=readme-ov-file#call-for-participation-guidelines">here</a> or through a <a href="https://github.com/rust-lang/this-week-in-rust">PR to TWiR</a> or by reaching out on <a href="https://bsky.app/profile/thisweekinrust.bsky.social">Bluesky</a> or <a href="https://mastodon.social/@thisweekinrust">Mastodon</a>!</p><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cfp-events">CFP - Events</a></h5><p>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.</p> <ul><li><a href="https://tokio.rs/blog/2025-09-26-announcing-tokio-conf-cfp"><strong>TokioConf 2026</strong></a>| CFP closes 2025-12-08 | Portland, Oregon, USA | 2026-04-20</li></ul><p>If you are an event organizer hoping to expand the reach of your event, please submit a link to the website through a <a href="https://github.com/rust-lang/this-week-in-rust">PR to TWiR</a> or by reaching out on <a href="https://bsky.app/profile/thisweekinrust.bsky.social">Bluesky</a> or <a href="https://mastodon.social/@thisweekinrust">Mastodon</a>!</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#updates-from-the-rust-project">Updates from the Rust Project</a></h4><p>369 pull requests were <a href="https://github.com/search?q=is%3Apr+org%3Arust-lang+is%3Amerged+merged%3A2025-10-14..2025-10-21">merged in the last week</a></p><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#compiler">Compiler</a></h6><ul><li><a href="https://github.com/rust-lang/rust/pull/147619">add a <code>!=</code> check to <code>ChunkedBitSet::union</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/147630">bitset cleanups</a></li><li><a href="https://github.com/rust-lang/rust/pull/147695"><code>deduced_param_attrs</code>: check Freeze on monomorphic types</a></li><li><a href="https://github.com/rust-lang/rust/pull/146167">deny-by-default never type lints</a></li><li><a href="https://github.com/rust-lang/rust/pull/147577">improve error message for ambiguous numeric types in closure parameters</a></li><li><a href="https://github.com/rust-lang/rust/pull/146221">remove boxes from AST list elements</a></li><li><a href="https://github.com/rust-lang/rust/pull/147508"><code>TaskDeps</code> improvements</a></li><li><a href="https://github.com/rust-lang/rust/pull/147382"><code>unused_must_use</code>: Don't warn on <code>Result&lt;(), Uninhabited&gt;</code> or <code>ControlFlow&lt;Uninhabited, ()&gt;</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/147644">use regular Vec in BitSet</a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#library">Library</a></h6><ul><li><a href="https://github.com/rust-lang/rust/pull/147708">const <code>mem::drop</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/146976">constify basic Clone impls</a></li><li><a href="https://github.com/rust-lang/rust/pull/147258">iter repeat: panic on last</a></li><li><a href="https://github.com/rust-lang/rust/pull/146841">stabilise <code>rotate_left</code> and <code>rotate_right</code> in <code>[_]</code> as <code>const fn</code> items</a></li><li><a href="https://github.com/rust-lang/rust/pull/143191">stabilize <code>rwlock_downgrade</code> library feature</a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cargo">Cargo</a></h6><ul><li><a href="https://github.com/rust-lang/cargo/pull/16127"><code>check</code>: Fix suggested command for bin package</a></li><li><a href="https://github.com/rust-lang/cargo/pull/16120"><code>script</code>: Remove name sanitiztion outside what is strictly required</a></li><li><a href="https://github.com/rust-lang/cargo/pull/16086"><code>script</code>: Tweak cargo script build-dir / target-dir</a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rustdoc">Rustdoc</a></h6><ul><li><a href="https://github.com/rust-lang/rust/pull/147660">search: stringdex 0.0.2</a></li><li><a href="https://github.com/rust-lang/rust/pull/147809">fix passes order so intra-doc links are collected after stripping passes</a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#clippy">Clippy</a></h6><ul><li><a href="https://github.com/rust-lang/rust-clippy/pull/15911"><code>empty_enum</code>: don't lint if all variants happen to be <code>cfg</code>-d out</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15870"><code>option_option</code>: split part of diagnostic message into help message</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15678"><code>unnecessary_safety_comment</code> Some fixes regarding comments above attributes</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15862">allow <code>explicit_write</code> in tests</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15706">dereference argument of <code>manual_div_ceil()</code> if needed</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15402"><code>manual_rotate</code>: also recognize non-consts</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15632">overhaul <code>mutex_{atomic,integer}</code></a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-analyzer">Rust-Analyzer</a></h6><ul><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20854">parser: Don't error on frontmatter</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20855">improve fixture support</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20880">fix invalid RestPat for <code>convert_tuple_struct_to_named_struct</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20872">fix missing RestPat for <code>convert_named_struct_to_tuple_struct</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20838">don't make <code>convert_to_guarded_return</code> applicable on <code>let-else</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20876">fix <code>signature_help</code> to proto conversion creating invalid utf16 offsets</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20673">support <code>break</code> with value in completions</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20758">support <code>else</code> blocks with <code>!</code> return type in <code>convert_to_guarded_return</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20772">support <code>match</code> inside <code>if</code> in <code>pull_assignment_up</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20841">migrate more stuff to the next solver</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20867">migrate variance to the next solver and remove lint allows from its stuff</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20873">rip Chalk out of the codebase 🎉</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20858">support underscore suffix parameter hide inlayHints</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20757">use <code>FileId::MAX</code> for id assertion in <code>PathInterner::intern</code></a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-compiler-performance-triage">Rust Compiler Performance Triage</a></h5><p>Fairly busy week, with lots of mixed results. However, overall we ended with aslight improvement on average.</p><p>Triage done by <strong>@simulacrum</strong>.Revision range: <a href="https://perf.rust-lang.org/?start=956f47c32f1bd97b22cd702d7ccf78f0f0d42c34&amp;end=4068bafedd8ba724e332a5221c06a6fa531a30d2&amp;absolute=false&amp;stat=instructions%3Au">956f47c3..4068bafe</a></p><p>2 Regressions, 5 Improvements, 10 Mixed; 5 of them in rollups</p><p>39 artifact comparisons made in total</p><p><a href="https://github.com/rust-lang/rustc-perf/blob/master/triage/2025/2025-10-20.md">Full report here</a></p><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#approved-rfcs"></a><a href="https://github.com/rust-lang/rfcs/commits/master">Approved RFCs</a></h5><p>Changes to Rust follow the Rust <a href="https://github.com/rust-lang/rfcs#rust-rfcs">RFC (request for comments) process</a>. Theseare the RFCs that were approved for implementation this week:</p><ul><li><em>No RFCs were approved this week.</em></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#final-comment-period">Final Comment Period</a></h5><p>Every week, <a href="https://www.rust-lang.org/team.html">the team</a> announces the 'final comment period' for RFCs and key PRswhich are reaching a decision. Express your opinions now.</p><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#tracking-issues-prs">Tracking Issues &amp; PRs</a></h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust_1"></a><a href="https://github.com/rust-lang/rust/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Rust</a><ul><li><a href="https://github.com/rust-lang/rust/issues/136306">Tracking Issue for NEON fp16 intrinsics</a></li><li><a href="https://github.com/rust-lang/rust/pull/146561">Change <code>Location&lt;'_&gt;</code> lifetime to <code>'static</code> in <code>Panic[Hook]Info</code></a></li><li><a href="https://github.com/rust-lang/rust/issues/126769">Tracking Issue for <code>substr_range</code> and related methods</a></li><li><a href="https://github.com/rust-lang/rust/pull/147185">repr(transparent): do not consider repr(C) types to be 1-ZST</a></li><li><a href="https://github.com/rust-lang/rust/pull/145665">Don't require <code>T: RefUnwindSafe</code> for <code>vec::IntoIter&lt;T&gt;: UnwindSafe</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/145974">Stabilize -Zno-jump-tables into -Cjump-tables=bool</a></li><li><a href="https://github.com/rust-lang/rust/issues/55724">Tracking issue for alloc_layout_extra</a></li><li><a href="https://github.com/rust-lang/rust/pull/147136">Add warn-by-default lint for visibility on <code>const _</code> declarations</a></li><li><a href="https://github.com/rust-lang/rust/issues/117729">Tracking Issue for <code>debug_closure_helpers</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/146882">fully deprecate the legacy integral modules</a></li><li><a href="https://github.com/rust-lang/rust/issues/146705">Tracking Issue for <code>fmt_from_fn</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/144090">Make <code>IoSlice</code> and <code>IoSliceMut</code> methods unstably const</a></li><li><a href="https://github.com/rust-lang/rust/issues/135889">Tracking Issue for <code>VecDeque::pop_front_if</code> &amp; <code>VecDeque::pop_back_if</code></a></li><li>[disposition: unspecified] <a href="https://github.com/rust-lang/rust/pull/145628">[std][BTree] Fix behavior of <code>::append</code> to match documentation, <code>::insert</code>, and <code>::extend</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/144113">Impls and impl items inherit <code>dead_code</code> lint level of the corresponding traits and trait items</a></li><li><a href="https://github.com/rust-lang/rust/pull/140463">Document MaybeUninit bit validity</a></li></ul><a class="toclink" href="http://this-week-in-rust.org/atom.xml#compiler-team-mcps-only"></a><a href="https://github.com/rust-lang/compiler-team/issues?q=label%3Amajor-change%20%20label%3Afinal-comment-period">Compiler Team</a> <a href="https://forge.rust-lang.org/compiler/mcp.html">(MCPs only)</a><ul><li><a href="https://github.com/rust-lang/compiler-team/issues/931">Move unreachable code lint from HIR type check to a proper lint</a></li><li><a href="https://github.com/rust-lang/compiler-team/issues/930">Rename <code>//@ add-core-stubs</code> to <code>//@ add-minicore</code></a></li><li><a href="https://github.com/rust-lang/compiler-team/issues/928">Move annotation for profiling compiler-generated moves and copies.</a></li><li><a href="https://github.com/rust-lang/compiler-team/issues/927">Use <code>llvm-bitcode-linker</code> as the default linker for nvptx64-nvidia-cuda</a></li></ul><a class="toclink" href="http://this-week-in-rust.org/atom.xml#leadership-council"></a><a href="https://github.com/rust-lang/leadership-council/issues?q=state%3Aopen%20label%3Afinal-comment-period">Leadership Council</a><ul><li><a href="https://github.com/rust-lang/leadership-council/issues/232">Delegate GSoC money spending to the t-mentorship team</a></li></ul><p><em>No Items entered Final Comment Period this week for<a href="https://github.com/rust-lang/rfcs/labels/final-comment-period">Rust RFCs</a>,<a href="https://github.com/rust-lang/cargo/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Cargo</a>,<a href="https://github.com/rust-lang/lang-team/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc+">Language Team</a>,<a href="https://github.com/rust-lang/reference/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Language Reference</a> or<a href="https://github.com/rust-lang/unsafe-code-guidelines/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Unsafe Code Guidelines</a>.</em></p><p>Let us know if you would like your PRs, Tracking Issues or RFCs to be tracked as a part of this list.</p><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#new-and-updated-rfcs"></a><a href="https://github.com/rust-lang/rfcs/pulls">New and Updated RFCs</a></h6><ul><li><em>No New or Updated RFCs were created this week.</em></li></ul><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#upcoming-events">Upcoming Events</a></h4><p>Rusty Events between 2025-10-22 - 2025-11-19 🦀</p><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#virtual">Virtual</a></h5><ul><li>2025-10-22 | Virtual (Boulder, CO, US) | <a href="https://www.meetup.com/boulder-elixir/events/">Boulder Elixir</a><ul><li><a href="https://www.meetup.com/boulder-elixir/events/310996627/"><strong>Integrating Elixir and Apache DataFusion with Rustler</strong></a></li></ul></li><li>2025-10-22 | Virtual (Buenos Aires, AR) | <a href="https://www.meetup.com/es-ES/net-baires/">[Net-Baires] Comunidad de .NET en Buenos Aires</a><ul><li><a href="https://www.meetup.com/es-ES/net-baires/events/311365783/"><strong>Rust para devs .NET | Community Standup #10</strong></a></li></ul></li><li>2025-10-23 | Hybrid (Seattle/Bellevue, WA, US) | <a href="https://www.meetup.com/join-srug">Seattle Rust User Group</a><ul><li><a href="https://www.meetup.com/seattle-rust-user-group/events/311351020/"><strong>October, 2025 SRUG (Seattle Rust User Group) Meetup</strong></a></li></ul></li><li>2025-10-23 | Virtual (Berlin, DE) | <a href="https://www.meetup.com/rust-berlin">Rust Berlin</a><ul><li><a href="https://www.meetup.com/rust-berlin/events/306046641/"><strong>Rust Hack and Learn</strong></a></li></ul></li><li>2025-10-23 | Virtual (Girona, ES) | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/zyc3touy"><strong>Sessió setmanal de codificació / Weekly coding session</strong></a></li></ul></li><li>2025-10-26 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/311109171/"><strong>Rust Readers Discord Discussion: Macros</strong></a></li></ul></li><li>2025-10-28 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/305361444/"><strong>Fourth Tuesday</strong></a></li></ul></li><li>2025-10-30 | Virtual (Girona, ES) | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/t8yovmmm"><strong>Sessió setmanal de codificació / Weekly coding session</strong></a></li></ul></li><li>2025-11-01 | Virtual (Kampala, UG) | <a href="https://www.eventbrite.com/o/rust-circle-kampala-65249289033">Rust Circle Meetup</a><ul><li><a href="https://www.eventbrite.com/e/rust-circle-meetup-tickets-628763868657"><strong>Rust Circle Meetup</strong></a></li></ul></li><li>2025-11-02 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/311109173/"><strong>Rust Readers Discord Discussion: Macros</strong></a></li></ul></li><li>2025-11-05 | Virtual (Buffalo, NY, US) | <a href="https://www.meetup.com/buffalo-rust-meetup">Buffalo Rust Meetup</a><ul><li><a href="https://www.meetup.com/buffalo-rust-meetup/events/305304242/"><strong>Buffalo Rust User Group</strong></a></li></ul></li><li>2025-11-05 | Virtual (Indianapolis, IN, US) | <a href="https://www.meetup.com/indyrs">Indy Rust</a><ul><li><a href="https://www.meetup.com/indyrs/events/311574520/"><strong>Indy.rs - with Social Distancing</strong></a></li></ul></li><li>2025-11-05 | Virtual | <a href="https://www.eventbrite.com/o/ardan-labs-7092394651">Ardan Labs</a><ul><li><a href="https://www.eventbrite.com/e/mastering-error-handling-in-rust-from-panics-to-thiserror-anyhow-tickets-1849030121869"><strong>Mastering Error Handling in Rust: From Panics to thiserror &amp; anyhow</strong></a></li></ul></li><li>2025-11-06 | Virtual (Berlin, DE) | <a href="https://www.meetup.com/rust-berlin/events/">Rust Berlin</a><ul><li><a href="https://www.meetup.com/rust-berlin/events/305646021/"><strong>Rust Hack and Learn</strong></a></li></ul></li><li>2025-11-06 | Virtual (Girona, ES) | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/xkd84gfz"><strong>Sessió setmanal de codificació / Weekly coding session</strong></a></li></ul></li><li>2025-11-09 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/events/">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/311109175/"><strong>Rust Readers Discord Discussion: Macros</strong></a></li></ul></li><li>2025-11-10 || <a href="https://www.bettercode.eu/">BetterCode</a><ul><li>$<a href="https://dev.events/conferences/better-code-rust-i6inve6t"><strong>betterCode() Industrielle Anwendungen mit Rust</strong></a></li></ul></li><li>2025-11-11 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/events/">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/305361536/"><strong>Second Tuesday</strong></a></li></ul></li><li>2025-11-11 | Virtual (London, GB) | <a href="https://www.meetup.com/women-in-rust/events/">Women in Rust</a><ul><li><a href="https://www.meetup.com/women-in-rust/events/311068632/"><strong>👋 Community Catch Up</strong></a></li></ul></li><li>2025-11-13 | Virtual (Girona, ES) | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/yhe1xrhe"><strong>Sessió setmanal de codificació / Weekly coding session</strong></a></li></ul></li><li>2025-11-13 | Virtual (Nürnberg, DE) | <a href="https://www.meetup.com/rust-noris/events/">Rust Nuremberg</a><ul><li><a href="https://www.meetup.com/rust-noris/events/310849154/"><strong>Rust Nürnberg online</strong></a></li></ul></li><li>2025-11-16 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/events/">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/311109181/"><strong>Rust Readers Discord Discussion: Macros</strong></a></li></ul></li><li>2025-11-18 | Virtual (Washington, DC, US) | <a href="https://www.meetup.com/rustdc/events/">Rust DC</a><ul><li><a href="https://www.meetup.com/rustdc/events/310002262/"><strong>Mid-month Rustful</strong></a></li></ul></li><li>2025-11-19 | Virtual (Vancouver, BC, CA) | <a href="https://www.meetup.com/vancouver-rust/events/">Vancouver Rust</a><ul><li><a href="https://www.meetup.com/vancouver-rust/events/309926564/"><strong>Rust Study/Hack/Hang-out</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#asia">Asia</a></h5><ul><li>2025-11-15 | Bangalore, IN | <a href="https://hasgeek.com/rustbangalore">Rust Bangalore</a><ul><li><a href="https://hasgeek.com/rustbangalore/november-2025-rustacean-meetup//"><strong>November 2025 Rustacean meetup</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#europe">Europe</a></h5><ul><li>2025-10-23 | Edinburgh, UK | <a href="https://www.meetup.com/rust-edi/events/">Rust and Friends</a><ul><li><a href="https://www.meetup.com/rust-and-friends/events/311501254/"><strong>Rust and Friends (evening pub)</strong></a></li></ul></li><li>2025-10-24 | Edinburgh, UK | <a href="https://www.meetup.com/rust-edi/events/">Rust and Friends</a><ul><li><a href="https://www.meetup.com/rust-and-friends/events/311501249/"><strong>Rust and Friends (daytime coffee)</strong></a></li></ul></li><li>2025-10-28 | Manchester, UK | <a href="https://www.meetup.com/rust-manchester">Rust Manchester</a><ul><li><a href="https://www.meetup.com/rust-manchester/events/307919171/"><strong>Rust Manchester October Code Night</strong></a></li></ul></li><li>2025-10-29 | Dortmund, DE | <a href="https://www.meetup.com/rust-dortmund/events/">Rust Dortmund</a><ul><li><a href="https://www.meetup.com/rust-dortmund/events/311251545/"><strong>Rust Dortmund Meetup October 2025</strong></a></li></ul></li><li>2025-10-30 | Copenhagen, DK | <a href="https://www.meetup.com/copenhagen-rust-community">Copenhagen Rust Community</a><ul><li><a href="https://www.meetup.com/copenhagen-rust-community/events/311405044/"><strong>Rust meetup #62 sponsored by Google!</strong></a></li></ul></li><li>2025-10-30 | Prague, CZ | <a href="https://www.meetup.com/rust-prague">Rust Prague</a><ul><li><a href="https://www.meetup.com/rust-prague/events/310967094/"><strong>Rust Meetup Prague (October 2025)</strong></a></li></ul></li><li>2025-11-01 | Stockholm, SE | <a href="https://www.meetup.com/stockholm-rust/events/">Stockholm Rust</a><ul><li><a href="https://www.meetup.com/stockholm-rust/events/311582259/"><strong>Ferris' Fika Forum #19</strong></a></li></ul></li><li>2025-11-02 - 2025-11-04 | Florence, IT | <a href="https://rustlab.it/">Rustlab 2025</a><ul><li>$<a href="https://rustlab.it/"><strong>Rustlab 2025</strong></a></li></ul></li><li>2025-11-03 | Bern, CH | <a href="https://www.meetup.com/it-IT/guild42ch/">Guild42</a><ul><li><a href="https://www.meetup.com/it-IT/guild42ch/events/307260207/"><strong>Moving out of systems programming into Kubernetes: is it time to adopt Rust ?</strong></a></li></ul></li><li>2025-11-04 | Manchester, UK | <a href="https://www.meetup.com/rust-manchester">Rust Manchester</a><ul><li><a href="https://www.meetup.com/rust-manchester/events/310921632/"><strong>Rust Manchester November Talk</strong></a></li></ul></li><li>2025-11-04 | Trondheim, NO | <a href="https://www.meetup.com/rust-trondheim/events/">Rust Trondheim</a><ul><li><a href="https://www.meetup.com/rust-trondheim/events/311595023/"><strong>Optimizing matrix multiplication and building Python packages with Rust</strong></a></li></ul></li><li>2025-11-05 | Girona, ES | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/xl8ob0tn"><strong>Rust Girona Hack &amp; Learn 11 2025</strong></a></li></ul></li><li>2025-11-05 | Oslo, NO | <a href="https://www.meetup.com/rust-oslo">Rust Oslo</a><ul><li><a href="https://www.meetup.com/rust-oslo/events/310601872/"><strong>Rust Hack'n'Learn at Kampen Bistro</strong></a></li></ul></li><li>2025-11-05 | Oxford, UK | <a href="https://www.meetup.com/oxford-rust-meetup-group">Oxford ACCU/Rust Meetup.</a><ul><li><a href="https://www.meetup.com/oxford-rust-meetup-group/events/nnrkttyhcpbhb/"><strong>Rust/ACCU meetup.</strong></a></li></ul></li><li>2025-11-06 | Gdansk, PL | <a href="https://www.meetup.com/rust-gdansk/events/">Rust Gdansk</a><ul><li><a href="https://www.meetup.com/rust-gdansk/events/310924266/"><strong>Rust Gdansk Meetup #11</strong></a></li></ul></li><li>2025-11-12 | Reading, UK | <a href="https://www.meetup.com/reading-rust-workshop/events/">Reading Rust Workshop</a><ul><li><a href="https://www.meetup.com/reading-rust-workshop/events/308944050/"><strong>Reading Rust Meetup</strong></a></li></ul></li><li>2025-11-13 | Geneva, CH | <a href="https://www.posttenebraslab.ch/wiki/events/monthly_meeting/rust_meetup">Rust Geneva</a><ul><li><a href="https://www.posttenebraslab.ch/wiki/events/monthly_meeting/rust_meetup"><strong>Rust Meetup Geneva</strong></a></li></ul></li><li>2025-11-13 | Paris, FR | <a href="https://www.meetup.com/rust-paris/events/">Rust Paris</a><ul><li><a href="https://www.meetup.com/rust-paris/events/311461594/"><strong>Rust meetup #80</strong></a></li></ul></li><li>2025-11-18 | Leipzig, SN, DE | <a href="https://www.meetup.com/rust-modern-systems-programming-in-leipzig/events/">Rust - Modern Systems Programming in Leipzig</a><ul><li><a href="https://www.meetup.com/rust-modern-systems-programming-in-leipzig/events/308592257/"><strong>Topic TBD</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#north-america">North America</a></h5><ul><li>2025-10-22 | Austin, TX, US | <a href="https://www.meetup.com/rust-atx">Rust ATX</a><ul><li><a href="https://www.meetup.com/rust-atx/events/310457307/"><strong>Rust Lunch - Fareground</strong></a></li></ul></li><li>2025-10-23 | Nashville, TN, US | <a href="https://www.meetup.com/music-city-rust-developers">Music City Rust Developers</a><ul><li><a href="https://www.meetup.com/music-city-rust-developers/events/304333267/"><strong>Year In Review</strong></a></li></ul></li><li>2025-10-23 | Hybrid (Seattle/Bellevue, WA, US) | <a href="https://www.meetup.com/join-srug">Seattle Rust User Group</a><ul><li><a href="https://www.meetup.com/seattle-rust-user-group/events/311351020/"><strong>October, 2025 SRUG (Seattle Rust User Group) Meetup</strong></a></li></ul></li><li>2025-10-23 | Spokane, WA, US | <a href="https://www.meetup.com/spokane-rust">Spokane Rust</a><ul><li><a href="https://www.meetup.com/spokane-rust/events/311346444/"><strong>October Rust Meetup: A Special Presentation and Monthly Meetups are Back!</strong></a></li></ul></li><li>2025-10-25 | Boston, MA, US | <a href="https://www.meetup.com/bostonrust">Boston Rust Meetup</a><ul><li><a href="https://www.meetup.com/bostonrust/events/310983712/"><strong>Porter Square Rust Lunch, Oct 25</strong></a></li></ul></li><li>2025-10-25 | Dallas, TX, US | <a href="https://www.meetup.com/dallasrust/events/">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/311562607/"><strong>In-person Meetup with Collin College Software Engineering Club!</strong></a></li></ul></li><li>2025-10-28 | Chicago, IL, US | <a href="https://www.meetup.com/chicago-rust-meetup/events/">Chicago Rust Meetup</a><ul><li><a href="https://www.meetup.com/chicago-rust-meetup/events/311603282/"><strong>Rust Happy Hour</strong></a></li></ul></li><li>2025-10-29 | New York, NY, US | <a href="https://www.meetup.com/rust-nyc/events/">Rust NYC</a><ul><li><a href="https://www.meetup.com/rust-nyc/events/311541108/"><strong>Rust NYC: Scalable static analysis: confronting the halting problem</strong></a></li></ul></li><li>2025-10-30 | Atlanta, GA, US | <a href="https://www.meetup.com/rust-atl">Rust Atlanta</a><ul><li><a href="https://www.meetup.com/rust-atl/events/308675988/"><strong>Rust-Atl</strong></a></li></ul></li><li>2025-10-30 | Mountain View, CA, US | <a href="https://www.meetup.com/hackerdojo/events/">Hacker Dojo</a><ul><li><a href="https://www.meetup.com/hackerdojo/events/311273832/"><strong>RUST MEETUP at HACKER DOJO</strong></a></li></ul></li><li>2025-11-01 | Boston, MA, US | <a href="https://www.meetup.com/bostonrust">Boston Rust Meetup</a><ul><li><a href="https://www.meetup.com/bostonrust/events/311039492/"><strong>Chinatown Rust Lunch, Nov 1</strong></a></li></ul></li><li>2025-11-06 | Saint Louis, MO, US | <a href="https://www.meetup.com/stl-rust/events/">STL Rust</a><ul><li><a href="https://www.meetup.com/stl-rust/events/307251982/"><strong>SIUE students on wasm 3D animations</strong></a></li></ul></li><li>2025-11-08 | Boston, MA, US | <a href="https://www.meetup.com/bostonrust/events/">Boston Rust Meetup</a><ul><li><a href="https://www.meetup.com/bostonrust/events/311039501/"><strong>Winter Hill Rust Lunch, Nov 8</strong></a></li></ul></li><li>2025-11-13 | Lehi, UT, US | <a href="https://www.meetup.com/utah-rust/events/">Utah Rust</a><ul><li><a href="https://www.meetup.com/utah-rust/events/311613658/"><strong>Ipmap: Building Desktop Apps with Tauri</strong></a></li></ul></li><li>2025-11-18 | San Francisco, CA, US | <a href="https://www.meetup.com/san-francisco-rust-study-group/events/">San Francisco Rust Study Group</a><ul><li><a href="https://www.meetup.com/san-francisco-rust-study-group/events/308865806/"><strong>Rust Hacking in Person</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#oceania">Oceania</a></h5><ul><li>2025-10-22 | Perth, AU | <a href="https://www.meetup.com/perth-rust-meetup-group">Rust Perth Meetup Group</a><ul><li><a href="https://www.meetup.com/perth-rust-meetup-group/events/310847099/"><strong>October Meetup</strong></a></li></ul></li><li>2025-10-28 | Barton, AU | <a href="https://www.meetup.com/rust-canberra">Canberra Rust User Group</a><ul><li><a href="https://www.meetup.com/rust-canberra/events/311234237/"><strong>October Meetup</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#south-america">South America</a></h5><ul><li>2025-10-22 | Montevideo, UY | <a href="https://www.meetup.com/rust-uruguay/events/">Rust Meetup Uruguay</a><ul><li><a href="https://www.meetup.com/rust-uruguay/events/311475675/"><strong>Rust Uruguay meetup de Octubre</strong></a></li></ul></li><li>2025-10-25 | São Paulo, BR | <a href="https://www.meetup.com/rust-sao-paulo-meetup">Rust São Paulo Meetup</a><ul><li><a href="https://www.meetup.com/rust-sao-paulo-meetup/events/311084440/"><strong>Encontro do Rust-SP na Amazon Web Services</strong></a></li></ul></li><li>2025-10-30 | Florianopolis, BR | <a href="https://luma.com/calendar/cal-iOloL5ZqswCO5Mm">Rust Brasil</a><ul><li><a href="https://luma.com/lky7an18"><strong>Rust Floripa</strong></a></li></ul></li></ul><p>If you are running a Rust event please add it to the <a href="https://www.google.com/calendar/embed?src=apd9vmbc22egenmtu5l6c5jbfc%40group.calendar.google.com">calendar</a> to getit mentioned here. Please remember to add a link to the event too.Email the <a href="mailto:community-team@rust-lang.org">Rust Community Team</a> for access.</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#jobs">Jobs</a></h4><p>Please see the latest <a href="https://www.reddit.com/r/rust/comments/1nknaii/official_rrust_whos_hiring_thread_for_jobseekers/">Who's Hiring thread on r/rust</a></p><h3><a class="toclink" href="http://this-week-in-rust.org/atom.xml#quote-of-the-week">Quote of the Week</a></h3><blockquote><p>There used to be recurring questions about mod vs use in the user forum, until I've added a note to the error message [...] and I think it largely solved the problem</p></blockquote><p>– <a href="https://internals.rust-lang.org/t/curly-brace-support-for-mod/23437/51">Kornel on rust-internals</a></p><p>Thanks to <a href="https://users.rust-lang.org/t/twir-quote-of-the-week/328/1722">Noratrieb</a> for the suggestion!</p><p><a href="https://users.rust-lang.org/t/twir-quote-of-the-week/328">Please submit quotes and vote for next week!</a></p><p><em>This Week in Rust is edited by: <a href="https://github.com/nellshamrell">nellshamrell</a>, <a href="https://github.com/llogiq">llogiq</a>, <a href="https://github.com/cdmistman">cdmistman</a>, <a href="https://github.com/ericseppanen">ericseppanen</a>, <a href="https://github.com/extrawurst">extrawurst</a>, <a href="https://github.com/U007D">U007D</a>, <a href="https://github.com/joelmarcey">joelmarcey</a>, <a href="https://github.com/mariannegoldin">mariannegoldin</a>, <a href="https://github.com/bennyvasquez">bennyvasquez</a>, <a href="https://github.com/bdillo">bdillo</a></em></p><p><em>Email list hosting is sponsored by <a href="https://foundation.rust-lang.org/">The Rust Foundation</a></em></p><p><small><a href="https://www.reddit.com/r/rust/comments/1odqrri/this_week_in_rust_622/">Discuss on r/rust</a></small></p></description> <pubDate>Wed, 22 Oct 2025 04:00:00 +0000</pubDate> <dc:creator>TWiR Contributors</dc:creator></item><item> <title>Niko Matsakis: Move, Destruct, Forget, and Rust</title> <guid isPermaLink="false">https://smallcultfollowing.com/babysteps/blog/2025/10/21/move-destruct-leak/</guid> <link>https://smallcultfollowing.com/babysteps/blog/2025/10/21/move-destruct-leak/?utm_source=atom_feed</link> <description><p>This post presents a proposal to extend Rust to support a number of different kinds of destructors. This means we could async drop, but also prevent “forgetting” (leaking) values, enabling async scoped tasks that run in parallel à la rayon/libstd. We’d also be able to have types whose “destructors” require arguments. This proposal – an evolution of <a href="https://smallcultfollowing.com/babysteps/ /blog/2023/03/16/must-move-types.html">“must move”</a> that I’ll call “controlled destruction” – is, I think, needed for Rust to live up to its goal of giving safe versions of critical patterns in systems programming. As such, it is needed to complete the “async dream”, in which async Rust and sync Rust work roughly the same.</p><p>Nothing this good comes for free. The big catch of the proposal is that it introduces more “core splits” into Rust’s types. I believe these splits are well motivated and reasonable – they reflect <em>inherent complexity</em>, in other words, but they are something we’ll want to think carefully about nonetheless.</p><h3>Summary</h3><p>The TL;DR of the proposal is that we should:</p><ul><li>Introduce a new “default trait bound” <code>Forget</code> and an associated trait hierarchy:<ul><li><code>trait Forget: Drop</code>, representing values that can be forgotten</li><li><code>trait Destruct: Move</code>, representing values with a destructor</li><li><code>trait Move: Pointee</code>, representing values that can be moved</li><li><code>trait Pointee</code>, the base trait that represents <em>any value</em></li></ul></li><li>Use the “opt-in to weaker defaults” scheme proposed for sizedness by <a href="https://github.com/rust-lang/rfcs/pull/3729">RFC #3729 (Hierarchy of Sized Traits)</a><ul><li>So <code>fn foo&lt;T&gt;(t: T)</code> defaults to “a <code>T</code> that can be forgotten/destructed/moved”</li><li>And <code>fn foo&lt;T: Destruct&gt;(t: T)</code> means “a <code>T</code> that can be destructed, but not necessarily forgotten”</li><li>And <code>fn foo&lt;T: Move&gt;(t: T)</code> means “a <code>T</code> that can be moved, but not necessarily forgotten”</li><li>…and so forth.</li></ul></li><li>Integrate and enforce the new traits:<ul><li>The bound on <code>std::mem::forget</code> will already require <code>Forget</code>, so that’s good.</li><li>Borrow check can enforce that any dropped value must implement <code>Destruct</code>; in fact, we already do this to enforce <code>const Destruct</code> bounds in <code>const fn</code>.</li><li>Borrow check can be extended to require a <code>Move</code> bound on any moved value.</li></ul></li><li>Adjust the trait bound on closures (luckily this works out fairly nicely)</li></ul><h3>Motivation</h3><p>In a <a href="https://nikomatsakis.github.io/rust-latam-2019/#1">talk I gave some years back at Rust LATAM in Uruguay</a><sup id="fnref:1"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:1">1</a></sup>, I <a href="https://nikomatsakis.github.io/rust-latam-2019/#81">said this</a>:</p><ul><li>It’s easy to <strong>expose</strong> a high-performance API.</li><li>But it’s hard to <strong>help users control it</strong> – and this is what Rust’s type system does.</li></ul><img alt="Person casting a firespell and burning themselves" src="https://smallcultfollowing.com/babysteps/ /assets/2025-movedestructleak/firespell.gif" /><p>Rust currently does a pretty good job with preventing parts of your program from interfering with one another, but we don’t do as good a job when it comes to guaranteeing that cleaup happens<sup id="fnref:2"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:2">2</a></sup>. We have destructors, of course, but they have two critical limitations:</p><ul><li>All destructors must meet the same signature, <code>fn drop(&amp;mut self)</code>, which isn’t always adequate.</li><li>There is no way to guarantee a destructor once you give up ownership of a value.</li></ul><h4>Making it concrete.</h4><p>That motivation was fairly abstract, so let me give some concrete examples of things that tie back to this limitation:</p><ul><li>The ability to have <code>async</code> or <code>const</code> drop, both of which require a distinct drop signature.</li><li>The ability to have a “drop” operation that takes arguments, such as e.g. a message that must be sent, or a result code that must be provided before the program terminates.</li><li>The ability to have async scopes that can access the stack, which requires a way to guarantee that a parallel thread will be joined even in an async context.</li><li>The ability to integrate at maximum efficiency with WebAssembly async tasks, which require guaranteed cleanup.<sup id="fnref:3"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:3">3</a></sup></li></ul><p>The goal of this post is to outline an approach that could solve all of the above problems and which is backwards compatible with Rust today.</p><h4>The “capabilities” of value disposal</h4><p>The core problem is that Rust today assumes that every <code>Sized</code> value can be moved, dropped, and forgotten:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="c1">// Without knowing anything about `T` apart</span></span></span><span class="line"><span class="cl"><span class="c1">// from the fact that it's `Sized`, we can...</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">fn</span> <span class="nf">demonstration</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">a</span>: <span class="nc">T</span><span class="p">,</span><span class="w"> </span><span class="n">b</span>: <span class="nc">T</span><span class="p">,</span><span class="w"> </span><span class="n">c</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// ...drop `a`, running its destructor immediately.</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">std</span>::<span class="n">mem</span>::<span class="nb">drop</span><span class="p">(</span><span class="n">a</span><span class="p">);</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// ...forget `b`, skipping its destructor</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">std</span>::<span class="n">mem</span>::<span class="n">forget</span><span class="p">(</span><span class="n">b</span><span class="p">);</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// ...move `c` into `x`</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">c</span><span class="p">;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span><span class="c1">// ...and then have `x` get dropped automatically,</span></span></span><span class="line"><span class="cl"><span class="c1">// as exit the block.</span></span></span></code></pre></div><h4>Destructors are like “opt-out methods”</h4><p>The way I see, most methods are “opt-in” – they don’t execute unless you call them. But destructors are different. They are effectively a method that runs by default – unless you opt-out, e.g., by calling <code>forget</code>. But the ability to opt-out means that they don’t fundamentally add any power over regular methods, they just make for a more ergonomic API.</p><p>The implication is that the only way in Rust today to <em>guarantee</em> that a destructor will run is to retain ownership of the value. This can be important to unsafe code – APIs that permit scoped threads, for example, need to <em>guarantee</em> that those parallel threads will be joined before the function returns. The only way they have to do that is to use a closure which gives <code>&amp;</code>-borrowed access to a <code>scope</code>:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="n">scope</span><span class="p">(</span><span class="o">|</span><span class="n">s</span><span class="o">|</span><span class="w"> </span><span class="o">..</span><span class="p">.)</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// - --- ...which ensures that this</span></span></span><span class="line"><span class="cl"><span class="c1">// | fn body cannot "forget" it.</span></span></span><span class="line"><span class="cl"><span class="c1">// | </span></span></span><span class="line"><span class="cl"><span class="c1">// This value has type `&amp;Scope`... </span></span></span></code></pre></div><p>Because the API nevers gives up ownership of the scope, it can ensure that it is never “forgotten” and thus that its destructor runs.</p><p>The scoped thread approach works for sync code, but it doesn’t work for async code. The problem is that async functions return a future, which is a value. Users can therefore decide to “forget” this value, just like any other value, and thus the destructor may never run.</p><h4>Guaranteed cleanup is common in systems programming</h4><p>When you start poking around, you find that <em>guaranteed</em> destructors turn up quite a bit in systems programming. Scoped APIs in futures are one example, but DMA (direct memory access) is another. Many embedded devices have a mode where you begin a DMA transfer that causes memory to be written into memory asynchronously. But you need to ensure that this DMA is terminated <em>before</em> that memory is freed. If that memory is on your stack, that means you need a destructor that will either cancel or block until the DMA finishes.<sup id="fnref:4"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:4">4</a></sup></p><h3>So what can we do about it?</h3><p>This situation is very analogous to the challenge of revisiting the default <code>Sized</code> bound, and I think the same basic approach that I outlined in [this blog post][sized] will work.</p><p>The core of the idea is simple: have a “special” set of traits arranged in a hierarchy:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">trait</span><span class="w"> </span><span class="n">Forget</span>: <span class="nc">Destruct</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// Can be "forgotten"</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">trait</span><span class="w"> </span><span class="n">Destruct</span>: <span class="nc">Move</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// Can be "destructed" (dropped)</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">trait</span><span class="w"> </span><span class="n">Move</span>: <span class="nc">Pointee</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// Can be "moved"</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">trait</span><span class="w"> </span><span class="n">Pointee</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// Can be referenced by pointer</span></span></span></code></pre></div><p>By default, generic parameters get a <code>Forget</code> bound, so <code>fn foo&lt;T&gt;()</code> is equivalent to <code>fn foo&lt;T: Forget&gt;()</code>. But if the parameter <em>opts in</em> to a weaker bound, then the default is suppressed, so <code>fn bar&lt;T: Destruct&gt;()</code> means that <code>T</code> is assumed by “destructible” but <em>not</em> forgettable. And <code>fn baz&lt;T: Move&gt;()</code> indicates that <code>T</code> can <em>only</em> be moved.</p><h3>Impact of these bounds</h3><p>Let me explain briefly how these bounds would work.</p><h4>The default can forget, drop, move etc</h4><p>Given a default type <code>T</code>, or one that writes <code>Forget</code> explicitly, the function can do anything that is possible today:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">just_forget</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nc">Forget</span><span class="o">&gt;</span><span class="p">(</span><span class="n">a</span>: <span class="nc">T</span><span class="p">,</span><span class="w"> </span><span class="n">b</span>: <span class="nc">T</span><span class="p">,</span><span class="w"> </span><span class="n">c</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// --------- this bound is the default</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">std</span>::<span class="n">mem</span>::<span class="nb">drop</span><span class="p">(</span><span class="n">a</span><span class="p">);</span><span class="w"> </span><span class="c1">// OK</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">std</span>::<span class="n">mem</span>::<span class="n">forget</span><span class="p">(</span><span class="n">b</span><span class="p">);</span><span class="w"> </span><span class="c1">// OK</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">c</span><span class="p">;</span><span class="w"> </span><span class="c1">// OK</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span><span class="w"></span></span></span></code></pre></div><h4>The forget function requires <code>T: Forget</code></h4><p>The <code>std::mem::forget</code> function would require <code>T: Forget</code> as well:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">forget</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nc">Forget</span><span class="o">&gt;</span><span class="p">(</span><span class="n">value</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="cm">/* magic intrinsic */</span><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span></code></pre></div><p>This means that if you have only <code>Destruct</code>, the function can only drop or move, it can’t “forget”:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">just_destruct</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nc">Destruct</span><span class="o">&gt;</span><span class="p">(</span><span class="n">a</span>: <span class="nc">T</span><span class="p">,</span><span class="w"> </span><span class="n">b</span>: <span class="nc">T</span><span class="p">,</span><span class="w"> </span><span class="n">c</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// -----------</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// This function only requests "Destruct" capability.</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">std</span>::<span class="n">mem</span>::<span class="nb">drop</span><span class="p">(</span><span class="n">a</span><span class="p">);</span><span class="w"> </span><span class="c1">// OK</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">std</span>::<span class="n">mem</span>::<span class="n">forget</span><span class="p">(</span><span class="n">b</span><span class="p">);</span><span class="w"> </span><span class="c1">// ERROR: `T: Forget` required</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">c</span><span class="p">;</span><span class="w"> </span><span class="c1">// OK</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span><span class="w"></span></span></span></code></pre></div><h4>The borrow checker would require “dropped” values implement <code>Destruct</code></h4><p>We would modify the <code>drop</code> function to require only <code>T: Destruct</code>:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">drop</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nc">Destruct</span><span class="o">&gt;</span><span class="p">(</span><span class="n">t</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span><span class="p">{}</span><span class="w"></span></span></span></code></pre></div><p>We would also extend the borrow checker so that when it sees a value being dropped (i.e., because it went out of scope), it would require the <code>Destruct</code> bound.</p><p>That means that if you have a value whose type is only <code>Move</code>, you cannot “drop” it:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">just_move</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nc">Move</span><span class="o">&gt;</span><span class="p">(</span><span class="n">a</span>: <span class="nc">T</span><span class="p">,</span><span class="w"> </span><span class="n">b</span>: <span class="nc">T</span><span class="p">,</span><span class="w"> </span><span class="n">c</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// -----------</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// This function only requests "Move" capability.</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">std</span>::<span class="n">mem</span>::<span class="nb">drop</span><span class="p">(</span><span class="n">a</span><span class="p">);</span><span class="w"> </span><span class="c1">// ERROR: `T: Destruct` required</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">std</span>::<span class="n">mem</span>::<span class="n">forget</span><span class="p">(</span><span class="n">b</span><span class="p">);</span><span class="w"> </span><span class="c1">// ERROR: `T: Forget` required</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">c</span><span class="p">;</span><span class="w"> </span><span class="c1">// OK</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span><span class="w"> </span><span class="c1">// ERROR: `x` is being dropped, but `T: Destruct`</span></span></span></code></pre></div><p>This means that if you have only a <code>Move</code> bound, you <em>must</em> move anything you own if you want to return from the function. For example:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">return_ok</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nc">Move</span><span class="o">&gt;</span><span class="p">(</span><span class="n">a</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">T</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="c1">// OK</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span><span class="w"></span></span></span></code></pre></div><p>If you have a function that does not move, you’ll get an error:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">return_err</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nc">Move</span><span class="o">&gt;</span><span class="p">(</span><span class="n">a</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">T</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span><span class="c1">// ERROR: `a` does not implement `Destruct`</span></span></span></code></pre></div><p>It’s worth pointing out that this will be annoying as all get out in the face of panics:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">return_err</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nc">Move</span><span class="o">&gt;</span><span class="p">(</span><span class="n">a</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">T</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// ERROR: If a panic occurs, `a` would be dropped, but `T` not implement `Destruct`</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">forbid_env_var</span><span class="p">();</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">a</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">fn</span> <span class="nf">forbid_env_var</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">std</span>::<span class="n">env</span>::<span class="n">var</span><span class="p">(</span><span class="s">"BAD"</span><span class="p">).</span><span class="n">is_ok</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">panic!</span><span class="p">(</span><span class="s">"Uh oh: BAD cannot be set"</span><span class="p">);</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"></span></span></span></code></pre></div><p>I’m ok with this, but it is going to put pressure on better ways to rule out panics statically.</p><h4>Const (and later async) variants of <code>Destruct</code></h4><p>In fact, we are already doing something much like this destruct check for const functions. Right now if you have a const fn and you try to drop a value, you get an error:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">const</span><span class="w"> </span><span class="k">fn</span> <span class="nf">test</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">t</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span><span class="c1">// ERROR!</span></span></span></code></pre></div><p>Compiling that gives you the error:</p><pre tabindex="0"><code>error[E0493]: destructor of `T` cannot be evaluated at compile-time --&gt; src/lib.rs:1:18 |1 | const fn test&lt;T&gt;(t: T) { } | ^ - value is dropped here | | | the destructor for this type cannot be evaluated in constant functions</code></pre><p>This check is not presently taking place in borrow check but it could be.</p><h4>The borrow checker would require “moved” values implement <code>Move</code></h4><p>The final part of the check would be requiring that “moved” values implement <code>Move</code>:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">return_err</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nc">Pointee</span><span class="o">&gt;</span><span class="p">(</span><span class="n">a</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">T</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="c1">// ERROR: `a` does not implement `Move`</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span><span class="w"></span></span></span></code></pre></div><p>You might think that having types that are <code>!Move</code> would replace the need for pin, but this is not the case. A <em>pinned</em> value is one that can <em>never move again</em>, whereas a value that is not <code>Move</code> can never be moved in the first place – at least once it is stored into a place.</p><p>I’m not sure if this part of the proposal makes sense, we could start by just having all types be <code>Move</code>, <code>Destruct</code>, or (the default) <code>Forget</code>.</p><h4>Opting out from forget etc</h4><p>The other part of the proposal is that you should be able to explicit “opt out” from being forgettable, e.g. by doing</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">struct</span> <span class="nc">MyType</span><span class="w"> </span><span class="p">{}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">impl</span><span class="w"> </span><span class="n">Destruct</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">MyType</span><span class="w"> </span><span class="p">{}</span><span class="w"></span></span></span></code></pre></div><p>Doing this will limit the generics that can accept your type, of course.</p><h4>Associated type bounds</h4><p>The tough part with these “default bound” proposals is always associated type bounds. For backwards compatibility, we’d have to default to <code>Forget</code> but a lot of associated types that exist in the wild today shouldn’t really <em>require</em> <code>Forget</code>. For example a trait like <code>Add</code> should <em>really</em> just require <code>Move</code> for its return type:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">trait</span><span class="w"> </span><span class="n">Add</span><span class="o">&lt;</span><span class="n">Rhs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">Self</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">type</span> <span class="nc">Output</span><span class="w"> </span><span class="cm">/* : Move */</span><span class="p">;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"></span></span></span></code></pre></div><p>I am basically not too worried about this. It’s possible that we can weaken these bounds over time or through editions. Or, perhaps, add in some kind of edition-specific “alias” like</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">trait</span><span class="w"> </span><span class="n">Add2025</span><span class="o">&lt;</span><span class="n">Rhs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">Self</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">type</span> <span class="nc">Output</span>: <span class="nc">Move</span><span class="p">;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"></span></span></span></code></pre></div><p>where <code>Add2025</code> is implemented for everything that implements <code>Add</code>.</p><p>I am not sure exactly how to manage it, but we’ll figure it out – and in the meantime, most of the types that should not be forgettable are really just “guard” types that don’t have to flow through quite so many places.</p><h5>Associated type bounds in closures</h5><p>The one place that I think it is <em>really imporatnt</em> that we weaken the associated type bounds is with closures– and, fortunately, that’s a place we can get away with due to the way our “closure trait bound” syntax works. I feel like I wrote a post on this before, but I can’t find it now, but the short version is that, today, when you write <code>F: Fn()</code>, that means that the closure must return <code>()</code>. If you write <code>F: Fn() -&gt; T</code>, then this type <code>T</code> must have been declared somewhere else, and so <code>T</code> will (independently from the associated type of the <code>Fn</code> trait) get a default <code>Forget</code> bound. So since the <code>Fn</code> associated type is not independently nameable in stable Rust, we can change its bounds, and code like this would continue to work unchanged:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">foo</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">F</span><span class="o">&gt;</span><span class="p">()</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">where</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">F</span>: <span class="nb">Fn</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="nc">T</span><span class="p">,</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// - `T: Forget` still holds by default</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">{}</span><span class="w"></span></span></span></code></pre></div><h3>Frequently asked questions</h3><h4>How does this relate to the recent thread on internals?</h4><p>Recently I was pointed at <a href="https://internals.rust-lang.org/t/pre-rfc-substructural-type-system/23614">this internals thread</a> for a “substructural type system” which likely has very similar capabilities. To be totally honest, though, I haven’t had time to read and digest it yet! I had this blog post like 95% done though so I figured I’d post it first and then go try and compare.</p><h4>What would it mean for a struct to opt out of <code>Move</code> (e.g., by being only <code>Pointee</code>)?</h4><p>So, the system as I described <em>would</em> allow for ‘unmoveable’ types (i.e., a struct that opts out from everything and only permits <code>Pointee</code>), but such a struct would only really be something you could store in a static memory location. You couldn’t put it on the stack because the stack must eventually get popped. And you couldn’t move it from place to place because, well, it’s immobile.</p><p>This seems like something that could be useful – e.g., to model “video RAM” or something that lives in a specific location in memory and cannot live anywhere else – but it’s not a widespread need.</p><h4>How would you handle destructors with arguments?</h4><p>I imagine something like this:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">struct</span> <span class="nc">Transaction</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">data</span>: <span class="nb">Vec</span><span class="o">&lt;</span><span class="kt">u8</span><span class="o">&gt;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="sd">/// Opt out from destruct</span></span></span><span class="line"><span class="cl"><span class="sd"></span><span class="k">impl</span><span class="w"> </span><span class="n">Move</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">Transaction</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">impl</span><span class="w"> </span><span class="n">Transaction</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// This is effectively a "destructor"</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">complete</span><span class="p">(</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">connection</span>: <span class="nc">Connection</span><span class="p">,</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">Transaction</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">data</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">self</span><span class="p">;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"></span></span></span></code></pre></div><p>With this setup, any function that owns a <code>Transaction</code> must eventually invoke <code>transaction.complete()</code>. This is because no values of this type can be dropped, so they must be moved.</p><h4>How does this relate to async drop?</h4><p>This setup provides attacks a key problem that has blocked async drop in my mind, which is that types that are “async drop” do not have to implement “sync drop”. This gives the type system the ability to prevent them from being dropped in sync code, then, and it would mean that they can only be dropped in async drop. But there’s still lots of design work to be done there.</p><h4>Why is the trait <code>Destruct</code> and not <code>Drop</code>?</h4><p>This comes from the const generifs work. I don’t love it. But there is a logic to it. Right now, when you drop a struct or other value, that actually does a whole sequence of things, only one of which is running any <code>Drop</code> impl – it also (for example) drops all the fields in the struct recursively, etc. The idea is that “destruct” refers to this whole sequence.</p><h4>How hard would this to be to prototype?</h4><p>I…don’t actually think it would be very hard. I’ve thought somewhat about it and all of the changes seem pretty straightforward. I would be keen to support a <a href="https://lang-team.rust-lang.org/how_to/experiment.html">lang-team experiment</a> on this.</p><h4>Does this mean we should have had leak?</h4><p>The whole topic of destructors and leaks and so forth datesback to approximately Rust 1.0, when we discovered that, in fact, our abstraction for threads was unsound when combined with cyclic ref-counted boxes. Before that we hadn’t fully internalized that destructors are “opt-out methods”. You can read <a href="https://smallcultfollowing.com/babysteps/ /blog/2015/04/29/on-reference-counting-and-leaks/">this blog post I wrote at the time</a>. At the time, the primary idea was to have some kind of <code>?Leak</code> bounds and it was tied to the idea of references (so that all <code>'static</code> data was assumed to be “leakable”, and hence something you could put into an <code>Rc</code>). I… mostly think we made the right call at the time. I think it’s good that most of the ecosystem is interoperable and that <code>Rc</code> doesn’t require <code>static</code> bounds, and certainly I think it’s good that we moved to 1.0 with minimal disruption. In any case, though, I rather prefer this design to the ones that were under discussion at the time, in part because it also addresses the need for different kinds of destructors and for destructors with many arguments and so forth, which wasn’t something we thought about then.</p><h4>Isn’t it confusing to have these “magic” traits that “opt out” from default bounds?</h4><p>I think that specifying the <em>bounds you want</em> is inherently better than today’s <code>?</code> design, both because it’s easier to understand and because it allows us to backwards compatibly add traits in between in ways that are not possible with the <code>?</code> design.</p><p>However, I do see that having <code>T: Move</code> mean that <code>T: Destruct</code> does not hold is subtle. I wonder if we should adopt some kind of sigil or convention on these traits, like <code>T: @Move</code> or something. I don’t know! Something to consider.</p><div class="footnotes"><hr /><ol><li id="fn:1"><p>That was a great conference. Also, interestingly, this is one of my favorite of all my talks, but for some reason, I rarely reuse this material. I should change that. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:1">↩︎</a></p></li><li id="fn:2"><p>Academics distinguish “safety” from “liveness properties”, where safety means “bad things don’t happen” and “liveness” means “good things eventually happen”. Another way of saying this is that Rust’s type system helps with a lot of safety properties but struggles with liveness properties. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:2">↩︎</a></p></li><li id="fn:3"><p>Uh, citation needed. I know this is true but I can’t find the relevant WebAssembly issue where it is discussed. Help, internet! <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:3">↩︎</a></p></li><li id="fn:4"><p>Really the DMA problem is the same as scoped threads. If you think about it, the embedded device writing to memory is basically the same as a parallel thread writing to memory. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:4">↩︎</a></p></li></ol></div></description> <pubDate>Wed, 22 Oct 2025 01:45:02 +0000</pubDate></item><item> <title>Mozilla Addons Blog: Developer Spotlight: Fox Recap</title> <guid isPermaLink="false">https://blog.mozilla.org/addons/?p=9262</guid> <link>https://blog.mozilla.org/addons/2025/10/21/developer-spotlight-fox-recap/</link> <description><div class="wp-caption alignleft" id="attachment_9263" style="width: 590px;"><a href="https://addons.mozilla.org/en-US/firefox/addon/fox-recap/"><img alt="" class="size-medium wp-image-9263" height="435" src="https://blog.mozilla.org/addons/files/2025/10/blog_FoxRecap-580x435.png" width="580" /></a><p class="wp-caption-text" id="caption-attachment-9263">The Fox Recap team (pictured left to right): Taimur Hasan, Mozilla community manager Matt Cool, Kate Sawtell, Diego Valdez (not pictured: Peter Mitchell).</p></div><p>“What if we did a Spotify Wrapped for your browser?” wondered a group of Cal State Monterey Bay computer science students. That was the initial spark of an idea that became <a href="https://addons.mozilla.org/firefox/addon/fox-recap/" rel="noopener" target="_blank">Fox Recap</a> — a Firefox extension that leverages machine learning to give Firefox users fascinating insights into their browsing habits, like peak usage hours, types of websites commonly visited (news, entertainment, shopping, etc.), navigation patterns, and more.</p><p><a href="https://www.linkedin.com/in/taimurhasan1/" rel="noopener" target="_blank">Taimur Hasan</a> was one of four CSMB students who built Fox Recap as part of a Mozilla-supported <a href="https://sites.google.com/csumb.edu/cscapstone-s2025/cs-projects/firefox-ai-platform?authuser=0" rel="noopener" target="_blank">Capstone project</a>. We spoke with Taimur about his experience building an AI-centered extension from scratch.</p><p><b>What makes Fox Recap an “AI” project?</b></p><p>Taimur Hasan: <i>Fox Recap uses Machine Learning behind the scenes to classify sites and generate higher level insights, like top/trending categories and transition patterns. I kept the “AI” messaging light on the listing page to avoid hype and focus on the experience. Ideally the AI features feel seamless and natural rather than front and center.</i></p><p><b>What was your most challenging development hurdle? </b></p><p>TH: <i>For me, the most challenging part of development was creating the inference pipeline, which means the part where you actually use the AI model to do something useful. It took careful optimization to run well on a typical laptop as load times were a priority.</i></p><p><b>What is your perception of young emergent developers like yourself and their regard for privacy on the web?</b></p><p>TH: <i>With data collection on the rise, privacy and security matter more than ever. Among dedicated and enthusiastic young developers, privacy will always be in mind.</i></p><p><b>How do you see AI and browser extensions interrelating in the coming years? Do you have a sense of mutual direction? </b></p><p>TH: <i>I expect wider use of small, task specific models that quietly improve the user experience in most browser extensions. For mutual direction in the browser and add-on space I can see the use of AI in manipulating the DOM being done pretty heavily in the future.</i></p><p><b>Any advice for other extension developers curious about AI integration? </b></p><p>TH: <i>Be clear about the use case and model choice before investing in training or fine tuning. Start simple, validate the value, then add complexity only if it clearly improves the experience.</i></p><p>To learn even more about Fox Recap’s development process, please see <a href="https://blog.mozilla.org/en/firefox/firefox-recap/" rel="noopener" target="_blank">Fox Recap: A student-built tool that analyzes your browsing habits</a>.</p><p>The post <a href="https://blog.mozilla.org/addons/2025/10/21/developer-spotlight-fox-recap/">Developer Spotlight: Fox Recap</a> appeared first on <a href="https://blog.mozilla.org/addons">Mozilla Add-ons Community Blog</a>.</p></description> <pubDate>Tue, 21 Oct 2025 17:36:13 +0000</pubDate> <dc:creator>Scott DeVaney</dc:creator></item><item> <title>Mozilla Privacy Blog: Behind the Manifesto: Standing up for encryption to keep the internet safe</title> <guid isPermaLink="false">https://blog.mozilla.org/netpolicy/?p=2512</guid> <link>https://blog.mozilla.org/netpolicy/2025/10/21/behind-the-manifesto-standing-up-for-encryption-to-keep-the-internet-safe/</link> <description><p><i>Welcome to the first blog of the series “Behind the Manifesto,” where we unpack core issues that are critical to Mozilla’s mission. The </i><a href="https://www.mozilla.org/en-US/about/manifesto/"><i>Mozilla Manifesto </i></a><i>represents Mozilla’s commitment to advancing an open, global internet. This blog series digs deeper on our vision for the web and the people who use it, and how these goals are advanced in policymaking and technology. </i></p><p>At Mozilla, we’ve <a href="https://blog.mozilla.org/en/mozilla/help-us-spread-the-word-encryption-matters/#:~:text=This%20is%20why%20Mozilla%20has,alone%20will%20not%20be%20enough.">long said</a> the internet is one of the world’s most important public resources, something that only thrives when guided by core principles. One of those principles is that individual security and privacy online are fundamental.</p><p><a href="https://support.mozilla.org/en-US/products/firefox/privacy-and-security/encryption">Encryption</a> is the technology that makes secure and private online interactions possible. It protects our messages, our data, and our privacy, sitting in the center of security and trust on the internet. Given its critical role in online privacy, it can be a focal point for policymakers.</p><table><tbody><tr><td><b>The truth is, encryption is integral to digital trust and safety. Strong encryption keeps us safe while weak encryption puts our personal, financial, and health data at risk. </b></td></tr></tbody></table><p>In recent years, we’ve seen <a href="https://www.globalencryption.org/blog/">governments around the world</a> test ways to undermine encryption to access private conversations and data, often framing it as critical to combating crime. From proposals in the EU that could allow law enforcement to read messages before they are encrypted, to the UK Government’s pushback on Apple’s rollout of iCloud end-to-end encryption, or U.S. legislation that would require platforms to provide access to encrypted data, the pressure to weaken encryption is growing globally.</p><p>Governments and law enforcement agencies face complex and legitimate challenges in protecting the public from serious crime and emerging online threats. Their work is critical to ensuring safety in an increasingly digital world. But weakening encryption is not the solution. Strong encryption is what keeps everyone safe — it protects citizens, officials, and infrastructure alike. It is the foundation that safeguards people from intrusive surveillance and shields their most sensitive data from those who would exploit it for harm. We must work together to find solutions that both uphold public safety and prevent the erosion of the privacy and security that strong encryption provides.</p><p>With encryption increasingly under threat, this year’s Global Encryption Day (October 21) is the perfect moment to reflect on why strong encryption matters for every internet user.</p><p>At Mozilla, we believe encryption isn’t a luxury or privilege. It is a necessity for protecting data against unauthorized access. Our commitment to end-to-end encryption is strong because it is essential to protecting people and ensuring the internet remains open and secure.</p><p>That’s why Mozilla has taken action for years to protect and advance encryption. In 2023, we joined the <a href="https://www.globalencryption.org/2023/04/mozilla-and-internet-freedom-foundation-join-global-encryption-coalition-steering-committee/">Global Encryption Coalition</a> <a href="https://www.globalencryption.org/about/members/">Steering Committee</a>, working with partners around the world to promote encryption and push back on proposals for backdoor access.</p><p>In the U.S., we’ve advanced encryption in our <a href="https://blog.mozilla.org/netpolicy/files/2025/03/US_Vision-25-26-1.pdf">2025 U.S. policy priorities</a>, <a href="https://blog.mozilla.org/netpolicy/2025/02/24/mozilla-joins-amicus-brief-in-support-of-law-that-protects-your-private-messages/">joined amicus briefs</a>, and raised concerns with <a href="https://blog.mozilla.org/netpolicy/2020/03/05/mozilla-statement-on-earn-it-act/">bills like the U.S. EARN IT Act</a>. In the EU, we ran a multi-year <a href="https://securityriskahead.eu/">campaign</a> on the <a href="https://digital-strategy.ec.europa.eu/en/policies/eidas-regulation">eIDAS Regulation</a> working alongside civil society, academics, and industry experts to address concerns that Article 45 threatened to undermine the encryption and authentication technologies used on the web. With such a massive risk to web security, Mozilla, with allies, took action, releasing <a href="https://blog.mozilla.org/netpolicy/files/2021/11/eIDAS-Position-paper-Mozilla-.pdf">detailed position papers and</a> <a href="https://blog.mozilla.org/netpolicy/files/2023/11/eIDAS-Industry-Letter.pdf">joint statements</a>. All of our efforts have been to safeguard encryption, privacy, and digital rights. Why? Because the bottom line is simple: backdoor policies diminish the trust that allows the web to be a safe and reliable public resource.</p><p>Mozilla’s strong commitment to protecting privacy isn’t just a policy priority; it’s the foundation of our products and initiatives. Below, we’d like to share some of the ways in which Mozilla partnered with allies to make encryption a reality and a core function of the open internet ecosystem.</p><ul><li>Mozilla is among the co-founders of <a href="https://letsencrypt.org/">Let’s Encrypt</a>, a nonprofit Certificate Authority run by the Internet Security Research Group (ISRG), alongside partners like the EFF and the University of Michigan. This project made HTTPS certificates free and automatically renewable, transforming HTTPS from a costly, complex setup into a default expectation across the web. As a result, the share of encrypted traffic skyrocketed <a href="https://news.engin.umich.edu/2019/11/how-lets-encrypt-doubled-the-percentage-of-secure-websites-in-four-years/">from less than 40% in 2016 to around 80% by 2019</a>.</li><li>Mozilla closely collaborated with Cloudflare to roll-out <a href="https://blog.mozilla.org/en/firefox/encrypted-hello/">Encrypted Client Hello (ECH) in Firefox</a> in 2023, which encrypts the first “Hello” message of a user’s TLS connection so that even the website name is hidden from network observers.</li><li>Mozilla has most recently set a new standard for certificate revocation on the web, advancing encryption and security. In April 2025, <a class="c-link" href="https://hacks.mozilla.org/2025/08/crlite-fast-private-and-comprehensive-certificate-revocation-checking-in-firefox/" rel="noopener noreferrer" target="_blank">Firefox became the first (and is still the only) browser</a> that has <a class="c-link" href="https://blog.mozilla.org/en/firefox/crlite/" rel="noopener noreferrer" target="_blank">deployed CRLite</a>, the technology invented by a group of researchers that ensures revoked HTTPS certificates are identified quickly and privately without leaking unencrypted browsing activity to third parties.</li><li>In 2024, Firefox became the first browser to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1884140">support DTLS 1.3 </a>providing the most robust end-to-end encryption of real-time audio and video data, including all your web conferencing.</li></ul><p>It’s easy to say we care about encryption, but it only works if the commitment is shared by the policymakers writing our laws and the engineers designing our systems.</p><blockquote><p>As Neha Kochar, Director of Firefox Security and Privacy puts it: “Whether you’re visiting your bank’s website or sending a family photo, Firefox works behind the scenes to keep your browsing secure. With no shareholders to answer to, we serve only you — open-source and transparent by design, with verifiable guarantees that not even Mozilla knows which websites you visit or what you do online.”</p></blockquote><p>That is why Global Encryption Day is such an important moment. If a system is weakened or broken, it opens vulnerabilities that anyone with the right tools can exploit. By standing up for encryption and the policies that protect it, we help ensure the internet remains safe, open, and fair for everyone.</p><p>To dig deeper on encryption, check out these partner resources: <a href="https://www.globalencryption.org/blog/">Global Encryption Coalition</a>, <a href="https://www.internetsociety.org/action-plan/encryption/">Internet Society</a> and <a href="https://www.gp-digital.org/world-map-of-encryption/">Global Partners Digital</a>.</p><p><i>This blog is part of a larger series. Be sure to follow </i><a href="https://www.linkedin.com/authwall?trk=bf&amp;trkInfo=AQG0ar_qcB8EBgAAAZoGzJxA4eFE_J5_aXXVy4XpoJaAGTPKMJZb6_q_yZbXt5vGjo9d80W8v1AWGYVTeF0DYt10NEXEk3U-6LtLf3ygQUMMT818X4ZZca59KKtwzaMNYEIJEzk=&amp;original_referer=&amp;sessionRedirect=https%3A%2F%2Fwww.linkedin.com%2Fin%2Fjennifer-taylor-hodges%2F"><i>Jenn Taylor Hodges</i></a><i> and </i><a href="https://it.linkedin.com/in/sema-karaman-0a9b988a"><i>Sema Karaman</i></a><i> on LinkedIn for further insights into Mozilla’s policy priorities. </i></p><p>The post <a href="https://blog.mozilla.org/netpolicy/2025/10/21/behind-the-manifesto-standing-up-for-encryption-to-keep-the-internet-safe/">Behind the Manifesto: Standing up for encryption to keep the internet safe</a> appeared first on <a href="https://blog.mozilla.org/netpolicy">Open Policy &amp; Advocacy</a>.</p></description> <pubDate>Tue, 21 Oct 2025 16:37:43 +0000</pubDate> <dc:creator>Jenn Taylor Hodges and Sema Karaman</dc:creator></item><item> <title>Mozilla Thunderbird: Thunderbird Monthly Release 144 Recap</title> <guid isPermaLink="false">https://blog.thunderbird.net/?p=3902</guid> <link>https://blog.thunderbird.net/2025/10/thunderbird-monthly-release-144-recap/</link> <description><p><img alt="" class="attachment-640x360 size-640x360 wp-post-image" height="360" src="https://blog.thunderbird.net/files/2025/10/blog-banner-desktop-month-release-series1-768x432.jpg" width="640" /></p><p>We’re back with our Monthly Release recap! Thunderbird 144.0 readies the way for Exchange Web Services support, makes reordering your folders easier, and adds a new UI for TLS certificate handling. Additionally, we’ve fixed a dark mode toggle bug for High Contrast Mode users.</p> <p><strong>A quick reminder</strong> – these updates are for users on our <strong>monthly Thunderbird Release channel</strong>. For our users still on the ESR (Extended Standard Release) channel, these updates won’t land until next July 2026. For more information on the differences between the channels and how to make the switch:</p> <ul><li>Visit the Release download portal:<a href="https://updates.thunderbird.net/thunderbird/128.0/monthly/"> Thunderbird Release Page</a>.</li> <li><a href="https://support.mozilla.org/en-US/kb/thunderbird-release">Explore detailed comparisons</a> and migration guides.</li></ul> <p>Now let’s dive into <strong>what’s new in 144.0!</strong></p> <h3>New Features:</h3> <h4>Support for Exchange Web Service (EWS) Email in Account Hub</h4> <figure class="wp-block-image size-full"><a href="https://blog.thunderbird.net/files/2025/10/ExchangeAccountHub.png"><img alt="" class="wp-image-3958" height="891" src="https://blog.thunderbird.net/files/2025/10/ExchangeAccountHub.png" width="1191" /></a></figure> <p>As part of our preparation for EWS support officially landing next month in Thunderbird 145.0, you’ll notice EWS accounts as an option in the Account Hub. We will have more detailed blog posts and support articles available next month describing what is and isn’t supported. </p> <p>Benefits:</p> <ul><li>This gives us a chance to gradually ready the app and users for our newest protocol</li></ul> <h4>Improve UX of folder reordering</h4> <p><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1957486">Bug 1957486</a></p> <figure class="wp-block-image size-full"><a href="https://blog.thunderbird.net/files/2025/10/FolderReordering.png"><img alt="" class="wp-image-3952" height="278" src="https://blog.thunderbird.net/files/2025/10/FolderReordering.png" width="399" /></a></figure> <p>We recently introduced drag and drop folder reordering, and in 144, we’re making it better. A new widget shows where your folder is going. We also fixed an issue that prevented the visual from showing. We removed the jitters when positioning between folders, and Improved consistency by using the same indicator used to reorder tabs and attachments.</p> <p>Benefits:</p> <ul><li>More control over drag-and- performance with fewer folders going to the wrong location</li> <li>More visual consistency</li></ul> <h4>New UI for TLS Certificate Handling</h4> <p>While power users might be comfortable handling TLS certificates, average Thunderbird users might not know what to do when Thunderbird doesn’t trust a server’s certificate. This UI makes these issues, when they occur, harder to ignore and easier to diagnose and fix, even for less tech-savvy users. </p> <p>The new UI will mark the server red, with a clickable icon that takes users to an updated server settings. There, users can view certificates and add or remove certificate override exceptions.</p> <figure class="wp-block-image size-full"><a href="https://blog.thunderbird.net/files/2025/10/image-1.jpeg"><img alt="" class="wp-image-3928" height="253" src="https://blog.thunderbird.net/files/2025/10/image-1.jpeg" width="504" /></a></figure> <hr class="wp-block-separator has-alpha-channel-opacity" /> <figure class="wp-block-image size-full"><a href="https://blog.thunderbird.net/files/2025/10/Monthly-Release-Update-1442.png"><img alt="" class="wp-image-3964" height="280" src="https://blog.thunderbird.net/files/2025/10/Monthly-Release-Update-1442.png" width="1190" /></a></figure> <hr class="wp-block-separator has-alpha-channel-opacity" /> <figure class="wp-block-image size-full"><a href="https://blog.thunderbird.net/files/2025/10/Monthly-Release-Update-1441.png"><img alt="" class="wp-image-3970" height="280" src="https://blog.thunderbird.net/files/2025/10/Monthly-Release-Update-1441.png" width="1190" /></a></figure> <hr class="wp-block-separator has-alpha-channel-opacity" /> <figure class="wp-block-image size-full"><a href="https://blog.thunderbird.net/files/2025/10/Monthly-Release-Update-144.png"><img alt="" class="wp-image-3976" height="280" src="https://blog.thunderbird.net/files/2025/10/Monthly-Release-Update-144.png" width="1190" /></a></figure> <p>Benefits:</p> <ul><li>Increased security for the average Thunderbird user</li> <li>Easier access, via the server settings, to certificate actions</li></ul> <h3>Bug Fixes:</h3> <h4>Dark mode won’t go away for messages in High Contrast Mode</h4> <p><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1976900">Bug 1976900</a></p> <p>Our High Contrast Mode users noticed the new toggle for messages in dark mode wasn’t appearing. Starting in Thunderbird 144, dark message mode will not be activated when in High Contrast mode, respecting the colors and priority of that accessibility setting.</p> <p>Benefits:</p> <ul><li>Consistent use of system colors when in High Contrast Mode</li> <li>More respectful of user settings</li></ul> <p>You can find a complete list of updates and bug fixes that went into Thunderbird 144.0 in our <a href="https://www.thunderbird.net/en-US/thunderbird/144.0/releasenotes/">Release Notes</a>.</p> <p>Thank you for using Thunderbird and for supporting our mission to bring a truly independent, open‑source email experience. Your feedback and enthusiasm drive every improvement we make — and we can’t wait to share more with you in the next release.</p><p>The post <a href="https://blog.thunderbird.net/2025/10/thunderbird-monthly-release-144-recap/">Thunderbird Monthly Release 144 Recap</a> appeared first on <a href="https://blog.thunderbird.net">The Thunderbird Blog</a>.</p></description> <pubDate>Tue, 21 Oct 2025 14:16:13 +0000</pubDate> <dc:creator>Monica Ayhens-Madon</dc:creator></item><item> <title>The Servo Blog: Servo 0.0.1 Release</title> <guid isPermaLink="true">https://servo.org/blog/2025/10/20/servo-0.0.1-release/</guid> <link>https://servo.org/blog/2025/10/20/servo-0.0.1-release/</link> <description><p>Today, the Servo team has released new versions of the <code>servoshell</code> binaries for all our supported platforms, tagged <a href="https://github.com/servo/servo/releases/tag/v0.0.1">v0.0.1</a>. These binaries are essentially the same nightly builds that were already available from the <a href="https://servo.org/download">download page</a> with additional manual testing, now tagging them explicitly as releases for future reference.</p><p>We plan to publish such a tagged release every month. For now, we are adopting a simple release process where we will use a recent nightly build and perform additional manual testing to identify issues and regressions before tagging and publishing the binaries.</p><p>There are currently no plans to publish these releases on <a href="https://crates.io/">crates.io</a> or platform-specific app stores. The goal is just to publish <a href="https://github.com/servo/servo/releases">tagged releases on GitHub</a>.</p></description> <pubDate>Mon, 20 Oct 2025 00:00:00 +0000</pubDate></item><item> <title>Mozilla Thunderbird: Thunderbird Monthly Development Digest: September 2025</title> <guid isPermaLink="false">https://blog.thunderbird.net/?p=3894</guid> <link>https://blog.thunderbird.net/2025/10/thunderbird-monthly-development-digest-september-2025/</link> <description><p><img alt="" class="attachment-640x360 size-640x360 wp-post-image" height="360" src="https://blog.thunderbird.net/files/2025/10/blog-banner-developer2-768x432.jpg" width="640" /></p><p>Hello again from the Thunderbird development team! This month’s sprints have been about focus and follow-through, as we’ve tightened up our new Account Hub experience and continued the deep work on Exchange Web Services (EWS) support. While those two areas have taken centre stage, we’ve also been busy adapting to a wave of upstream platform changes that demanded careful attention to keep everything stable and our continuous integration systems happy. Alongside this, our developers have been lending extra support to the Services team to ensure a smooth path for upcoming releases. It’s been a month of steady, detail-oriented progress – the kind that doesn’t always make headlines, but lays the groundwork for the next leaps forward.</p> <h4><strong>Exchange Web Services support announcement for 145</strong></h4> <p>While support for Microsoft Exchange via EWS landed in Thunderbird 144, the new “Account Hub” setup interface had a few outstanding priorities which required our attention. Considering that the announcement of EWS support will likely generate a large spike in secondary account additions, we felt it important enough to delay the announcement in order to polish the setup interface and make the experience better for the users taking advantage of the new features. The team working on the “back end” took the opportunity to deliver more features that had been in our backlog and address some bugs that were reported by users who are already using EWS on Beta and Daily:</p> <ul><li>Offline message policy</li> <li>Soft delete / copy to Trash</li> <li>Empty Trash</li> <li>Notifications with message preview</li> <li>Reply-to multiple recipients bug</li> <li>Mark Folder as read</li> <li>Experimental tenant-specific configuration options (behind a preference) now being tested with early adopters</li></ul> <p>Looking ahead, the team is already focused on our work week where we’ll have chance to put plans in place to tackle some architectural refactoring and the next major milestones in our EWS implementation for Calendar and Address Book.</p> <p>We were also delighted to work with a community contributor who has been hard at work on adding <a href="https://github.com/thunderbird/ews-rs/pull/64"><u>support for the FindItem operation</u></a>. We know some of our workflows are tricky so we very much appreciate the support and patience required!</p> <p><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1847846"><u>Keep track of feature delivery here.</u></a> </p> <h4><strong>Account Hub</strong></h4> <p>We’ve now added the ability to manually edit any configuration from the first screen. This effectively bypasses the simpler detection methods which don’t work for every configuration. Upon detection failure, a user is now able to switch between protocols and choose EWS configuration.</p> <p>Other notable items being rolled into 145 are:</p> <ul><li>Redirect warning and handling to prevent a hang for platforms using autodiscover on a 3rd party server</li> <li>Authentication step added for Exchange discovery requiring credentials</li> <li>Ability to cancel the account configuration detection process</li> <li>Improvements to the experience for users with screen reading technology</li></ul> <p>The creation of address books through the Account Hub is now the experience by default on 145 which is coming to Beta release users this week and monthly Release users before I write next.</p> <p>Follow progress in the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1981786"><u>Meta Bug</u></a></p> <h4><strong>Calendar UI Rebuild</strong></h4> <p>With the front end team mainly focused on Account Hub, the Calendar UI project has moved slowly this past month. We’ve concentrated the continued work in the following areas:</p> <ul><li>Acceptance widget</li> <li>Title and close button</li> <li>Dialog repositioning on resize</li> <li>Migrating calendar strings from legacy .dtd files into modern .ftl files and preserving translations to avoid repeat work for our translation community.</li></ul> <h4><strong>Maintenance, Upstream adaptations, Recent Features and Fixes</strong></h4> <p>With our focused maintenance sprint over, the team kept the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1492751"><u>Fluent Migration</u></a> and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979960"><u>moz-src migration</u></a> projects moving in the background. They also handled another surge of upstream changes requiring triage. In addition to these items, the development community has helped us deliver a variety of improvements over the past month:</p> <ul><li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1831713"><u>Unified toolbar fix to toggle Spam/Not Spam</u></a></li> <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=382977"><u>An 18 year-old bug to enable full path display</u></a></li> <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1851875"><u>Fix a regression to allow remote content in .eml file</u></a></li> <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1988718"><u>Support for DNS over HTTPS</u></a></li> <li>and many more which we list in <a href="https://www.thunderbird.net/en-US/thunderbird/145.0beta/releasenotes/"><u>release notes for beta</u></a>.</li></ul> <p>If you would like to see new features as they land, and help us find some early bugs, you can try running <a href="https://archive.mozilla.org/pub/thunderbird/nightly/latest-comm-central/"><u>daily</u></a> and check the pushlog to see what has recently landed. This assistance is immensely helpful for catching problems early.</p> <h3>—</h3> <p><strong>Toby Pilling</strong></p> <p>Senior Manager, Desktop Engineering</p><p>The post <a href="https://blog.thunderbird.net/2025/10/thunderbird-monthly-development-digest-september-2025/">Thunderbird Monthly Development Digest: September 2025</a> appeared first on <a href="https://blog.thunderbird.net">The Thunderbird Blog</a>.</p></description> <pubDate>Fri, 17 Oct 2025 16:35:31 +0000</pubDate> <dc:creator>Toby Pilling</dc:creator></item><item> <title>Firefox Add-on Reviews: Reddit revolutionized — use a browser extension to enhance your favorite forum</title> <guid isPermaLink="true">https://addons.mozilla.org/blog/reddit-revolutionized-use-a-browser-extension-to-enhance-your-favorite-forum/</guid> <link>https://addons.mozilla.org/blog/reddit-revolutionized-use-a-browser-extension-to-enhance-your-favorite-forum/</link> <description><p>Reddit is awash with great conversation (well, <a href="https://www.reddit.com/r/notinteresting/" rel="noreferrer noopener">not all the time)</a>. There’s a Reddit forum for just about everybody —<a href="https://www.reddit.com/subreddits/leaderboard/sports/" rel="noreferrer noopener"> sports fans</a>, <a href="https://www.reddit.com/subreddits/leaderboard/gaming/" rel="noreferrer noopener">gamers</a>, <a href="https://www.reddit.com/r/FoodHaikus/" rel="noreferrer noopener">poets inspired by food</a>, <a href="https://www.reddit.com/r/birdswitharms/" rel="noreferrer noopener">people who like arms on birds</a> — you get the idea. </p> <p>If you spend time on Reddit, there are ways to augment your experience with a browser extension… </p> <h3 class="wp-block-heading">Reddit Enhancement Suite</h3> <p>Used by millions of Redditors across various browsers, <a href="https://addons.mozilla.org/firefox/addon/reddit-enhancement-suite/" rel="noreferrer noopener">Reddit Enhancement Suite</a> is optimized to work with the beloved “old Reddit”. </p> <div class="addon-card"></div> <p>Key features: </p> <ul class="wp-block-list"><li><strong>Subreddit manager</strong>. Customize the top nav bar with your own subreddit shortcuts. </li> <li><strong>Account switcher</strong>. Easily manage multiple Reddit accounts with a couple quick clicks. </li> <li><strong>Show “parent” comment on hover</strong>. When you mouse over a comment, its “parent” comment displays. </li> <li><strong>Dashboard</strong>. Fully customizable dashboard showcases content from subreddits, your message inbox &amp; more. </li> <li><strong>Tag</strong> specific users and subreddits so their activity appears more prominently</li> <li><strong>Custom filters</strong>. Select words, subreddits, or even certain users you want filtered out of your scrolling experience. </li> <li><strong>New comment count</strong>. See the number of new comments on a thread since your last visit. </li> <li><strong>Neverending Reddit</strong>. Just keep scrolling. Never stop!</li></ul> <h3 class="wp-block-heading">Old Reddit Redirect</h3> <p>Speaking of the former design, <a href="https://addons.mozilla.org/firefox/addon/old-reddit-redirect/" rel="noreferrer noopener">Old Reddit Redirect</a> provides a straightforward function. It simply ensures that every Reddit page you visit will redirect to the <em>old.reddit.com</em> domain. </p> <div class="addon-card"></div> <p>Sure, if you have a Reddit account the site gives you the option of using the old design, but with the browser extension you’ll get the old site regardless of being logged in or not. It’s also great for when you click Reddit links shared from the new domain. </p> <h3 class="wp-block-heading">Sink It for Reddit</h3> <p>Designed to “make Reddit’s web version actually usable,” <a href="https://addons.mozilla.org/firefox/addon/sink-it-for-reddit/">Sink It for Reddit</a> is built for people craving a minimalist discussion platform. </p> <div class="addon-card"></div> <p>Color coded comments are much simpler to navigate, especially with Sink It’s brilliant Adaptive Dark Mode feature. Give this privacy respecting extension a try if you desire a laser focused Reddit experience. </p> <h3 class="wp-block-heading"><strong>Reddit Comment Collapser</strong></h3> <p>No more getting lost in confusing comment threads for users of <strong>old.reddt.com</strong>. <a href="https://addons.mozilla.org/en-US/firefox/addon/reddit_comment_collapser/" rel="noreferrer noopener">Reddit Comment Collapser</a> cleans up your commentary view with a simple mouse click.</p> <div class="addon-card"></div> <p>Compatible with <a href="https://addons.mozilla.org/en-US/firefox/addon/reddit-enhancement-suite/" rel="noreferrer noopener">Reddit Enhancement Suite</a> and <a href="https://addons.mozilla.org/en-US/firefox/addon/old-reddit-redirect/" rel="noreferrer noopener">Old Reddit Redirect</a>, this single-use extension is beloved by many seeking a minimalist view of the classic Reddit.</p> <h3 class="wp-block-heading">Reddit on YouTube</h3> <p>Bring Reddit with you to YouTube. Whenever you’re on a YouTube page, <a href="https://addons.mozilla.org/firefox/addon/reddit-on-youtube/" rel="noreferrer noopener">Reddit on YouTube</a> searches for Reddit posts that link to the video and embeds those comments into the YouTube comment area. </p> <div class="addon-card"></div> <p>You can easily toggle between Reddit and YouTube comments and select either one to be your default preference. </p> <figure class="wp-block-image size-large"><img alt="" class="wp-image-178" height="716" src="https://mozamo.wpengine.com/wp-content/uploads/2021/07/blog_reddit_comment-1-1024x716.png" width="1024" />&lt;figcaption class="wp-element-caption"&gt;If there are multiple Reddit threads about the video you’re watching, the extension will display them in tab form in the YouTube comment section. &lt;/figcaption&gt;</figure> <h3 class="wp-block-heading">Reddit Ad Remover</h3> <p>Sick of seeing so many “Promoted” posts and paid advertisements in the feed and sidebar? <a href="https://addons.mozilla.org/firefox/addon/reddit-ad-remover/" rel="noreferrer noopener">Reddit Ad Remover</a> silences the noise. </p> <div class="addon-card"></div> <p>The extension even blocks auto-play video ads, which is great for people who don’t appreciate sudden bursts of commercial sound. Hey, somebody should <a href="https://www.reddit.com/r/badads/" rel="noreferrer noopener">create a subreddit about this</a>! </p> <p>Happy redditing, folks. Feel free to explore more <a href="https://addons.mozilla.org/firefox/extensions/category/feeds-news-blogging/" rel="noreferrer noopener">news and media extensions</a> on <em>addons.mozilla.org</em>.</p></description> <pubDate>Thu, 16 Oct 2025 21:29:46 +0000</pubDate> <dc:creator>Scott DeVaney</dc:creator></item><item> <title>Firefox Add-on Reviews: Boost your writing skills with a browser extension</title> <guid isPermaLink="true">https://addons.mozilla.org/blog/boost-your-writing-skills-with-a-browser-extension/</guid> <link>https://addons.mozilla.org/blog/boost-your-writing-skills-with-a-browser-extension/</link> <description><p>Whatever kind of writing you do — technical documentation, corporate communications, Harry Potter-vampire crossover fan fiction — it probably happens online. Here are some fabulous browser extensions that will benefit anyone who writes on the web. Get grammar help, productivity tools, and other strong writing aids… </p> <h3 class="wp-block-heading">LanguageTool</h3> <p>It’s like having your own copy editor with you wherever you write on the web. <a href="https://addons.mozilla.org/firefox/addon/languagetool/" rel="noreferrer noopener">Language Tool – Grammar and Spell Checker</a> will make you a better writer in 25+ languages. </p> <div class="addon-card"></div> <p>More than just a spell checker, LanguageTool also…</p> <ul class="wp-block-list"><li>Recognizes common misuses of similar sounding words (e.g. <em>there/their</em> or <em>your/you’re</em>)</li> <li>Works on social media sites and email</li> <li>Offers alternate phrasing and style suggestions for brevity and clarity</li></ul> <h3 class="wp-block-heading">Dictionary Anywhere</h3> <p>Need a quick word definition? With <a href="https://addons.mozilla.org/firefox/addon/dictionary-anyvhere/" rel="noreferrer noopener">Dictionary Anywhere</a> just double-click any word you find on the web and get an instant pop-up definition. </p> <div class="addon-card"></div> <p>You can even save and download words and their definitions for later offline reference. </p> <figure class="wp-block-image size-large"><img alt="" class="wp-image-232" height="724" src="https://mozamo.wpengine.com/wp-content/uploads/2021/08/blog_write_DictAnywhere-1024x724.jpg" width="1024" />&lt;figcaption class="wp-element-caption"&gt;Dictionary Anywhere — no more navigating away from a page just to get a word check.&lt;/figcaption&gt;</figure> <h3 class="wp-block-heading">Yomitan</h3> <p>Think of <a href="https://addons.mozilla.org/firefox/addon/yomitan/">Yomitan</a> as a dictionary extension that doubles as a language learning tool. Decipher and define text in 20+ languages. </p> <div class="addon-card"></div> <p>As you navigate foreign language websites, Yomitan is right there with you to not only help define unfamiliar words and phrases, but also provide audio pronunciation guidance, flashcard creation for future study, offline support and more — all within a privacy protective framework. </p> <h3 class="wp-block-heading">Power Thesaurus</h3> <p>Every writer occasionally struggle to find the perfect word. Bring <a href="https://addons.mozilla.org/firefox/addon/power-thesaurus/">Power Thesaurus</a> with you wherever you write on the web to gain instant access to alternative phrasing. </p> <div class="addon-card"></div> <p>Simply highlight any word and pop up a handy thesaurus (also includes word definitions and antonyms). Power Thesaurus is a priceless tool for writers who labor over every word. </p> <h3 class="wp-block-heading">Dark Background and Light Text</h3> <p>Give your eyes a break. <a href="https://addons.mozilla.org/firefox/addon/dark-background-light-text/" rel="noreferrer noopener">Dark Background and Light Text</a> makes staring at blinking words all day a whole lot easier on your lookers. </p> <div class="addon-card"></div> <p>Really simple to use out of the box. Once installed, the extension’s default settings automatically flip the colors of every web page you visit. But if you’d like more granular control of color settings, just click the extension’s toolbar button to access a pop-up menu that lets you customize color schemes, set page exceptions for sites you don’t want colors inverted, and more simple controls. </p> <figure class="wp-block-image size-large"><img alt="" class="wp-image-233" height="551" src="https://mozamo.wpengine.com/wp-content/uploads/2021/08/blog_write_dblt-1024x551.jpg" width="1024" />&lt;figcaption class="wp-element-caption"&gt;Dark Background and Light Text goes easy on the eyes.&lt;/figcaption&gt;</figure> <h3 class="wp-block-heading">Clippings</h3> <p>If your online writing requires the repeated use of certain phrases (for example, work email templates or customer support responses), <a href="https://addons.mozilla.org/firefox/addon/clippings/" rel="noreferrer noopener">Clippings</a> can be a huge time saver. </p> <div class="addon-card"></div> <p>Key features…</p> <ul class="wp-block-list"><li>Create a practically limitless library of saved phrases</li> <li>Paste your clippings anywhere via context menu</li> <li>Organize batches of clippings with folders and color coded labels</li> <li>Shortcut keys for power users</li> <li>Extension supported in English, Dutch, French, German, and Portuguese (Brazil)</li></ul> <figure class="wp-block-image size-large"><img alt="" class="wp-image-234" height="789" src="https://mozamo.wpengine.com/wp-content/uploads/2021/08/blog_write_clippings-1024x789.jpg" width="1024" />&lt;figcaption class="wp-element-caption"&gt;Clippings handles bulk cutting/pasting. &lt;/figcaption&gt;</figure> <p>We hope these extensions take your prose to the next level. Some writers may also be interested in this collection of <a href="https://addons.mozilla.org/blog/supercharge-your-productivity-with-a-browser-extension/" rel="noreferrer noopener">great productivity extensions</a> to help organize your writing projects. Feel free to explore thousands of other useful extensions on <em>addons.mozilla.org</em>. </p></description> <pubDate>Thu, 16 Oct 2025 19:54:02 +0000</pubDate> <dc:creator>Scott DeVaney</dc:creator></item><item> <title>Firefox Add-on Reviews: Extension starter pack</title> <guid isPermaLink="true">https://addons.mozilla.org/blog/extension-starter-pack/</guid> <link>https://addons.mozilla.org/blog/extension-starter-pack/</link> <description><p>You’ve probably heard about “ad blockers,” “tab managers,” “anti-trackers” or any number of browser customization tools commonly known as <em>extensions.</em> And maybe you’re intrigued to try one, but you’ve never installed an extension before and the whole notion just seems a bit vague. </p> <p>Let’s demystify extensions. </p> <p>An extension is simply an app that runs on a browser like Firefox. From serious productivity and privacy enhancing features to fun stuff like changing the way the web looks and feels, extensions give you the power to completely personalize your browsing experience. </p> <p><a href="https://addons.mozilla.org/firefox/" rel="noreferrer noopener"><em>Addons.mozilla.org</em></a> (AMO) is a discovery site that hosts thousands of independently developed Firefox extensions. It’s a vast and eclectic ecosystem of features, so we’ve hand-picked a small collection of great extensions to get you started…</p> <h3><em>I’ve always wanted an ad blocker!</em></h3> <h4>uBlock Origin</h4> <p>Works beautifully “right out of the box.” Just add it to Firefox and <a href="https://addons.mozilla.org/firefox/addon/ublock-origin/" rel="noreferrer noopener">uBlock Origin</a> will automatically start blocking all types of advertising — display ads, banners, video pre-rolls, pop-ups — you name it. </p> <div class="addon-card"></div> <p>Of course, if you prefer deeper content blocking customization, uBlock Origin allows for fine control as well, like the ability to import your own custom block filters or access a data display that shows how much of a web page was blocked by the extension. More than just an ad blocker, uBlock Origin also effectively thwarts some websites that may be infected with malware. </p> <p>For more insights about this excellent ad blocker, please see <a href="https://addons.mozilla.org/blog/ublock-origin-everything-you-need-to-know-about-the-ad-blocker/" rel="noreferrer noopener">uBlock Origin — everything you need to know about the ad blocker</a>, or to explore even more ad blocker options, check out <a href="https://addons.mozilla.org/blog/whats-the-best-ad-blocker-for-you/" rel="noreferrer noopener">What’s the best ad blocker for you?</a></p> <h3><em>I’m concerned about my privacy and tracking around the web</em></h3> <h4>Privacy Badger</h4> <p>The flagship anti-tracking extension from privacy proponents at the <a href="https://www.eff.org/">Electronic Frontier Foundation</a>, <a href="https://addons.mozilla.org/firefox/addon/privacy-badger17/" rel="noreferrer noopener">Privacy Badger</a> is programmed to look for tracking heuristics (i.e. specific actions that indicate someone is trying to track you). </p> <div class="addon-card"></div> <p>Zero set up required. Just install Privacy Badger and it will automatically search for third-party cookies, HTML5 local storage “supercookies,” canvas fingerprinting, and other sneaky tracking methods. </p> <h4>Consent-O-Matic</h4> <p>Not only will <a href="https://addons.mozilla.org/firefox/addon/consent-o-matic/">Consent-O-Matic</a> automatically handle pop-up data consent forms (per <a href="https://gdpr-info.eu/">GDPR</a> regulations), but it’s brilliantly designed to interpret the often intentionally confusing language of consent pop-ups trying to trick you into agreeing to invasive tracking. </p> <div class="addon-card"></div> <p>Developed by internet privacy researchers at Aarhus University in Denmark who grew sick of seeing so many deceptive consent pop-ups, Consent-O-Matic’s decision-making logic is built upon studying hundreds of pop-ups and identifying duplicitous patterns. So using this extension not only gives you a great ally in the fight against intrusive tracking, but you’re spared the annoyance of constantly clicking consent forms all over the internet. </p> <h3><em>I need an easier way to translate languages</em></h3> <h4>Simple Translate</h4> <p>Do you do a lot of language translations on the web? If so, it’s a hassle always copying text and navigating away from the page you’re on just to translate a word or phrase. <a href="https://addons.mozilla.org/firefox/addon/simple-translate/" rel="noreferrer noopener">Simple Translate</a> solves this problem by giving you the power to perform translations right there on the page. </p> <div class="addon-card"></div> <p>Just highlight the text you want translated and right-click to get instant translations in a handy pop-up display, so you never have to leave the page again. </p> <h3><em>My grammar in speling is bad!</em></h3> <h4><strong>LanguageTool</strong></h4> <p>Anywhere you write on the web, <a href="https://addons.mozilla.org/firefox/addon/languagetool/" rel="noreferrer noopener">LanguageTool</a> will be there to lend a guiding editorial hand. It helps fix typos, grammar problems, and even recognizes common word mix-ups like the there/their/they’re. </p> <div class="addon-card"></div> <p>Available in 25 languages, LanguageTool automatically works on any web-based publishing platform like Gmail, web docs, social media sites, etc. The clever extension will even spot words you’re possibly overusing and suggest alternatives to spruce up your prose. </p> <h3><em>YouTube your way</em></h3> <h4>Improve YouTube!</h4> <p>Boasting 175+ customization features, <a href="https://addons.mozilla.org/firefox/addon/youtube-addon/">Improve YouTube!</a> is simple to grasp while providing a huge variety of ways to radically alter YouTube functionality. </p> <div class="addon-card"></div> <p>Key features include… </p> <ul class="wp-block-list"><li>Customize YouTube’s layout with different color schemes</li> <li>Create shortcuts for common actions like skipping to next video, scrolling back/forward 10 seconds, volume control &amp; more</li> <li>Filter out unwanted elements like Related Videos, Shorts, Comments, etc. </li> <li>Ad blocking (with ability to allow ads from channels you choose to support)</li> <li>Simple screenshot and save features</li> <li>Playlist shuffle</li> <li>Frame by frame scrolling</li> <li>High-def default video quality</li></ul> <h3><em>I’m drowning in browser tabs! Send help! </em></h3> <h4>OneTab</h4> <p>You’ve got an overwhelming number of open tabs. You can’t close them. You need them. But you can’t organize them all right now either. You’re too busy. What to do?! </p> <p>If you have <a href="https://addons.mozilla.org/firefox/addon/onetab/" rel="noreferrer noopener">OneTab</a> on Firefox you just click the toolbar button and suddenly all those open tabs become a clean list of text links listed on a single page. Ahhh serenity.</p> <div class="addon-card"></div> <p>Not only will you create browser breathing room for yourself, but with all those previously open tabs now closed and converted to text links, you’ve also freed up a bunch of CPU and memory, which should improve browser speed and performance. </p> <p>If you’ve never installed a browser extension before, we hope you found something here that piques your interest to try. To continue exploring ways to personalize Firefox through the power of extensions, please see our collection of 100+ <a href="https://addons.mozilla.org/firefox/search/?promoted=recommended&amp;sort=random&amp;type=extension" rel="noreferrer noopener">Recommended Extensions</a>. </p></description> <pubDate>Thu, 16 Oct 2025 19:22:03 +0000</pubDate> <dc:creator>Scott DeVaney</dc:creator></item><item> <title>The Mozilla Blog: Windows 10 updates are ending. Here’s what it means for Firefox users.</title> <guid isPermaLink="false">https://blog.mozilla.org/?p=82297</guid> <link>https://blog.mozilla.org/en/firefox/windows-10-updates-support/</link> <description><figure class="wp-block-image size-large"><img alt="Firefox logo with orange fox wrapped around purple globe." class="wp-image-82299" height="576" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/Press_Firefox_Brand_1920x1080_2-1024x576.png" width="1024" /></figure> <p>This week Microsoft released the final free monthly update to Windows 10. While this marks the end of support from Microsoft, <strong>Firefox will continue to support Windows 10 for the foreseeable future</strong>. </p> <p>If you remain on Windows 10, you will <a href="https://support.mozilla.org/en-US/kb/firefox-support-windows-10-end-support" rel="noreferrer noopener" target="_blank">continue to get the same updates</a> to Firefox you do today, with all of our latest feature improvements and bug fixes. This includes our commitment to resolve security vulnerabilities as rapidly as we can, <a href="https://blog.mozilla.org/security/2024/04/04/rapidly-leveling-up-firefox-security/">sometimes in less than 24 hours</a>, with special security updates. Windows 10 remains a primary platform for Firefox users. Unlike older versions of Windows like Windows 7 and 8, where Mozilla is only offering security updates to Firefox, Windows 10 will get the latest and greatest features and bug fixes just like users on Windows 11. </p> <h3><strong>Should you upgrade to Windows 11?</strong></h3> <p>While Mozilla will continue to deliver the latest updates to Firefox on Windows 10, security online also requires continued updates from Microsoft to Windows 10 itself, and to the many other software and devices that you use on your Windows 10 computer. That’s why <strong>we recommend upgrading to Windows 11 if your computer supports it</strong>. You can find out if your PC can run Windows 11 and upgrade to it for free from your Windows update settings. With this option, when you start up Windows 11 for the first time you’ll find that Firefox is still installed, and all of your data and settings are just like you left them. </p> <p>If your computer <em>cannot</em> run Windows 11, or you wish to remain on Windows 10 for other reasons, your next best option is to <strong>make sure you’re getting “extended security updates”</strong> from Microsoft. While these updates won’t deliver new Windows features or non-security bug fixes, they will fix security vulnerabilities that are found in Windows 10 in the future. You should see an option to “enroll” in these updates in your Windows update settings, and if you choose the “Windows Backup” option you’ll get the updates for free. Microsoft has more information on <a href="https://www.microsoft.com/windows/extended-security-updates">Windows 10 extended security updates</a> if you have other questions. </p> <h3><strong>Preparing for a device upgrade or new PC</strong></h3> <p>If you get a new Windows 11 PC you might be surprised to see that even if you used Windows Backup, non-Microsoft apps like Firefox haven’t migrated with you. You will typically get a link in your start menu or on your desktop to re-install Firefox, and after it’s installed you’ll find that everything is “fresh” — without your bookmarks, saved passwords, browsing history, or any of your other data and settings. </p> <p>This can be frustrating, but we do have a solution for you if you prepare in advance and <strong>back up your data using </strong><a href="https://support.mozilla.org/en-US/kb/how-do-i-set-sync-my-computer"><strong>Firefox sync</strong></a><strong> through a </strong><a href="https://www.mozilla.org/account/"><strong>Mozilla account</strong></a><strong>.</strong> To get started with sync, just choose “sign in” from the Firefox toolbar or menu, and we’ll walk you through the quick process of creating a Mozilla account and enabling sync. </p> <h3><strong>Firefox sync helps transfer your data securely</strong></h3> <p>Sync isn’t just for people who have Firefox running on more than one computer. It’s also a safe way to back up your data and protect yourself against a lost laptop, a computer that breaks down or is damaged, or your own excited forgetfulness if you get rid of your old PC the moment you get a new one. And what many Firefox users may not realize is that Firefox sync is “end-to-end encrypted,” which is a fancy way of saying that not even Mozilla can read your data. Without your password, which we don’t know, your data is an indecipherable scramble even to us. But it’s safe on our servers nonetheless, which means that if you find yourself with a new PC and a “fresh” Firefox, all you need to do is log in and all your bookmarks, passwords, history and more will quickly load in. </p> <p>Meanwhile, you can also rest assured that if you continue to use Firefox on Windows 10 over the next few years, we’ll let you know through messages in Firefox if there is new information about staying secure and whether our stance regarding our support for Windows 10 needs to change. <br /><br />Thanks for using Firefox, and know that you can always reach us at <a href="https://connect.mozilla.org/">Mozilla Connect</a>. We’re eager for your feedback and questions.</p> <a class="ft-c-inline-cta" href="https://www.mozilla.org/firefox/new/?utm_source=blog.mozilla.org&amp;utm_medium=referral&amp;utm_campaign=blog-nav"> <div class="ft-c-inline-cta__media"> <img alt="" class="attachment-1x1 size-1x1" height="800" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2021/10/Visual-Guidelines-800x800.png" width="800" /> </div> <div class="ft-c-inline-cta__content"> <h4>Take control of your internet</h4> <span>Download Firefox</span> </div></a><p>The post <a href="https://blog.mozilla.org/en/firefox/windows-10-updates-support/">Windows 10 updates are ending. Here’s what it means for Firefox users.</a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p></description> <pubDate>Thu, 16 Oct 2025 17:14:25 +0000</pubDate> <dc:creator>David Rubino</dc:creator></item><item> <title>The Rust Programming Language Blog: docs.rs: changed default targets</title> <guid isPermaLink="true">https://blog.rust-lang.org/2025/10/16/docsrs-changed-default-targets/</guid> <link>https://blog.rust-lang.org/2025/10/16/docsrs-changed-default-targets/</link> <description><h3><a class="anchor" href="https://blog.rust-lang.org/2025/10/16/docsrs-changed-default-targets/#changes-to-default-build-targets-on-docs-rs"></a>Changes to default build targets on docs.rs</h3><p>This post announces two changes to the list of default targets used to builddocumentation on docs.rs.</p><p>Crate authors can specify a custom list of targets using<a href="https://docs.rs/about/metadata">docs.rs metadata in <code>Cargo.toml</code></a>. If thismetadata is not provided, docs.rs falls back to a default list. We are updatingthis list to better reflect the current state of the Rust ecosystem.</p><h4><a class="anchor" href="https://blog.rust-lang.org/2025/10/16/docsrs-changed-default-targets/#apple-silicon-arm64-replaces-x86-64"></a>Apple silicon (ARM64) replaces x86_64</h4><p>Reflecting Apple's transition from x86_64 to its own ARM64 silicon, the Rustproject has updated its platform support tiers. The <code>aarch64-apple-darwin</code>target is now Tier 1, while <code>x86_64-apple-darwin</code> has moved to Tier 2. You canread more about this in <a href="https://github.com/rust-lang/rfcs/pull/3671">RFC 3671</a>and <a href="https://github.com/rust-lang/rfcs/pull/3841">RFC 3841</a>.</p><p>To align with this, docs.rs will now use <code>aarch64-apple-darwin</code> as the defaulttarget for Apple platforms instead of <code>x86_64-apple-darwin</code>.</p><h4><a class="anchor" href="https://blog.rust-lang.org/2025/10/16/docsrs-changed-default-targets/#linux-arm64-replaces-32-bit-x86"></a>Linux ARM64 replaces 32-bit x86</h4><p>Support for 32-bit <code>i686</code> architectures is declining, and major Linuxdistributions have begun to phase it out.</p><p>Consequently, we are replacing the <code>i686-unknown-linux-gnu</code> target with<code>aarch64-unknown-linux-gnu</code> in our default set.</p><h4><a class="anchor" href="https://blog.rust-lang.org/2025/10/16/docsrs-changed-default-targets/#new-default-target-list"></a>New default target list</h4><p>The updated list of default targets is:</p><ul><li><code>x86_64-unknown-linux-gnu</code></li><li><code>aarch64-apple-darwin</code> (replaces <code>x86_64-apple-darwin</code>)</li><li><code>x86_64-pc-windows-msvc</code></li><li><code>aarch64-unknown-linux-gnu</code> (replaces <code>i686-unknown-linux-gnu</code>)</li><li><code>i686-pc-windows-msvc</code></li></ul><h4><a class="anchor" href="https://blog.rust-lang.org/2025/10/16/docsrs-changed-default-targets/#opting-out"></a>Opting out</h4><p>If your crate requires the previous default target list, you can explicitlydefine it in your <code>Cargo.toml</code>:</p><pre class="language-toml z-code"><code class="language-toml"><span class="z-source z-toml"><span class="z-punctuation z-definition z-table z-begin z-toml">[</span><span class="z-meta z-tag z-table z-toml"><span class="z-entity z-name z-table z-toml">package</span><span class="z-punctuation z-separator z-table z-toml">.</span><span class="z-entity z-name z-table z-toml">metadata</span><span class="z-punctuation z-separator z-table z-toml">.</span><span class="z-entity z-name z-table z-toml">docs</span><span class="z-punctuation z-separator z-table z-toml">.</span><span class="z-entity z-name z-table z-toml">rs</span></span><span class="z-punctuation z-definition z-table z-end z-toml">]</span></span><span class="z-source z-toml"><span class="z-meta z-tag z-key z-toml"><span class="z-entity z-name z-tag z-toml">targets</span></span> <span class="z-punctuation z-definition z-key-value z-toml">=</span> <span class="z-punctuation z-definition z-array z-begin z-toml">[</span></span><span class="z-source z-toml"> <span class="z-string z-quoted z-double z-basic z-toml"><span class="z-punctuation z-definition z-string z-begin z-toml">"</span>x86_64-unknown-linux-gnu<span class="z-punctuation z-definition z-string z-end z-toml">"</span></span><span class="z-punctuation z-separator z-array z-toml">,</span></span><span class="z-source z-toml"> <span class="z-string z-quoted z-double z-basic z-toml"><span class="z-punctuation z-definition z-string z-begin z-toml">"</span>x86_64-apple-darwin<span class="z-punctuation z-definition z-string z-end z-toml">"</span></span><span class="z-punctuation z-separator z-array z-toml">,</span></span><span class="z-source z-toml"> <span class="z-string z-quoted z-double z-basic z-toml"><span class="z-punctuation z-definition z-string z-begin z-toml">"</span>x86_64-pc-windows-msvc<span class="z-punctuation z-definition z-string z-end z-toml">"</span></span><span class="z-punctuation z-separator z-array z-toml">,</span></span><span class="z-source z-toml"> <span class="z-string z-quoted z-double z-basic z-toml"><span class="z-punctuation z-definition z-string z-begin z-toml">"</span>i686-unknown-linux-gnu<span class="z-punctuation z-definition z-string z-end z-toml">"</span></span><span class="z-punctuation z-separator z-array z-toml">,</span></span><span class="z-source z-toml"> <span class="z-string z-quoted z-double z-basic z-toml"><span class="z-punctuation z-definition z-string z-begin z-toml">"</span>i686-pc-windows-msvc<span class="z-punctuation z-definition z-string z-end z-toml">"</span></span></span><span class="z-source z-toml"><span class="z-punctuation z-definition z-array z-end z-toml">]</span></span></code></pre><p>Note that docs.rs continues to support any target available in the Rusttoolchain; only the <em>default</em> list has changed.</p></description> <pubDate>Thu, 16 Oct 2025 00:00:00 +0000</pubDate> <dc:creator>Denis Cornehl</dc:creator></item><item> <title>Firefox Add-on Reviews: Translate the web easily with a browser extension</title> <guid isPermaLink="true">https://addons.mozilla.org/blog/translate-the-web-easily-with-a-browser-extension/</guid> <link>https://addons.mozilla.org/blog/translate-the-web-easily-with-a-browser-extension/</link> <description><p>At Mozilla, of course we’re fans of <a href="https://www.firefox.com/features/translate/">Firefox’s built-in, privacy-focused translation feature</a>, but the beauty of browser extensions is the vast array of niche tools and customization features they can provide. Sometimes finding the right extension for your personal needs can profoundly change the way you interact with the web. So if you do a lot of translating on the internet, you might consider using a specialized extension translator. Here are some great options…</p> <h3><em><span class="has-inline-color has-light-green-cyan-color">I just want a simple, efficient way to translate. I don’t need fancy features.</span></em></h3> <h4>Simple Translate</h4> <p>It doesn’t get much simpler than this. Highlight the text you want to translate and click the extension’s toolbar icon to activate a streamlined pop-up. Your highlighted text automatically appears in the pop-up’s translation field and a drop-down menu lets you easily select your target language. <a href="https://addons.mozilla.org/firefox/addon/simple-translate/" rel="noreferrer noopener">Simple Translate</a> also features a handy one-click “Translate this page” button. </p> <div class="addon-card"></div> <h4>Translate Web Pages</h4> <p>Maybe you just need to translate full web pages, like when reading news articles, how-to guides, or job related sites. If so, <a href="https://addons.mozilla.org/firefox/addon/traduzir-paginas-web/" rel="noreferrer noopener">Translate Web Pages</a> might be the ideal solution for you with its sharp focus on full-page utility. </p> <div class="addon-card"></div> <p>The extension includes a handy feature if you commonly translate a few languages — you can select up to three languages to easily access with a single-click popup menu. TWP also gives you the option to designate specific websites you always want translated without prompt. </p> <h4>S3.Translator</h4> <p>Supporting 100+ languages, <a href="https://addons.mozilla.org/firefox/addon/s3_translator/" rel="noreferrer noopener">S3.Translator</a> serves up a full feature set of language tools, like the ability to translate full or select portions of a page, text-to-speech translation, YouTube subtitle translations, and more.</p> <div class="addon-card"></div> <p>There’s even a nifty Learning Language mode, which allows you to turn any text into the language you’re studying. Toggle between languages so you can conveniently learn as you naturally browse the web.</p> <h4>To Google Translate</h4> <p>Very popular, very simple translation extension that exclusively uses Google’s translation services, including text-to-speech. </p> <div class="addon-card"></div> <p>Simply highlight any text on a web page and right-click to pull up a <a href="https://addons.mozilla.org/firefox/addon/to-google-translate/" rel="noreferrer noopener">To Google Translate</a> context menu that allows three actions: 1) translate into your preferred language; 2) listen to audio of the text; 3) Translate the entire page</p> <figure class="wp-block-image"><img alt="" class="wp-image-142" height="619" src="https://mozamo.wpengine.com/wp-content/uploads/2021/06/blogTGT-1024x619.png" width="1024" />&lt;figcaption class="wp-element-caption"&gt;Right-click any highlighted text to activate To Google Translate.&lt;/figcaption&gt;</figure> <h3><em>I do a ton of translating. I need power features to save me time and trouble.</em></h3> <h4>ImTranslator</h4> <p>Striking a balance between out-of-the-box ease and deep customization potential, <a href="https://addons.mozilla.org/firefox/addon/imtranslator/" rel="noreferrer noopener">ImTranslator</a> leverages three top translation engines (Google, Bing, Translator) to cover 100+ languages. </p> <div class="addon-card"></div> <p>Other strong features include text-to-speech, dictionary and spell check in eight languages, hotkey customization, and a huge assortment of ways to customize the look of ImTranslator’s interface — from light and dark themes to font size and more. </p> <h4>Immersive Translate</h4> <p>One of the most feature packed translation extensions you’ll find, <a href="https://addons.mozilla.org/firefox/addon/immersive-translate/">Immersive Translate</a> goes beyond the web to capably handle PDF’s, eBooks and much more. </p> <div class="addon-card"></div> <p>With more features than we have space to list, here are some of the most uniquely compelling capabilities of Immersive Translate.</p> <ul class="wp-block-list"><li>Smartly identifies the main content portions of a web page to provide elegant side-by-side bilingual translations while avoiding page clutter</li> <li>Mouse hover translations</li> <li>Input translation box, so you can enter text to be translated (an ideal tool for real-time bilingual conversations)</li> <li>Video subtitle translations</li> <li>Strong Desktop and mobile support</li></ul> <h4>Mate Translate</h4> <p>A slick, intuitive extension that performs all basic translation functions very well, but it’s <a href="https://addons.mozilla.org/firefox/addon/instant-translate/" rel="noreferrer noopener">Mate Translate</a>’s paid tier that unlocks some unique features, such as Sync (saved translations can appear across devices and browsers, including iPhones and Mac). </p> <div class="addon-card"></div> <p>There’s also a neat Phrasebook feature, which lets you build custom word and phrase lists so you can return to common translations you frequently need. It works offline, too, so it’s ideal for travellers who need quick reference to common foreign phrases. </p> <p>These are some of our favorites, but there are plenty <a href="https://addons.mozilla.org/firefox/search/?q=translate" rel="noreferrer noopener">more translation extensions to explore</a> on <em>addons.mozilla.org</em>.</p></description> <pubDate>Wed, 15 Oct 2025 23:14:16 +0000</pubDate> <dc:creator>Scott DeVaney</dc:creator></item><item> <title>The Mozilla Blog: Fox Recap: A student-built tool that analyzes your browsing habits</title> <guid isPermaLink="false">https://blog.mozilla.org/?p=81518</guid> <link>https://blog.mozilla.org/en/firefox/firefox-recap/</link> <description><p>What would your browser history say about you? Whether you were getting things done this week or just collecting tabs, a new Firefox extension helps you reflect on your digital habits. </p> <p>Designed as a personal productivity tool, <a href="https://addons.mozilla.org/en-US/firefox/addon/fox-recap/" rel="noreferrer noopener" target="_blank">Fox Recap</a> is a <a href="https://sites.google.com/csumb.edu/cscapstone-s2025/cs-projects/firefox-ai-platform?authuser=0" rel="noreferrer noopener" target="_blank">capstone project</a> from a group of college seniors at California State University, Monterey Bay. It categorizes your browsing history, shows how much time you’re spending on different sites, and turns that data into simple visual reports. Everything happens locally on your device, so your information stays private.</p> <p><em><strong>Related story: <a href="https://blog.mozilla.org/addons/2025/10/21/developer-spotlight-fox-recap/" rel="noreferrer noopener" target="_blank">Developer Spotlight: Fox Recap</a></strong></em></p> <p></p> <div class="wp-block-group is-content-justification-space-between is-nowrap is-layout-flex wp-container-1 wp-block-group-is-layout-flex"><figure class="wp-block-image size-large"><img alt="Gradient intro card inviting a dive into today’s browser activity overview" class="wp-image-81539" height="1024" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/08/2-607x1024.png" width="607" /></figure> <figure class="wp-block-image size-large"><img alt="Browser activity stat card showing Technology as most-clicked with 37 visits" class="wp-image-81529" height="1024" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/08/1-607x1024.png" width="607" /></figure></div> <p></p> <h3>How Fox Recap works</h3> <p>Once you <a href="https://addons.mozilla.org/en-US/firefox/addon/fox-recap/" rel="noreferrer noopener" target="_blank">download</a> and open the extension on Firefox for desktop, click on settings and grant permission to run the ML engine. From there, you can choose to view your browsing history for today, this week or this month. </p> <p>Fox Recap then lays out your activity in simple charts and categories like technology, shopping, education and entertainment.</p> <p>“It’s really a tool for you to know how you use your browser,” said one of the student developers, Taimur Hasan. “Maybe you want to lessen the amount of time you spend on entertainment, and see that you use more education sites.”</p> <p>Kate Sawtell wanted to create a tool that helps people see how they spend their time on the internet. “As a busy mom with a bunch of side projects, I love how it shows where my time online actually goes,” Kate said. “Am I researching, streaming shows or slipping into online shopping holes? It’s not super serious or judgmental, just a quick snapshot of my habits. Sometimes it makes me feel productive, other times it’s like, wow okay maybe I should chill on the shopping tab.”</p> <div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img alt="Four people standing in front of a Firefox Recap project display at California State University, Monterey Bay. From left to right: Taimur Hasan, Mozilla community manager Matt Cool, Kate Sawtell, and Diego Valdez." class="wp-image-81594" height="768" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/08/firefox_recap_2025-1024x768.jpg" style="width: 650px;" width="1024" />&lt;figcaption class="wp-element-caption"&gt;Members of the Fox Recap team at California State University, Monterey Bay, presenting their capstone project. Pictured (left to right): Taimur Hasan, Mozilla community manager Matt Cool, Kate Sawtell, and Diego Valdez. Not pictured: Peter Mitchell.&lt;/figcaption&gt;</figure></div> <h3>‘Useful AI and strong privacy can coexist’</h3> <p>Firefox machine learning engineer Tarek Ziadé served as a mentor for the project. He was struck by how quickly Taimur, Kate, Diego and Peter internalized both the technical challenges of building AI features and their privacy implications. </p> <p>“I had assumed younger developers might treat privacy as an afterthought,” Tarek said. “I was wrong. They pushed for privacy by design from the start.”</p> <p>Taimur, who trained the model himself rather than using an existing one, explained: “It’s not an off-the-shelf model that I pulled off the internet. I trained it myself using my gaming computer.”</p> <div class="wp-block-group is-nowrap is-layout-flex wp-container-2 wp-block-group-is-layout-flex"><div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img alt="" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/08/categories-1.gif" style="width: 416px;" /></figure></div> <figure class="wp-block-image size-large is-resized"><img alt="Browser activity stat card showing Technology as most-clicked with 37 visits" class="wp-image-81529" height="1024" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/08/1-607x1024.png" style="width: 416px;" width="607" /></figure></div> <p></p> <p>Tarek believes that what the group built reflects the direction in which privacy-focused technology is headed.</p> <p>“Intelligence should be local by default, data should be minimized, and anything that needs to leave the device should be explicit and consented,” Tarek said. “As AI capabilities become a commodity, the differentiator will be trust.”</p> <p>That’s exactly where Mozilla should be leading, Tarek added: “making high-quality, on-device AI the default, and proving that useful AI and strong privacy can coexist.”</p> <h3>A glimpse of the next generation of web builders</h3> <p>For team member Diego Valdez, the project’s value is personal and practical: “I hope people who use Fox Recap can learn about their browsing activity in an engaging way, in hopes [of helping them] improve their productivity.”</p> <p>Mozilla community manager Matt Cool sees it in a larger frame. “It’s a scary and exciting time to enter the tech industry,” <a href="https://mattcool.tech/posts/csumb-student-capstones-2025" rel="noreferrer noopener" target="_blank">Matt said</a>. “The next generation of open web builders is already stepping up. Right here in Monterey, they’re building real-world projects, contributing to open-source, and tackling some of the toughest problems facing the future of the web.”</p> <p>Fox Recap is one of several student projects showcased at this spring’s Capstone Festival by the School of Computing and Design at Cal State Monterey Bay. Professor Bude Su, who chairs the department, emphasized the value of mentorship as students prepare for what comes next.</p> <p>“Mozilla’s involvement brought an added layer of motivation for our students,” Professor Su said. “The opportunity to work on a real-world project under industry mentorship has been invaluable for our students’ learning and professional growth.”</p> <p>The collaboration shows what can happen when education, mentorship and Mozilla’s values of openness and trust come together. Fox Recap helps make sense of the tabs we collect, but it also points to something bigger: a new wave of developers building tools that respect the people who use them.</p> <a class="ft-c-inline-cta" href="https://www.mozilla.org/firefox/new/?utm_source=blog.mozilla.org&amp;utm_medium=referral&amp;utm_campaign=blog-nav"> <div class="ft-c-inline-cta__media"> <img alt="" class="attachment-1x1 size-1x1" height="800" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2021/10/Visual-Guidelines-800x800.png" width="800" /> </div> <div class="ft-c-inline-cta__content"> <h4>Take control of your internet</h4> <span>Download Firefox</span> </div></a><p>The post <a href="https://blog.mozilla.org/en/firefox/firefox-recap/">Fox Recap: A student-built tool that analyzes your browsing habits </a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p></description> <pubDate>Wed, 15 Oct 2025 17:53:49 +0000</pubDate> <dc:creator>Kristina Bravo</dc:creator></item><item> <title>The Mozilla Blog: The social media director who helps make Merriam-Webster go viral</title> <guid isPermaLink="false">https://blog.mozilla.org/?p=82268</guid> <link>https://blog.mozilla.org/en/internet-culture/interviews/merriam-webster-social/</link> <description><figure class="wp-block-image size-large"><img alt="A bearded man in a denim shirt over a dark T-shirt, against a green background with a layered pixel effect." class="wp-image-82269" height="576" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/MCOTI_John-Sabine-Merriam-Webster-1024x576.png" width="1024" /></figure> <p><em>Here at Mozilla, we are the first to admit the internet isn’t perfect, but we know the internet is pretty darn magical. The internet opens up doors and opportunities, allows for human connection, and lets everyone find where they belong — their corners of the internet. We all have an internet story worth sharing. In </em><a href="https://blog.mozilla.org/tag/my-corner-of-the-internet/"><em>My Corner Of The Internet</em></a><em>, we talk with people about the online spaces they can’t get enough of, the sites and forums that shaped them, and how they would design their own corner of the web.</em></p> <p><em>We caught up with John Sabine, the social media director of Merriam-Webster and Encyclopedia Britannica. He talks about his favorite subreddit, silly deep dives and why his job makes him hopeful about the internet.</em><br /></p> <h3><strong>What is your favorite corner of the internet?</strong></h3> <p>Honestly, it’s the <a href="https://www.reddit.com/r/AskHistorians/">“AskHistorians” subreddit</a>. It’s one of my few internet habits that I have that has kept up. I can’t recommend it enough. I wish more things were curated with such level of scrutiny and scholarship. If people disagree, they disagree as Ph.D. people disagree. I don’t have a Ph.D., but I imagine it’s respectful. There’s profiles and avatars, but those feel very secondary to the content. You lead with the “what,” and then you can look up the “who” afterwards. I don’t post on Reddit at all; I’m a lurker in general on the internet. So I’m shocked by how many people weigh in on things.</p> <h3><strong>What is an internet deep dive that you can’t wait to jump back into?</strong></h3> <p>I have a bunch of articles that I have bookmarked… and my goal is to read one of the 400 articles I have saved. What I’m looking forward to specifically is just to read an article for joy, that’s not doomscrolling or part of my job. I do feel like when you have this job, you kind of get <em>internet-ed</em> out every day. And also: crosswords. I want to get better at crosswords, if that counts. We have one on <a href="http://merriam-webster.com">merriam-webster.com</a>, and I also do The New York Times, though I rarely finish it.</p> <h3><strong>What’s the last great story that you read?</strong></h3> <p>It was on <a href="http://ringer.com">ringer.com</a>. A writer named <a href="https://www.theringer.com/2025/10/06/nba/best-nba-player-names-ranked-21st-century">Tyler Parker went through NBA names</a>. He just ranked their names, had nothing to do with basketball. I started it before bed, and I was like, “Oh, I’ll skim.” I read every single word. He really thought about the names and how they make people feel. And it’s truly just how they sound like. That’s it. It was written beautifully. That’s a silly one, but I think silly deep dives are probably good for the soul right now.</p> <h3><strong>What is the one tab you always regret closing?</strong></h3> <p>Probably my calendar… And honestly, I always have Merriam-Webster and Britannica up. And I rarely do close them because I always need them for my work.</p> <h3><strong>What can you not stop talking about on the internet right now?</strong></h3> <p>So Merriam-Webster is releasing <a href="https://www.merriam-webster.com/collegiate-dictionary-twelfth-edition">its first print dictionary</a> in over 20 years. And they made it really pretty, and it feels like a really cool book that you would display. I’m very excited because I’m doing deep dives of old ads for an almost 200-year-old company. There’s a lot of stuff to go through. Some of it we have in the archives, some of it is just out there. So just going through the old print stuff, finding old paper dictionaries. So, like, selfishly, I’m excited for the new collegiate 12th edition.</p> <h3><strong>What was the first online community you engaged with?</strong></h3> <p>I’m a lurker, so engagement is a lot for me. The first time I probably posted was on a forum when I moved to Chicago to do improv comedy. There’s a Chicago improv forum and I think I was like, “What show should I see?”</p> <h3><strong>What articles and/or videos are you waiting to read/watch right now?</strong></h3> <p>I’m waiting for the next [recommendation] from my <a href="https://mozillasidebar.substack.com/p/gen-z-algorithm">group chats</a>. There are some people that will just send you anything, and you’re like, “OK, thank you for sending me this. I’ll watch 30% of the things you sent.” But there’s the ones that you’re like, “Oh, yeah, gotta watch that.” So I’ve got a couple friends like that, so I hope they send me stuff because Lord knows, the internet’s huge.</p> <h3><strong>Is there anything about the way people engage with Merriam-Webster online that makes you feel hopeful about the internet?</strong></h3> <p>Oh, 4,000%. Yes, doomscrolling is a reality of being online now. I know a lot of people who just step away and go outside and touch grass.</p> <p>But there’s still good stuff happening. The comment sections on our <a href="https://www.instagram.com/merriamwebster/">Instagram</a> and <a href="https://www.tiktok.com/@merriamwebster">TikTok</a> can actually be really fun. People have genuine, kind, often funny conversations. It’s rarely mean. Seeing that makes me hopeful, because people clearly want wholesome, thoughtful interactions.<br /><br />People have a personal connection to language. Over time, I’ve seen our audience expand to include all kinds of people who care deeply about words, even if they wouldn’t call themselves “word nerds.” Language is personal, and I think our work celebrates that.</p> <p>And honestly, I feel more hopeful doing this job on the internet than I think I would if I weren’t doing this work and was just online as a regular user.</p> <hr class="wp-block-separator has-alpha-channel-opacity" /> <p><em>John Sabine is the social media director for Merriam-Webster and Encyclopedia Britannica. He is originally from Dallas, Texas, and he’s never once spelled “definitely” correctly on the first try.</em></p><p>The post <a href="https://blog.mozilla.org/en/internet-culture/interviews/merriam-webster-social/">The social media director who helps make Merriam-Webster go viral</a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p></description> <pubDate>Wed, 15 Oct 2025 13:00:00 +0000</pubDate> <dc:creator>Kristina Bravo</dc:creator></item><item> <title>Mozilla Performance Blog: Firefox 144 ships interactionId for INP</title> <guid isPermaLink="false">https://blog.mozilla.org/performance/?p=531</guid> <link>https://blog.mozilla.org/performance/2025/10/15/firefox-144-ships-interactionid-for-inp/</link> <description><hr /><h3>TL;DR</h3><p><b>Firefox 144</b> ships <code>PerformanceEventTiming.interactionId</code>, which lets browsers and tools group events that belong to the same user interaction. This property is used to calculate <b>Interaction to Next Paint (INP)</b>, one of the <a href="https://web.dev/articles/inp">Core Web Vitals</a>.</p><hr /><p><b>Firefox 144</b> ships support for the <code>PerformanceEventTiming.interactionId</code> property. It helps browsers and tools identify which input events belong to a single user interaction, such as a <code>pointerdown</code>, <code>pointerup</code>, and <code>click</code> triggered by the same tap.</p><p>The <b>Interaction to Next Paint (INP)</b> metric, part of the <a href="https://web.dev/articles/inp">Core Web Vitals</a>, relies on this grouping to measure how responsive a page feels during real user interactions. INP represents how long it takes for the next frame to paint after a user input. Instead of looking at a single event, it captures the worst interaction latency during the page’s lifetime, giving a more complete view of responsiveness.</p><h3>Why this matters</h3><p>Before <code>interactionId</code>, each event had to be measured separately, which made it hard to connect related events as part of the same interaction.<br />With this property, performance tools and developers can now:</p><ul><li>Group related input events into a single interaction</li><li>Measure interaction latency more accurately</li><li>Identify and debug slow interactions more easily</li></ul><h3>Using interactionId</h3><p>If you use the<a href="https://developer.mozilla.org/docs/Web/API/PerformanceObserver"> PerformanceObserver API</a> to collect <code>PerformanceEventTiming</code> entries, you’ll start seeing an <code>interactionId</code> field in Firefox 144. Events that share a non-zero <code>interactionId</code> belong to the same interaction group, which can be used to calculate latency or understand where delays occur.</p><pre style="background: #2d2d2d; color: #ccc; padding: 10px; border-radius: 6px; overflow: auto; margin-top: 0; line-height: 1.4;"><code><span style="color: #999;">// The key is the interaction ID.</span><span style="color: #cc99cd;">let</span> <span style="color: #f99157;">eventLatencies</span> = {}; <span style="color: #cc99cd;">const</span> <span style="color: #f99157;">observer</span> = <span style="color: #6699cc;">new</span> <span style="color: #6699cc;">PerformanceObserver</span>((<span style="color: #f99157;">list</span>) =&gt; { list.<span style="color: #f2777a;">getEntries</span>().<span style="color: #f2777a;">forEach</span>((<span style="color: #f99157;">entry</span>) =&gt; { <span style="color: #cc99cd;">if</span> (entry.<span style="color: #f99157;">interactionId</span> &gt; 0) { <span style="color: #cc99cd;">const</span> <span style="color: #f99157;">interactionId</span> = entry.<span style="color: #f99157;">interactionId</span>; <span style="color: #cc99cd;">if</span> (!eventLatencies[interactionId]) { eventLatencies[interactionId] = []; } eventLatencies[interactionId].<span style="color: #f2777a;">push</span>(entry.<span style="color: #f99157;">duration</span>); } });}); observer.<span style="color: #f2777a;">observe</span>({ <span style="color: #f99157;">type</span>: <span style="color: #99cc99;">"event"</span>, <span style="color: #f99157;">buffered</span>: <span style="color: #cc99cd;">true</span> }); <span style="color: #999;">// Log events with maximum event duration for a user interaction</span><span style="color: #6699cc;">Object</span>.<span style="color: #f2777a;">entries</span>(eventLatencies).<span style="color: #f2777a;">forEach</span>(([<span style="color: #f99157;">k</span>, <span style="color: #f99157;">v</span>]) =&gt; { <span style="color: #6699cc;">console</span>.<span style="color: #f2777a;">log</span>(<span style="color: #6699cc;">Math</span>.<span style="color: #f2777a;">max</span>(...v));});</code></pre><p>If you use external tools and libraries like <a href="https://github.com/GoogleChrome/web-vitals">web-vitals</a>, they should already collect the INP value for you.</p></description> <pubDate>Wed, 15 Oct 2025 12:44:26 +0000</pubDate> <dc:creator>Nazim Can Altinova</dc:creator></item><item> <title>This Week In Rust: This Week in Rust 621</title> <guid isPermaLink="false">tag:this-week-in-rust.org,2025-10-15:/blog/2025/10/15/this-week-in-rust-621/</guid> <link>https://this-week-in-rust.org/blog/2025/10/15/this-week-in-rust-621/</link> <description><p>Hello and welcome to another issue of <em>This Week in Rust</em>!<a href="https://www.rust-lang.org/">Rust</a> 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<a href="https://bsky.app/profile/thisweekinrust.bsky.social">@thisweekinrust.bsky.social</a> on Bluesky or<a href="https://mastodon.social/@thisweekinrust">@ThisWeekinRust</a> on mastodon.social, or<a href="https://github.com/rust-lang/this-week-in-rust">send us a pull request</a>.Want to get involved? <a href="https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md">We love contributions</a>.</p><p><em>This Week in Rust</em> is openly developed <a href="https://github.com/rust-lang/this-week-in-rust">on GitHub</a> and archives can be viewed at <a href="https://this-week-in-rust.org/">this-week-in-rust.org</a>.If you find any errors in this week's issue, <a href="https://github.com/rust-lang/this-week-in-rust/pulls">please submit a PR</a>.</p><p>Want TWIR in your inbox? <a href="https://this-week-in-rust.us11.list-manage.com/subscribe?u=fd84c1c757e02889a9b08d289&amp;id=0ed8b72485">Subscribe here</a>.</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#updates-from-rust-community">Updates from Rust Community</a></h4> <h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#official">Official</a></h5><ul><li><a href="https://blog.rust-lang.org/inside-rust/2025/10/14/program-management-update-2025-09/">Program management update — September 2025</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#foundation">Foundation</a></h5><ul><li><a href="https://rustfoundation.org/media/introducing-the-rust-foundations-newest-project-directors-october-2025/">Rust Foundation Board Updates</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#newsletters">Newsletters</a></h5><ul><li><a href="https://rust-osdev.com/this-month/2025-09/">This Month in Rust OSDev: September 2025</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#projecttooling-updates">Project/Tooling Updates</a></h5><ul><li><a href="https://lwn.net/SubscriberLink/1040197/0733825193ca1f04/">Gccrs after libcore</a></li><li><a href="https://lwn.net/SubscriberLink/1039374/664ea18bb8a3c1a8/">A new API for interrupt-aware spinlocks</a></li><li><a href="https://www.rustydonkey.dev/blog/2025.10.08_introduction_to_heave/">Announcing Heave 0.1.0: an EAV data model rust library that can persist custom structs onto a SQLite DB with no friction at all!</a></li><li><a href="https://www.willsearch.com.br/?page_id=19">GuardianDB 0.10.15 - Introducing: the embedded iroh node</a></li><li><a href="https://linebender.org/blog/tmil-21/">Linebender in September 2025</a></li><li><a href="https://github.com/emilk/egui/releases/tag/0.33.0">egui 0.33.0 - <code>egui::Plugin</code>, better kerning, kitdiff viewer</a></li><li><a href="https://slint.dev/blog/making-slint-desktop-ready">Making Slint Desktop-Ready</a></li><li><a href="https://joonaa.dev/blog/09/avian-0-4">Avian Physics 0.4</a></li><li><a href="https://blog.antoyo.xyz/rustc_codegen_gcc-progress-report-38">rustc_codegen_gcc: Progress Report #38</a></li><li><a href="https://contextgeneric.dev/blog/v0-5-0-release/">CGP v0.5.0 Release - Auto dispatchers, extensible datatype improvements, monadic computation, RTN emulation, modular serde, and more</a></li><li><a href="https://blog.weiznich.de/blog/diesel-async-0-7/">Diesel-Async 0.7</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#observationsthoughts">Observations/Thoughts</a></h5><ul><li><a href="https://smallcultfollowing.com/babysteps/blog/2025/10/13/ergonomic-explicit-handles/">We need (at least) ergonomic, explicit handles</a></li><li><a href="https://www.ncameron.org/blog/to-panic-or-not-to-panic/">To panic or not to panic</a></li><li><a href="https://www.jessestuart.ca/posts/2025-10-10-recursive-type-state-in-rust/">Recursive type state in Rust</a></li><li><a href="https://tweedegolf.nl/en/blog/195/talk-about-memory-safety-at-one-conference">Talk about memory safety at ONE Conference</a></li><li><a href="https://www.thecodedmessage.com/posts/rust-trait-limitation/">A Little Rust Trait Limitation</a></li><li><a href="https://aloso.foo/blog/2025-10-10-effects/">Effects in Rust (and Koka)</a></li><li>[video] <a href="https://www.youtube.com/playlist?list=PLilpJp3WAOvcn5_VDv3VIkQzniMWl_BfO">Oxidize Conference 2025</a></li><li>[video] <a href="https://www.youtube.com/watch?v=nOSxuaDgl3s">Rust 2025: 400K Salaries, AI, Defence &amp; Borrow Checker — Jon Gjengset on Rust &amp; the Future of Coding</a></li><li>[audio] <a href="https://netstack.fm/#episode-9">Netstack.FM Episode 9 – gRPC with Lucio Franco</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-walkthroughs">Rust Walkthroughs</a></h5><ul><li><a href="https://kerkour.com/sqlite-extension-rust">Building SQLite extensions in Rust</a></li><li><a href="https://blog.0xshadow.dev/posts/backend-engineering-with-axum/axum-jwt-refresh-token/">Axum Backend Series: JWT with Refresh Token</a></li><li>[series] <a href="https://aibodh.com/posts/bevy-rust-game-development-chapter-1/">The Impatient Programmer's Guide to Bevy and Rust: Chapter 1 - Let There Be a Player</a></li><li>[series] <a href="https://aibodh.com/posts/bevy-rust-game-development-chapter-2/">The Impatient Programmer's Guide to Bevy and Rust: Chapter 2 - Let There Be a World</a></li><li>[video] <a href="https://www.youtube.com/watch?v=F04kQMKwrwQ">Building Embedded TUIs with Rust &amp; Ratatui — Tokyo Rust Meetup 2025</a></li><li>[video] <a href="https://www.youtube.com/watch?v=IkCUhGAyS9U">Build with Naz : Eliminate off by one errors with Rust type system design</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#research">Research</a></h5><ul><li><a href="https://hjaem.info/c-to-rust-papers">Papers on C-to-Rust Translation</a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#miscellaneous">Miscellaneous</a></h5><ul><li><a href="https://rustnl.org/fund/">Rust Maintainers Fund - RustNL</a></li><li><a href="https://github.com/MariaLetta/free-ferris-pack">🦀 Pack of 50+ Free (CC0 license) Ferris illustrations with different emotions, poses and situations in PNG and SVG 🦀</a></li></ul><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#crate-of-the-week">Crate of the Week</a></h4><p>This week's crate is <a href="https://github.com/olson-sean-k/mitsein">mitsein</a>, a library of non-empty collections.</p><p>Thanks to <a href="https://users.rust-lang.org/t/crate-of-the-week/2704/1481">Nik Revenco</a> for the suggestion!</p><p><a href="https://users.rust-lang.org/t/crate-of-the-week/2704">Please submit your suggestions and votes for next week</a>!</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#calls-for-testing">Calls for Testing</a></h4><p>An important step for RFC implementation is for people to experiment with theimplementation and give feedback, especially before stabilization.</p><p>If you are a feature implementer and would like your RFC to appear in this list, add a<code>call-for-testing</code> label to your RFC along with a comment providing testing instructions and/orguidance on which aspect(s) of the feature need testing.</p><ul><li><em>No calls for testing were issued this week by <a href="https://github.com/rust-lang/rust/labels/call-for-testing">Rust</a>, <a href="https://github.com/rust-lang/rfcs/issues?q=label%3Acall-for-testing">Rust language RFCs</a>, <a href="https://github.com/rust-lang/cargo/labels/call-for-testing">Cargo</a> or <a href="https://github.com/rust-lang/rustup/labels/call-for-testing">Rustup</a>.</em></li></ul><p><a href="https://github.com/rust-lang/this-week-in-rust/issues">Let us know</a> if you would like your feature to be tracked as a part of this list.</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#call-for-participation-projects-and-speakers">Call for Participation; projects and speakers</a></h4><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cfp-projects">CFP - Projects</a></h5><p>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!</p><p>Some of these tasks may also have mentors available, visit the task page for more information.</p> <ul><li><a href="https://github.com/diesel-rs/diesel/discussions/4805">Diesel - View Support - Show me your view definitions</a></li><li><a href="https://github.com/diesel-rs/diesel/issues/4760">Diesel - Add <code>#[diagnostic::do_not_recommend]</code> to <code>impl AsExpression for T: Expression</code></a></li><li><a href="https://github.com/diesel-rs/diesel/issues/4764">Diesel - Improve documentation for Postgres loading modes</a></li></ul><p>If you are a Rust project owner and are looking for contributors, please submit tasks <a href="https://github.com/rust-lang/this-week-in-rust?tab=readme-ov-file#call-for-participation-guidelines">here</a> or through a <a href="https://github.com/rust-lang/this-week-in-rust">PR to TWiR</a> or by reaching out on <a href="https://x.com/ThisWeekInRust">X (formerly Twitter)</a> or <a href="https://mastodon.social/@thisweekinrust">Mastodon</a>!</p><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cfp-events">CFP - Events</a></h5><p>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.</p> <ul><li><a href="https://tokio.rs/blog/2025-09-26-announcing-tokio-conf-cfp"><strong>TokioConf 2026</strong></a> | CFP closes 2025-12-08 | Portland, Oregon, USA | 2026-04-20</li></ul><p>If you are an event organizer hoping to expand the reach of your event, please submit a link to the website through a <a href="https://github.com/rust-lang/this-week-in-rust">PR to TWiR</a> or by reaching out on <a href="https://x.com/ThisWeekInRust">X (formerly Twitter)</a> or <a href="https://mastodon.social/@thisweekinrust">Mastodon</a>!</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#updates-from-the-rust-project">Updates from the Rust Project</a></h4><p>420 pull requests were <a href="https://github.com/search?q=is%3Apr+org%3Arust-lang+is%3Amerged+merged%3A2025-10-07..2025-10-14">merged in the last week</a></p><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#compiler">Compiler</a></h6><ul><li><a href="https://github.com/rust-lang/rust/pull/147205">add a new <code>wasm32-wasip3</code> target to Rust</a></li><li><a href="https://github.com/rust-lang/rust/pull/146869">Global Variable Naming: evaluate constants lazily</a></li><li><a href="https://github.com/rust-lang/rust/pull/147423"><code>DepNodeColor</code> tweaks</a></li><li><a href="https://github.com/rust-lang/rust/pull/147483">perform InstSimplify before ReferencePropagation</a></li><li><a href="https://github.com/rust-lang/rust/pull/147477">refactor AddCallGuards in two loops</a></li><li><a href="https://github.com/rust-lang/rust/pull/147502">split <code>overlapping_{inherent,trait}_impls</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/145513">validate <code>CopyForDeref</code> and <code>DerefTemps</code> better and remove them from runtime MIR</a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#library">Library</a></h6><ul><li><a href="https://github.com/rust-lang/rust/pull/147124">move more code to <code>RawVec::finish_grow</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/146568">port the implemention of SIMD intrinsics from Miri to const-eval</a></li><li><a href="https://github.com/rust-lang/rust/pull/147457">specialize <code>slice::fill</code> to use memset when possible</a></li><li><a href="https://github.com/rust-lang/rust/pull/147562">stabilize <code>NonZero&lt;u*&gt;::div_ceil</code></a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cargo">Cargo</a></h6><ul><li><a href="https://github.com/rust-lang/cargo/pull/15947">Reorganize build-dir layout</a></li><li><a href="https://github.com/rust-lang/cargo/pull/16063">add: Report a missing source error for workspace dependencies</a></li><li><a href="https://github.com/rust-lang/cargo/pull/16064">script: Default bin.name to package.name</a></li><li><a href="https://github.com/rust-lang/cargo/pull/16087">script: Store cargo script lockfiles in build-dir</a></li><li><a href="https://github.com/rust-lang/cargo/pull/16081">tree: Switch from <code>--depth public</code> to <code>--edges public</code></a></li><li><a href="https://github.com/rust-lang/cargo/pull/16082">allow to rustfix <code>unused_variables</code> lint</a></li><li><a href="https://github.com/rust-lang/cargo/pull/16075">fix regression that swallowed json diagnostic explanations</a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rustdoc">Rustdoc</a></h6><ul><li><a href="https://github.com/rust-lang/rust/pull/147402">rustdoc: Don't serialize &amp; deserialize data that doesn't go over the wire</a></li><li><a href="https://github.com/rust-lang/rust/pull/147443">rustdoc: a small performance improvement: only allocate new string if there are DOS backlines in highlight.rs</a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#clippy">Clippy</a></h6><ul><li><a href="https://github.com/rust-lang/rust-clippy/pull/15843"><code>multiple_inherent_impl</code>: Add config option to target specific scope</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15826"><code>zero_repeat_side_effects</code>: don't suggest unnecessary braces around stmts</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15740"><code>clone_on_ref_ptr</code>: only name the generic type if possible</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15608"><code>collapsible_match</code>: exclude binding modes from <code>struct</code> field pattern suggestions</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15815"><code>zero_repeat_side_effects</code>: don't suggest unsuggestable types</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15816"><code>legacy_numeric_constants</code>: add ctxt check for internal macro</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15812"><code>manual_unwrap_or</code>: fix false positive edge case</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15847"><code>get_unwrap</code>: avoid calling <code>is_type_diagnostic_item</code> multiple times</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/14953">add <code>replace_box</code> lint</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/14662">add lint <code>unnecessary_option_map_or_else</code></a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15566">check structs and enums for <code>use_self</code></a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15547">fix <code>needless_continue</code> false positive when match type is not unit or never</a></li><li><a href="https://github.com/rust-lang/rust-clippy/pull/15849">honor <code>allow</code>/<code>expect</code> attributes on ADT and <code>impl Clone</code> nodes</a></li></ul><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-analyzer">Rust-Analyzer</a></h6><ul><li><a href="https://github.com/rust-lang/rust-analyzer/pull/19771">add ide-assist: generate blanket trait impl</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20812">add self param completions for trait assoc fn</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20804">build rust-analyzer with <code>--target</code> for install/pgo xtask</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20526">fix .let completion not working for let-chain</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20816">fix closure coerced return type for <code>add_return_type</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20824">fix empty closure completion analysis</a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20788">fix not applicable c-str and byte-str for <code>raw_string</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20817">fix not applicable on param in let-stmt for <code>add_explicit_type</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20805">improve parsing error for <code>static</code> and <code>const</code></a></li><li><a href="https://github.com/rust-lang/rust-analyzer/pull/20803">replace <code>--show-output</code> task defaults with <code>--nocapture</code></a></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-compiler-performance-triage">Rust Compiler Performance Triage</a></h5><p>This week saw small wins across the board from some microoptimizations of the incremental querysystem (<a href="https://github.com/rust-lang/rust/pull/147423">#147423</a>). There have also been a couple ofregressions. <a href="https://github.com/rust-lang/rust/pull/142390">#142390</a> introduced regressions of <code>check</code>builds across the board. The largest regression (18%) is from an incremental opt build of a secondaryartificial stress test, so we deemed it acceptable.</p><p>Triage done by <strong>@kobzol</strong>.</p><p>Revision range: <a href="https://perf.rust-lang.org/?start=1a3cdd34629306fa67624eaa60d73687e7fcf855&amp;end=956f47c32f1bd97b22cd702d7ccf78f0f0d42c34&amp;absolute=false&amp;stat=instructions%3Au">1a3cdd34..956f47c3</a></p><p><strong>Summary</strong>:</p><table><thead><tr><th align="center">(instructions:u)</th><th align="center">mean</th><th align="center">range</th><th align="center">count</th></tr></thead><tbody><tr><td align="center">Regressions ❌ <br /> (primary)</td><td align="center">0.7%</td><td align="center">[0.1%, 2.0%]</td><td align="center">65</td></tr><tr><td align="center">Regressions ❌ <br /> (secondary)</td><td align="center">0.8%</td><td align="center">[0.1%, 18.6%]</td><td align="center">65</td></tr><tr><td align="center">Improvements ✅ <br /> (primary)</td><td align="center">-0.6%</td><td align="center">[-1.6%, -0.1%]</td><td align="center">119</td></tr><tr><td align="center">Improvements ✅ <br /> (secondary)</td><td align="center">-0.4%</td><td align="center">[-1.6%, -0.1%]</td><td align="center">76</td></tr><tr><td align="center">All ❌✅ (primary)</td><td align="center">-0.1%</td><td align="center">[-1.6%, 2.0%]</td><td align="center">184</td></tr></tbody></table><p>2 Regressions, 7 Improvements, 3 Mixed; 3 of them in rollups35 artifact comparisons made in total</p><p><a href="https://github.com/rust-lang/rustc-perf/blob/b4b30e719c7083141669f79edfdf20e685cf918f/triage/2025/2025-10-13.md">Full report here</a>.</p><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#approved-rfcs"></a><a href="https://github.com/rust-lang/rfcs/commits/master">Approved RFCs</a></h5><p>Changes to Rust follow the Rust <a href="https://github.com/rust-lang/rfcs#rust-rfcs">RFC (request for comments) process</a>. Theseare the RFCs that were approved for implementation this week:</p><ul><li><em>No RFCs were approved this week.</em></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#final-comment-period">Final Comment Period</a></h5><p>Every week, <a href="https://www.rust-lang.org/team.html">the team</a> announces the 'final comment period' for RFCs and key PRswhich are reaching a decision. Express your opinions now.</p><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#tracking-issues-prs">Tracking Issues &amp; PRs</a></h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust"></a><a href="https://github.com/rust-lang/rust/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Rust</a><ul><li><a href="https://github.com/rust-lang/rust/pull/147258">iter repeat: panic on last</a></li><li><a href="https://github.com/rust-lang/rust/issues/146939">Tracking Issue (take 2) for <code>more_float_constants</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/146098">Temporary lifetime extension for blocks</a></li><li><a href="https://github.com/rust-lang/rust/pull/140463">Document MaybeUninit bit validity</a></li><li><a href="https://github.com/rust-lang/rust/pull/147382">unused_must_use: Don't warn on <code>Result&lt;(), Uninhabited&gt;</code> or <code>ControlFlow&lt;Uninhabited, ()&gt;</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/146961">Allow passing <code>expr</code> metavariable to <code>cfg</code></a></li><li><a href="https://github.com/rust-lang/rust/pull/147022">Remove current code for embedding command-line args in PDB</a></li><li><a href="https://github.com/rust-lang/rust/pull/146725"><code>-Znext-solver</code> instantiate predicate binder without recanonicalizing goal</a></li></ul><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cargo_1"></a><a href="https://github.com/rust-lang/cargo/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Cargo</a><ul><li><a href="https://github.com/rust-lang/cargo/issues/7614">Should build-plans be deleted?</a></li></ul><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-rfcs"></a><a href="https://github.com/rust-lang/rfcs/labels/final-comment-period">Rust RFCs</a><ul><li><a href="https://github.com/rust-lang/rfcs/pull/3848">Pass pointers to <code>const</code> in assembly</a></li></ul><a class="toclink" href="http://this-week-in-rust.org/atom.xml#leadership-council"></a><a href="https://github.com/rust-lang/leadership-council/issues?q=state%3Aopen%20label%3Afinal-comment-period">Leadership Council</a><ul><li><a href="https://github.com/rust-lang/leadership-council/issues/232">Delegate GSoC money spending to the t-mentorship team</a></li></ul><p><em>No Items entered Final Comment Period this week for <a href="https://github.com/rust-lang/lang-team/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc+">Language Team</a>, <a href="https://github.com/rust-lang/reference/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Language Reference</a> or <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Unsafe Code Guidelines</a>.</em></p><p>Let us know if you would like your PRs, Tracking Issues or RFCs to be tracked as a part of this list.</p><h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#new-and-updated-rfcs"></a><a href="https://github.com/rust-lang/rfcs/pulls">New and Updated RFCs</a></h6><ul><li><em>No New or Updated RFCs were created this week.</em></li></ul><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#upcoming-events">Upcoming Events</a></h4><p>Rusty Events between 2025-10-15 - 2025-11-12 🦀</p><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#virtual">Virtual</a></h5><ul><li>2025-10-15 | Hybrid (Vancouver, BC, CA) | <a href="https://www.meetup.com/vancouver-rust">Vancouver Rust</a><ul><li><a href="https://www.meetup.com/vancouver-rust/events/307731034/"><strong>indielinks</strong></a></li></ul></li><li>2025-10-16 | Virtual (Girona, ES) | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/o8fh3fh7"><strong>Sessió setmanal de codificació / Weekly coding session</strong></a></li></ul></li><li>2025-10-16 | Virtual (Nürnberg, DE) | <a href="https://www.meetup.com/rust-noris">Rust Nuremberg</a><ul><li><a href="https://www.meetup.com/rust-noris/events/306046668/"><strong>Rust Nürnberg online</strong></a></li></ul></li><li>2025-10-18 | Virtual (Gdansk/Kraków/Wroclaw, PL) | <a href="https://www.meetup.com/stacja-it-trojmiasto/">Stacja IT Trójmiasto</a><ul><li><a href="https://www.meetup.com/stacja-it-trojmiasto/events/310935164/"><strong>[BEZPŁATNIE] Programowanie w języku Rust</strong></a> | <a href="https://www.meetup.com/stacja-it-krakow/events/310935157/">Kraków Mirror</a> | <a href="https://www.meetup.com/stacja-it-wroclaw/events/310935159/">Wroclaw Mirror</a></li></ul></li><li>2025-10-19 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/311109167/"><strong>Rust Readers Discord Discussion: Macros</strong></a></li></ul></li><li>2025-10-21 | Virtual (London, UK) | <a href="https://www.meetup.com/women-in-rust">Women in Rust</a><ul><li><a href="https://www.meetup.com/women-in-rust/events/311068625/"><strong>👋 Community Catch Up</strong></a></li></ul></li><li>2025-10-21 | Virtual (Washington, DC, US) | <a href="https://www.meetup.com/rustdc">Rust DC</a><ul><li><a href="https://www.meetup.com/rustdc/events/310002307/"><strong>Mid-month Rustful</strong></a></li></ul></li><li>2025-10-22 | Virtual (Boulder, CO, US) | <a href="https://www.meetup.com/boulder-elixir/events/">Boulder Elixir</a><ul><li><a href="https://www.meetup.com/boulder-elixir/events/310996627/"><strong>Integrating Elixir and Apache DataFusion with Rustler</strong></a></li></ul></li><li>2025-10-22 | Virtual (Buenos Aires, AR) | <a href="https://www.meetup.com/es-ES/net-baires/">[Net-Baires] Comunidad de .NET en Buenos Aires</a><ul><li><a href="https://www.meetup.com/es-ES/net-baires/events/311365783/"><strong>Rust para devs .NET | Community Standup #10</strong></a></li></ul></li><li>2025-10-23 | Hybrid (Seattle/Bellevue, WA, US) | <a href="https://www.meetup.com/join-srug">Seattle Rust User Group</a><ul><li><a href="https://www.meetup.com/seattle-rust-user-group/events/311351020/"><strong>October, 2025 SRUG (Seattle Rust User Group) Meetup</strong></a></li></ul></li><li>2025-10-23 | Virtual (Berlin, DE) | <a href="https://www.meetup.com/rust-berlin">Rust Berlin</a><ul><li><a href="https://www.meetup.com/rust-berlin/events/306046641/"><strong>Rust Hack and Learn</strong></a></li></ul></li><li>2025-10-23 | Virtual (Girona, ES) | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/zyc3touy"><strong>Sessió setmanal de codificació / Weekly coding session</strong></a></li></ul></li><li>2025-10-26 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/311109171/"><strong>Rust Readers Discord Discussion: Macros</strong></a></li></ul></li><li>2025-10-28 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/305361444/"><strong>Fourth Tuesday</strong></a></li></ul></li><li>2025-10-30 | Virtual (Girona, ES) | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/t8yovmmm"><strong>Sessió setmanal de codificació / Weekly coding session</strong></a></li></ul></li><li>2025-11-01 | Virtual (Kampala, UG) | <a href="https://www.eventbrite.com/o/rust-circle-kampala-65249289033">Rust Circle Meetup</a><ul><li><a href="https://www.eventbrite.com/e/rust-circle-meetup-tickets-628763868657"><strong>Rust Circle Meetup</strong></a></li></ul></li><li>2025-11-02 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/311109173/"><strong>Rust Readers Discord Discussion: Macros</strong></a></li></ul></li><li>2025-11-05 | Virtual (Buffalo, NY, US) | <a href="https://www.meetup.com/buffalo-rust-meetup">Buffalo Rust Meetup</a><ul><li><a href="https://www.meetup.com/buffalo-rust-meetup/events/305304242/"><strong>Buffalo Rust User Group</strong></a></li></ul></li><li>2025-11-05 | Virtual (Indianapolis, IN, US) | <a href="https://www.meetup.com/indyrs">Indy Rust</a><ul><li><a href="https://www.meetup.com/indyrs/events/wqzhftyhcpbhb/"><strong>Indy.rs - with Social Distancing</strong></a></li></ul></li><li>2025-11-06 | Virtual (Berlin, DE) | <a href="https://www.meetup.com/rust-berlin/events/">Rust Berlin</a><ul><li><a href="https://www.meetup.com/rust-berlin/events/305646021/"><strong>Rust Hack and Learn</strong></a></li></ul></li><li>2025-11-06 | Virtual (Girona, ES) | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/xkd84gfz"><strong>Sessió setmanal de codificació / Weekly coding session</strong></a></li></ul></li><li>2025-11-09 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/events/">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/311109175/"><strong>Rust Readers Discord Discussion: Macros</strong></a></li></ul></li><li>2025-11-11 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/events/">Dallas Rust User Meetup</a><ul><li><a href="https://www.meetup.com/dallasrust/events/305361536/"><strong>Second Tuesday</strong></a></li></ul></li><li>2025-11-11 | Virtual (London, GB) | <a href="https://www.meetup.com/women-in-rust/events/">Women in Rust</a><ul><li><a href="https://www.meetup.com/women-in-rust/events/311068632/"><strong>👋 Community Catch Up</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#asia">Asia</a></h5><ul><li>2025-10-20 | Tel Aviv-yafo, IL | <a href="https://www.meetup.com/rust-tlv">Rust 🦀 TLV</a><ul><li><a href="https://www.meetup.com/rust-tlv/events/310628902/"><strong>In person Rust October 2025 at AWS in Tel Aviv</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#europe">Europe</a></h5><ul><li>2025-10-21 | Aarhus, DK | <a href="https://www.meetup.com/rust-aarhus">Rust Aarhus</a><ul><li><a href="https://www.meetup.com/rust-aarhus/events/311035141/"><strong>Hack Night</strong></a></li></ul></li><li>2025-10-21 | Bergen, NO | <a href="https://www.meetup.com/bergen-rust-new-technology/events/">Rust Bergen</a><ul><li><a href="https://www.meetup.com/bergen-rust-new-technology/events/311153821/"><strong>Rust Meetup #01 @ Zrch</strong></a></li></ul></li><li>2025-10-21 | Leipzig, DE | <a href="https://www.meetup.com/rust-modern-systems-programming-in-leipzig">Rust - Modern Systems Programming in Leipzig</a><ul><li><a href="https://www.meetup.com/rust-modern-systems-programming-in-leipzig/events/308592252/"><strong>Topic TBD</strong></a></li></ul></li><li>2025-10-21 | London, UK | <a href="https://www.meetup.com/london-rust-project-group">London Rust Project Group</a><ul><li><a href="https://www.meetup.com/london-rust-project-group/events/310813952/"><strong>Rust in Surgery: Powering the Data Pipelines</strong></a></li></ul></li><li>2025-10-23 | Edinburgh, UK | <a href="https://www.meetup.com/rust-edi/events/">Rust and Friends</a><ul><li><a href="https://www.meetup.com/rust-and-friends/events/311501254/"><strong>Rust and Friends (evening pub)</strong></a></li></ul></li><li>2025-10-24 | Edinburgh, UK | <a href="https://www.meetup.com/rust-edi/events/">Rust and Friends</a><ul><li><a href="https://www.meetup.com/rust-and-friends/events/311501249/"><strong>Rust and Friends (daytime coffee)</strong></a></li></ul></li><li>2025-10-28 | Manchester, UK | <a href="https://www.meetup.com/rust-manchester">Rust Manchester</a><ul><li><a href="https://www.meetup.com/rust-manchester/events/307919171/"><strong>Rust Manchester October Code Night</strong></a></li></ul></li><li>2025-10-29 | Dortmund, DE | <a href="https://www.meetup.com/rust-dortmund/events/">Rust Dortmund</a><ul><li><a href="https://www.meetup.com/rust-dortmund/events/311251545/"><strong>Rust Dortmund Meetup October 2025</strong></a></li></ul></li><li>2025-10-30 | Copenhagen, DK | <a href="https://www.meetup.com/copenhagen-rust-community">Copenhagen Rust Community</a><ul><li><a href="https://www.meetup.com/copenhagen-rust-community/events/311405044/"><strong>Rust meetup #62 sponsored by Google!</strong></a></li></ul></li><li>2025-10-30 | Prague, CZ | <a href="https://www.meetup.com/rust-prague">Rust Prague</a><ul><li><a href="https://www.meetup.com/rust-prague/events/310967094/"><strong>Rust Meetup Prague (October 2025)</strong></a></li></ul></li><li>2025-11-02 - 2025-11-04 | Florence, IT | <a href="https://rustlab.it/">Rustlab 2025</a><ul><li><a href="https://rustlab.it/"><strong>Rustlab 2025</strong></a></li></ul></li><li>2025-11-04 | Manchester, UK | <a href="https://www.meetup.com/rust-manchester">Rust Manchester</a><ul><li><a href="https://www.meetup.com/rust-manchester/events/310921632/"><strong>Rust Manchester November Talk</strong></a></li></ul></li><li>2025-11-05 | Girona, ES | <a href="https://lu.ma/rust-girona">Rust Girona</a> | <a href="https://silicongirona.club">Silicon Girona</a><ul><li><a href="https://luma.com/xl8ob0tn"><strong>Rust Girona Hack &amp; Learn 11 2025</strong></a></li></ul></li><li>2025-11-05 | Oslo, NO | <a href="https://www.meetup.com/rust-oslo">Rust Oslo</a><ul><li><a href="https://www.meetup.com/rust-oslo/events/310601872/"><strong>Rust Hack'n'Learn at Kampen Bistro</strong></a></li></ul></li><li>2025-11-05 | Oxford, UK | <a href="https://www.meetup.com/oxford-rust-meetup-group">Oxford ACCU/Rust Meetup.</a><ul><li><a href="https://www.meetup.com/oxford-rust-meetup-group/events/nnrkttyhcpbhb/"><strong>Rust/ACCU meetup.</strong></a></li></ul></li><li>2025-11-06 | Gdansk, PL | <a href="https://www.meetup.com/rust-gdansk/events/">Rust Gdansk</a><ul><li><a href="https://www.meetup.com/rust-gdansk/events/310924266/"><strong>Rust Gdansk Meetup #11</strong></a></li></ul></li><li>2025-11-12 | Reading, UK | <a href="https://www.meetup.com/reading-rust-workshop/events/">Reading Rust Workshop</a><ul><li><a href="https://www.meetup.com/reading-rust-workshop/events/308944050/"><strong>Reading Rust Meetup</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#north-america">North America</a></h5><ul><li>2025-10-15 | Hybrid (Vancouver, BC, CA) | <a href="https://www.meetup.com/vancouver-rust">Vancouver Rust</a><ul><li><a href="https://www.meetup.com/vancouver-rust/events/307731034/"><strong>indielinks</strong></a></li></ul></li><li>2025-10-16 | Mountain View, CA, US | <a href="https://www.meetup.com/hackerdojo/events/">Hacker Dojo</a><ul><li><a href="https://www.meetup.com/hackerdojo/events/311012947/"><strong>RUST MEETUP at HACKER DOJO</strong></a></li></ul></li><li>2025-10-16 | San Francisco, CA, US | <a href="https://luma.com/calendar/cal-Cnmn4RR2n4fRUNZ">Svix</a><ul><li><a href="https://luma.com/tp6w7tc9"><strong>San Francisco Rust Meetup</strong></a></li></ul></li><li>2025-10-21 | San Francisco, CA, US | <a href="https://luma.com/events-by-vara-gear">Vara &amp; Gear</a><ul><li><a href="https://luma.com/kbs2os1c"><strong>Rust Workshop by Vara Network</strong></a></li></ul></li><li>2025-10-21 | San Francisco, CA, US | <a href="https://www.meetup.com/san-francisco-rust-study-group">San Francisco Rust Study Group</a><ul><li><a href="https://www.meetup.com/san-francisco-rust-study-group/events/308284343/"><strong>Rust Hacking in Person</strong></a></li></ul></li><li>2025-10-22 | Austin, TX, US | <a href="https://www.meetup.com/rust-atx">Rust ATX</a><ul><li><a href="https://www.meetup.com/rust-atx/events/310457307/"><strong>Rust Lunch - Fareground</strong></a></li></ul></li><li>2025-10-23 | Hybrid (Seattle/Bellevue, WA, US) | <a href="https://www.meetup.com/join-srug">Seattle Rust User Group</a><ul><li><a href="https://www.meetup.com/seattle-rust-user-group/events/311351020/"><strong>October, 2025 SRUG (Seattle Rust User Group) Meetup</strong></a></li></ul></li><li>2025-10-23 | Nashville, TN, US | <a href="https://www.meetup.com/music-city-rust-developers">Music City Rust Developers</a><ul><li><a href="https://www.meetup.com/music-city-rust-developers/events/304333267/"><strong>Year In Review</strong></a></li></ul></li><li>2025-10-23 | Spokane, WA, US | <a href="https://www.meetup.com/spokane-rust">Spokane Rust</a><ul><li><a href="https://www.meetup.com/spokane-rust/events/311346444/"><strong>October Rust Meetup: A Special Presentation and Monthly Meetups are Back!</strong></a></li></ul></li><li>2025-10-25 | Boston, MA, US | <a href="https://www.meetup.com/bostonrust">Boston Rust Meetup</a><ul><li><a href="https://www.meetup.com/bostonrust/events/310983712/"><strong>Porter Square Rust Lunch, Oct 25</strong></a></li></ul></li><li>2025-10-29 | New York, NY, US | <a href="https://www.meetup.com/rust-nyc/events/">Rust NYC</a><ul><li><a href="https://www.meetup.com/rust-nyc/events/311541108/"><strong>Rust NYC: Scalable static analysis: confronting the halting problem</strong></a></li></ul></li><li>2025-10-30 | Atlanta, GA, US | <a href="https://www.meetup.com/rust-atl">Rust Atlanta</a><ul><li><a href="https://www.meetup.com/rust-atl/events/308675988/"><strong>Rust-Atl</strong></a></li></ul></li><li>2025-10-30 | Mountain View, CA, US | <a href="https://www.meetup.com/hackerdojo/events/">Hacker Dojo</a><ul><li><a href="https://www.meetup.com/hackerdojo/events/311273832/"><strong>RUST MEETUP at HACKER DOJO</strong></a></li></ul></li><li>2025-11-01 | Boston, MA, US | <a href="https://www.meetup.com/bostonrust">Boston Rust Meetup</a><ul><li><a href="https://www.meetup.com/bostonrust/events/311039492/"><strong>Chinatown Rust Lunch, Nov 1</strong></a></li></ul></li><li>2025-11-06 | Saint Louis, MO, US | <a href="https://www.meetup.com/stl-rust/events/">STL Rust</a><ul><li><a href="https://www.meetup.com/stl-rust/events/307251982/"><strong>SIUE students on wasm 3D animations</strong></a></li></ul></li><li>2025-11-08 | Boston, MA, US | <a href="https://www.meetup.com/bostonrust/events/">Boston Rust Meetup</a><ul><li><a href="https://www.meetup.com/bostonrust/events/311039501/"><strong>Winter Hill Rust Lunch, Nov 8</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#oceania">Oceania</a></h5><ul><li>2025-10-22 | Perth, AU | <a href="https://www.meetup.com/perth-rust-meetup-group">Rust Perth Meetup Group</a><ul><li><a href="https://www.meetup.com/perth-rust-meetup-group/events/310847099/"><strong>October Meetup</strong></a></li></ul></li><li>2025-10-28 | Barton, AU | <a href="https://www.meetup.com/rust-canberra">Canberra Rust User Group</a><ul><li><a href="https://www.meetup.com/rust-canberra/events/311234237/"><strong>October Meetup</strong></a></li></ul></li></ul><h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#south-america">South America</a></h5><ul><li>2025-10-22 | Montevideo, UY | <a href="https://www.meetup.com/rust-uruguay/events/">Rust Meetup Uruguay</a><ul><li><a href="https://www.meetup.com/rust-uruguay/events/311475675/"><strong>Rust Uruguay meetup de Octubre</strong></a></li></ul></li><li>2025-10-25 | São Paulo, BR | <a href="https://www.meetup.com/rust-sao-paulo-meetup">Rust São Paulo Meetup</a><ul><li><a href="https://www.meetup.com/rust-sao-paulo-meetup/events/311084440/"><strong>Encontro do Rust-SP na Amazon Web Services</strong></a></li></ul></li><li>2025-10-30 | Florianopolis, BR | <a href="https://luma.com/calendar/cal-iOloL5ZqswCO5Mm">Rust Brasil</a><ul><li><a href="https://luma.com/lky7an18"><strong>Rust Floripa</strong></a></li></ul></li></ul><p>If you are running a Rust event please add it to the <a href="https://www.google.com/calendar/embed?src=apd9vmbc22egenmtu5l6c5jbfc%40group.calendar.google.com">calendar</a> to getit mentioned here. Please remember to add a link to the event too.Email the <a href="mailto:community-team@rust-lang.org">Rust Community Team</a> for access.</p><h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#jobs">Jobs</a></h4> <p>Please see the latest <a href="https://www.reddit.com/r/rust/comments/1nknaii/official_rrust_whos_hiring_thread_for_jobseekers/">Who's Hiring thread on r/rust</a></p><h3><a class="toclink" href="http://this-week-in-rust.org/atom.xml#quote-of-the-week">Quote of the Week</a></h3><blockquote><p>Pointers are quite hard.</p></blockquote><p>– Tim McNamara</p><blockquote><p>And, as the name implies, pointy.</p></blockquote><p>– <a href="https://www.linkedin.com/feed/update/urn:li:activity:7381109081857724416?commentUrn=urn%3Ali%3Acomment%3A%28activity%3A7381109081857724416%2C7381113605926166528%29&amp;dashCommentUrn=urn%3Ali%3Afsd_comment%3A%287381113605926166528%2Curn%3Ali%3Aactivity%3A7381109081857724416%29">llogiq on LinkedIn</a></p><p>Thanks to <a href="https://users.rust-lang.org/t/twir-quote-of-the-week/328/1721">llogiq</a> for the self-suggestion!</p><p><a href="https://users.rust-lang.org/t/twir-quote-of-the-week/328">Please submit quotes and vote for next week!</a></p><p><em>This Week in Rust is edited by: <a href="https://github.com/nellshamrell">nellshamrell</a>, <a href="https://github.com/llogiq">llogiq</a>, <a href="https://github.com/cdmistman">cdmistman</a>, <a href="https://github.com/ericseppanen">ericseppanen</a>, <a href="https://github.com/extrawurst">extrawurst</a>, <a href="https://github.com/U007D">U007D</a>, <a href="https://github.com/joelmarcey">joelmarcey</a>, <a href="https://github.com/mariannegoldin">mariannegoldin</a>, <a href="https://github.com/bennyvasquez">bennyvasquez</a>, <a href="https://github.com/bdillo">bdillo</a></em></p><p><em>Email list hosting is sponsored by <a href="https://foundation.rust-lang.org/">The Rust Foundation</a></em></p><p><small><a href="https://www.reddit.com/r/rust/comments/1o7upmn/this_week_in_rust_621/">Discuss on r/rust</a></small></p></description> <pubDate>Wed, 15 Oct 2025 04:00:00 +0000</pubDate> <dc:creator>TWiR Contributors</dc:creator></item><item> <title>The Rust Programming Language Blog: Announcing the New Rust Project Directors</title> <guid isPermaLink="true">https://blog.rust-lang.org/2025/10/15/announcing-the-new-rust-project-directors-2025/</guid> <link>https://blog.rust-lang.org/2025/10/15/announcing-the-new-rust-project-directors-2025/</link> <description><p>We are happy to announce that we have completed the annual process to elect new Project Directors.</p><p>The new Project Directors are:</p><ul><li><a href="https://github.com/davidtwco/">David Wood</a></li><li><a href="https://github.com/jackh726/">Jack Huey</a></li><li><a href="https://github.com/nikomatsakis/">Niko Matsakis</a></li></ul><p>They will join <a href="https://github.com/rylev">Ryan Levick</a> and <a href="https://github.com/carols10cents">Carol Nichols</a> to make up the five members of the Rust Foundation Board of Directors who represent the Rust Project.</p><p>We would also like to thank the outgoing going Project Directors for contributions and service:</p><ul><li><a href="https://github.com/JakobDegen">Jakob Degen</a></li><li><a href="https://github.com/spastorino">Santiago Pastorino</a></li><li><a href="https://github.com/scottmcm">Scott McMurray</a></li></ul><p>The board is made up of Project Directors, who come from and represent the Rust Project, and Member Directors, who represent the corporate members of the Rust Foundation. Both of these director groups have equal voting power.</p><p>We look forward to working with and being represented by this new group of project directors.</p><p>We were fortunate to have a number of excellent candidates and this was a difficult decision. We wish to express our gratitude to all of the candidates who were considered for this role! We also extend our thanks to the project as a whole who participated by nominating candidates and providing additional feedback once the nominees were published.</p><p>Finally, we want to share our appreciation for <a href="https://github.com/tomassedovic">Tomas Sedovic</a> for facilitating the election process. An overview of the election process can be found in a previous blog post <a href="https://blog.rust-lang.org/2023/08/30/electing-new-project-directors/">here</a>.</p></description> <pubDate>Wed, 15 Oct 2025 00:00:00 +0000</pubDate> <dc:creator>Leadership Council</dc:creator></item><item> <title>Firefox Developer Experience: Firefox WebDriver Newsletter 144</title> <guid isPermaLink="false">https://fxdx.dev/?p=515</guid> <link>https://fxdx.dev/firefox-webdriver-newsletter-144/</link> <description><p>W<em>ebDriver is a remote control interface that enables introspection and control of user agents.</em> <em>As such it</em> <em>can</em> <em>help developers to verify that their websites are working and performing well with all major browsers. The protocol is standardized by the</em><a href="https://www.w3.org/"><em> W3C</em></a><em> and consists of two separate specifications:</em><a href="https://w3c.github.io/webdriver/"><em> WebDriver classic</em></a><em> (HTTP) and the new</em><a href="https://w3c.github.io/webdriver-bidi/"><em> WebDriver BiDi</em></a><em> (Bi-Directional).</em></p> <p><em>This newsletter gives an overview of the work we’ve done as part of the Firefox 144 release cycle</em>.</p> <h3>Contributions</h3> <p>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.</p> <p>WebDriver code is written in JavaScript, Python, and Rust so any web developer can contribute! Read<a href="https://firefox-source-docs.mozilla.org/devtools/getting-started/README.html"> how to setup the work environment</a> and check<a href="https://codetribute.mozilla.org/projects/automation"> the list of mentored issues</a> for Marionette, or the<a href="https://codetribute.mozilla.org/languages/javascript?project%3DWebDriver%2520BiDi"> list of mentored JavaScript bugs for WebDriver BiDi</a>. Join<a href="https://chat.mozilla.org/#/room/#webdriver:mozilla.org"> our chatroom</a> if you need any help to get started!</p> <h3>WebDriver BiDi</h3> <ul><li>Implemented the new <a href="https://bugzil.la/1874365"><code>browsingContext.downloadWillBegin</code> event</a>, which is emitted when a new download is initiated, either by clicking a link with the <code>download</code> attribute, or in response to a network request with a <code>Content-Disposition</code> header indicating a file attachment.</li> <li>Implemented the new <a href="https://bugzil.la/1974167"><code>emulation.setScreenOrientationOverride</code> command</a>, which allows clients to emulate different screen orientations. This command is not limited to mobile devices, but also works for desktop applications.</li> <li>Implemented the new <a href="https://bugzil.la/1978027"><code>emulation.setTimezoneOverride</code> command</a>, which allows clients to simulate a specific timezone setting.</li> <li>Enhanced the <a href="https://bugzil.la/1983807"><code>emulation.setLocaleOverride</code> command</a> to also apply the specified settings to sandboxes previously created via WebDriver BiDi.</li> <li>Fixed a bug where <a href="https://bugzil.la/1980211">the locale override set via <code>emulation.setLocaleOverride</code> was sometimes incorrectly shared between different browsing contexts within the same process</a>.</li> <li><a href="https://bugzil.la/1914407">Enhanced the <code>browsingContext.navigate</code> command to avoid <code>NS_BINDING_ABORTED</code> errors</a> caused by redirects or interruptions occurring after the navigation was already committed.</li></ul> <h3>Marionette</h3> <ul><li><a href="https://bugzil.la/1986238">Reverted the <code>Scroll Into View</code> WebDriver algorithm as used by several WebDriver classic commands in Marionette to always use the <code>instant</code> scroll behavior</a>. This undoes the change introduced in Firefox 97, which had switched the behavior to <code>auto</code>. The reversion addresses potential race conditions when scrolling elements that use <code>smooth</code> behavior.</li></ul></description> <pubDate>Tue, 14 Oct 2025 13:25:20 +0000</pubDate> <dc:creator>Henrik Skupin</dc:creator></item><item> <title>The Mozilla Blog: Choose how you search and stay organized with Firefox</title> <guid isPermaLink="false">https://blog.mozilla.org/?p=82237</guid> <link>https://blog.mozilla.org/en/firefox/firefox-144/</link> <description><figure class="wp-block-image size-large is-style-default"><img alt="llustration showing Firefox’s browser interface with a focus on search options. A bar labeled “Use visual search” overlaps an image of a floral painting, while another option labeled “with the Perplexity icon” appears below it. A small browser window shows a cropped view of the same artwork. The Firefox toolbar is visible at the bottom with a highlighted smiley face icon. The background is a gradient of purple and blue with grid lines and sparkles, conveying a playful, tech-inspired design." class="wp-image-82258" height="576" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/Firefox-ProfileManagement-1920x1080-Static-v1.3-Dark2-1024x576.png" width="1024" /></figure> <p>At Mozilla, we build Firefox around one principle: putting you in control. With today’s release, we’re introducing new features that make browsing smarter and more personal while staying true to the values you care about most: privacy and choice.</p> <h3><strong>A new option for search, still on your terms.</strong></h3> <p>Earlier this year, we gave you more choice in how you search by <a href="https://connect.mozilla.org/t5/discussions/try-out-perplexity-ai-search-in-firefox-139/m-p/98352">testing</a> <a href="https://www.perplexity.ai/">Perplexity</a>, an AI-powered answer engine, as a search option on Firefox. Now, after positive feedback, we’re making it a fixture, rolling it out to more users for desktop. Perplexity provides conversational answers with citations, so you can validate information without digging through pages of results.</p> <p>This addition reflects our shared commitment to choice: You decide when to use an AI answer engine, or if you want to use it at all. Available globally, Perplexity can be found in the unified search button in the address bar. We’ll be bringing Perplexity to mobile in the coming months. And as always, privacy matters – <a href="https://www.perplexity.ai/hub/legal/privacy-policy">Perplexity</a> maintains strict prohibitions against selling or sharing personal data.</p> <h3><strong>Organize your life with profiles</strong></h3> <p class="has-text-align-left">At the beginning of the year, we started <a href="https://connect.mozilla.org/t5/discussions/try-out-firefox-profiles-in-nightly/m-p/84223">testing</a> <a href="https://blog.mozilla.org/en/firefox/profile-management/">profiles</a> — a way to create and switch between different browsing setups. After months of gradual rollout and <a href="https://blog.mozilla.org/en/firefox/shifting-left-for-better-accessibility/">community feedback</a>, profiles are now <a href="https://blog.mozilla.org/en/firefox/profile-management/">available</a> to everyone.</p> <div class="wp-block-image is-style-default"><figure class="aligncenter size-large is-resized"><img alt="Firefox Profiles feature shown with an illustration of three foxes and a setup screen for creating and customizing browser profiles." class="wp-image-82095" height="576" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/firefox-profiles-1024x576.png" style="width: 675px;" width="1024" />&lt;figcaption class="wp-element-caption"&gt;<em>Create and switch between different browsing setups</em>&lt;/figcaption&gt;</figure></div> <p>Profiles let you keep work tabs distinct from personal browsing, or dedicate a setup to testing extensions or managing a specific project. Each profile runs independently, giving you flexibility and focus. Feedback from students, professionals and contributors helped us refine this feature into the version you see today.</p> <h3><strong>Discover more with visual search</strong></h3> <p>In September, we <a href="https://connect.mozilla.org/t5/discussions/new-in-firefox-desktop-only-visual-search/m-p/106216">announced</a> visual search on <a href="https://connect.mozilla.org/">Mozilla Connect</a> and began rolling it out for testing. Powered by Google Lens, it lets you search what you see with a simple right-click on any image.</p> <div class="wp-block-image"><figure class="aligncenter size-full"><img alt="" class="wp-image-82248" height="396" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/image.png" width="464" />&lt;figcaption class="wp-element-caption"&gt;<em>Search what you see with a simple right-click on an image</em>&lt;/figcaption&gt;</figure></div> <p>You can:</p> <ul><li>Find similar products, places or objects </li> <li>Copy, translate or search text from images</li> <li>Get inspiration for learning, travel or research</li></ul> <p>This desktop-only feature makes searching more intuitive and curiosity-driven. For now, it requires Google as your default search engine. Tell us what you think. Your feedback will guide where visual search appears next, from the address bar to mobile.</p> <h3><strong>Evolving to meet your needs</strong></h3> <p>Today’s release brings more ways to browse on your terms — from smarter search with Perplexity, to profiles that let you separate work from play, to visual search.</p> <p>Each of these features reflects what matters most to us: putting you in control of your online experience and building alongside the community that inspires Firefox. With your feedback, we’ll keep shaping a browser that not only keeps pace with the future of the web but also stays true to the open values you trust.</p> <p>We’re excited to see how you use what’s new, and can’t wait to share what’s next.</p> <a class="ft-c-inline-cta" href="https://www.mozilla.org/firefox/new/?utm_source=blog.mozilla.org&amp;utm_medium=referral&amp;utm_campaign=blog-nav"> <div class="ft-c-inline-cta__media"> <img alt="" class="attachment-1x1 size-1x1" height="800" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2021/10/Visual-Guidelines-800x800.png" width="800" /> </div> <div class="ft-c-inline-cta__content"> <h4>Take control of your internet</h4> <span>Download Firefox</span> </div></a><p>The post <a href="https://blog.mozilla.org/en/firefox/firefox-144/">Choose how you search and stay organized with Firefox</a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p></description> <pubDate>Tue, 14 Oct 2025 13:00:00 +0000</pubDate> <dc:creator>Jenifer Boscacci</dc:creator></item><item> <title>Niko Matsakis: We need (at least) ergonomic, explicit handles</title> <guid isPermaLink="false">https://smallcultfollowing.com/babysteps/blog/2025/10/13/ergonomic-explicit-handles/</guid> <link>https://smallcultfollowing.com/babysteps/blog/2025/10/13/ergonomic-explicit-handles/?utm_source=atom_feed</link> <description><p>Continuing my discussion on Ergonomic RC, I want to focus on the core question: <strong>should users have to explicitly invoke handle/clone, or not?</strong> This whole “Ergonomic RC” work was originally proposed by <a href="https://dioxuslabs.com/">Dioxus</a> and their answer is simple: <strong>definitely not</strong>. For the kind of high-level GUI applications they are building, having to call <code>cx.handle()</code> to clone a ref-counted value is pure noise. For that matter, for a lot of Rust apps, even cloning a string or a vector is no big deal. On the other hand, for a lot of applications, the answer is <strong>definitely yes</strong> – knowing where handles are created can impact performance, memory usage, and even correctness (don’t worry, I’ll give examples later in the post). So how do we reconcile this?</p><p><strong>This blog argues that we should make it ergonomic to be explicit</strong>. This wasn’t always my position, but after an impactful conversation with Josh Triplett, I’ve come around. I think it aligns with what I once called the <a href="https://smallcultfollowing.com/babysteps//blog/2022/09/18/dyn-async-traits-part-8-the-soul-of-rust/">soul of Rust</a>: we want to be ergonomic, yes, but we want to be <strong>ergonomic while giving control</strong><sup id="fnref:1"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:1">1</a></sup>.</p><p>I like Tyler Mandry’s <a href="https://tmandry.gitlab.io/blog/posts/the-main-thing/"><em>Clarity of purpose</em></a> contruction, <em>“Great code brings only the important characteristics of your application to your attention”</em>. The key point is that <em>there is great code in which cloning and handles are important characteristics</em>, so we need to make that code possible to express nicely. This is particularly true since Rust is one of the very few languages that really targets that kind of low-level, foundational code.</p><p><strong>This does not mean we cannot (later) support automatic clones and handles.</strong> It’s inarguable that this would benefit clarity of purpose for a lot of Rust code. But I think we should focus <em>first</em> on the harder case, the case where explicitness is needed, and <strong>get that as nice as we can</strong>; then we can circle back and decide whether to also support something automatic. One of the questions for me, in fact, is whether we can get “fully explicit” to be <em>nice enough</em> that we don’t really need the automatic version. There are benefits from having “one Rust”, where all code follows roughly the same patterns, where those patterns are perfect some of the time, and don’t suck too bad<sup id="fnref:2"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:2">2</a></sup> when they’re overkill.</p><h3>“Rust should not surprise you.” (hat tip: Josh Triplett)</h3><p>I mentioned this blog post resulted from a long conversation with Josh Triplett<sup id="fnref:3"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:3">3</a></sup>. The key phrase that stuck with me from that conversation was: <em>Rust should not surprise you</em>. The way I think of it is like this. Every programmer knows what its like to have a marathon debugging session – to sit and state at code for days and think, <em>but… how is this even POSSIBLE?</em> Those kind of bug hunts can end in a few different ways. Occasionally you uncover a deeply satisfying, subtle bug in your logic. More often, you find that you wrote <code>if foo</code> and not <code>if !foo</code>. And <em>occasionally</em> you find out that your language was doing something that you didn’t expect. That some simple-looking code concealed a subltle, complex interaction. People often call this kind of a <em>footgun</em>.</p><p>Overall, Rust is <em>remarkably</em> good at avoiding footguns<sup id="fnref:4"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:4">4</a></sup>. And part of how we’ve achieved that is by making sure that things you might need to know are visible – like, explicit in the source. Every time you see a Rust match, you don’t have to ask yourself “what cases might be missing here” – the compiler guarantees you they are all there. And when you see a call to a Rust function, you don’t have to ask yourself if it is fallible – you’ll see a <code>?</code> if it is.<sup id="fnref:5"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:5">5</a></sup></p><h4>Creating a handle can definitely “surprise” you</h4><p>So I guess the question is: <em>would you ever have to know about a ref-count increment</em>? The trick part is that the answer here is application dependent. For some low-level applications, definitely yes: an atomic reference count is a measurable cost. To be honest, I would wager that the set of applications where this is true are vanishingly small. And even in those applications, Rust already improves on the state of the art by giving you the ability to choose between <code>Rc</code> and <code>Arc</code> <em>and then proving that you don’t mess it up</em>.</p><p>But there are other reasons you might want to track reference counts, and those are less easy to dismiss. One of them is memory leaks. Rust, unlike GC’d languages, has <em>deterministic destruction</em>. This is cool, because it means that you can leverage destructors to manage all kinds of resources, as Yehuda wrote about long ago in his classic ode-to-<a href="https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization">RAII</a> entitled <a href="https://blog.skylight.io/rust-means-never-having-to-close-a-socket/">“Rust means never having to close a socket”</a>. But although the points where handles are created and destroyed is deterministic, the nature of reference-counting can make it much harder to predict when the underlying resource will actually get freed. And if those increments are not visible in your code, it is that much harder to track them down.</p><p>Just recently, I was debugging <a href="http://smallcultfollowing.com/babysteps/atom.xml">Symposium</a>, which is written in Swift. Somehow I had two <code>IPCManager</code> instances when I only expected one, and each of them was responding to every IPC message, wreaking havoc. Poking around I found stray references floating around in some surprising places, which was causing the problem. Would this bug have still occurred if I had to write <code>.handle()</code> explicitly to increment the ref count? Definitely, yes. Would it have been easier to find after the fact? Also yes.<sup id="fnref:6"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:6">6</a></sup></p><p>Josh gave me a similar example from <a href="https://docs.rs/bytes/latest/bytes/">the “bytes” crate</a>. A <a href="https://docs.rs/bytes/latest/bytes/struct.Bytes.html"><code>Bytes</code></a> type is a <a href="https://smallcultfollowing.com/babysteps/ /blog/2025/10/07/the-handle-trait/">handle</a> to a slice of some underlying memory buffer. When you clone that handle, it will keep the entire backing buffer around. Sometimes you might prefer to copy your slice out into a separate buffer so that the underlying buffer can be freed. It’s not that hard for me to imagine trying to hunt down an errant handle that is keeping some large buffer alive and being very frustrated that I can’t see explicitly in the where those handles are created.</p><p>A similar case occurs with APIs like like <code>Arc::get_mut</code><sup id="fnref:7"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:7">7</a></sup>. <code>get_mut</code> takes an <code>&amp;mut Arc&lt;T&gt;</code> and, if the ref-count is 1, returns an <code>&amp;mut T</code>. This lets you take a <em>shareable</em> handle that <em>you</em> know is not actually <em>being</em> shared and recover uniqueness. This kind of API is not frequently used – but when you need it, it’s so nice it’s there.</p><h3>“What I love about Rust is its versatility: low to high in one language” (hat tip: Alex Crichton)</h3><p>Entering the conversation with Josh, I was leaning towards a design where you had some form of automated cloning of handles and an allow-by-default lint that would let crates which <em>don’t</em> want that turn it off. But Josh convinced me that there is a significant class of applications that want handle creation to be ergonomic AND visible (i.e., explicit in the source). Low-level network services and even things like Rust For Linux likely fit this description, but any Rust application that uses <code>get_mut</code> or <code>make_mut</code> might also.</p><p>And this reminded me of something Alex Crichton once said to me. Unlike the other quotes here, it wasn’t in the context of ergonomic ref-counting, but rather when I was working on my first attempt at the <a href="https://smallcultfollowing.com/babysteps/blog/2021/09/08/rustacean-principles/">“Rustacean Principles”</a>. Alex was saying that he loved how Rust was great for low-level code but also worked well high-level stuff like CLI tools and simple scripts.</p><p>I feel like you can interpret Alex’s quote in two ways, depending on what you choose to emphasize. You could hear it as, “It’s important that Rust is good for high-level use cases”. That is true, and it is what leads us to ask whether we should even make handles visible at all.</p><p>But you can also read Alex’s quote as, “It’s important that there’s one language that works well enough for <em>both</em>” – and I think that’s true too. The “true Rust gestalt” is when we manage to <em>simultaneously</em> give you the low-level control that grungy code needs but wrapped in a high-level package. This is the promise of zero-cost abstractions, of course, and Rust (in its best moments) delivers.</p><h4>The “soul of Rust”: low-level enough for a kernel, usable enough for a GUI</h4><p>Let’s be honest. High-level GUI programming is not Rust’s bread-and-butter, and it never will be; users will never confuse Rust for TypeScript. But then, TypeScript will never be in the Linux kernel.</p><p>The goal of Rust is to be a single language that can, by and large, be “good enough” for <em>both</em> extremes. <strong>The goal is make enough low-level details visible for kernel hackers but do so in a way that is usable enough for a GUI.</strong> It ain’t easy, but it’s the job.</p><p>This isn’t the first time that Josh has pulled me back to this realization. The last time was in the context of async fn in dyn traits, and it led to a blog post talking about the <a href="https://smallcultfollowing.com/babysteps/blog/2022/09/18/dyn-async-traits-part-8-the-soul-of-rust/">“soul of Rust”</a> and a <a href="https://smallcultfollowing.com/babysteps/blog/2022/09/19/what-i-meant-by-the-soul-of-rust/">followup going into greater detail</a>. I think the catchphrase “low-level enough for a Kernel, usable enough for a GUI” kind of captures it.</p><h4>Conclusion: Explicit handles should be the first step, but it doesn’t have to be the final step</h4><p>There is a slight caveat I want to add. I think another part of Rust’s soul is <em>preferring nuance to artificial simplicity</em> (“as simple as possible, but no simpler”, as they say). And I think the reality is that there’s a huge set of applications that make new handles left-and-right (particularly but not exclusively in async land<sup id="fnref:8"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:8">8</a></sup>) and where explicitly creating new handles is noise, not signal. This is why e.g. Swift<sup id="fnref:9"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:9">9</a></sup> makes ref-count increments invisible – and they get a big lift out of that!<sup id="fnref:10"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:10">10</a></sup> I’d wager most Swift users don’t even realize that Swift is not garbage-collected<sup id="fnref:11"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:11">11</a></sup>.</p><p>But the key thing here is that even if we do add some way to make handle creation automatic, we ALSO want a mode where it is explicit and visible. So we might as well do that one first.</p><p>OK, I think I’ve made this point 3 ways from Sunday now, so I’ll stop. The next few blog posts in the series will dive into (at least) two options for how we might make handle creation and closures more ergonomic while retaining explicitness.</p><div class="footnotes"><hr /><ol><li id="fn:1"><p>I see a potential candidate for a design axiom… <em>rubs hands with an evil-sounding cackle and a look of glee</em> <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:1">↩︎</a></p></li><li id="fn:2"><p><a href="https://youtu.be/JMFS9lrVd64?si=BdaDNm7rIueS0Jlx&amp;t=71">It’s an industry term</a>. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:2">↩︎</a></p></li><li id="fn:3"><p>Actually, by the standards of the conversations Josh and I often have, it was’t really all that long – an hour at most. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:3">↩︎</a></p></li><li id="fn:4"><p>Well, at least <em>sync</em> Rust is. I think async Rust has more than its share, particularly around cancellation, but that’s a topic for another blog post. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:4">↩︎</a></p></li><li id="fn:5"><p>Modulo panics, of course – and no surprise that accounting for panics is a major pain point for some Rust users. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:5">↩︎</a></p></li><li id="fn:6"><p>In this particular case, it was fairly easy for me to find regardless, but this application is very simple. I can definitely imagine ripgrep’ing around a codebase to find all increments being useful, and that would be much harder to do without an explicit signal they are occurring. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:6">↩︎</a></p></li><li id="fn:7"><p>Or <code>Arc::make_mut</code>, which is one of my favorite APIs. It takes an <code>Arc&lt;_&gt;</code> and gives you back mutable (i.e., unique) access to the internals, always! How is that possible, given that the ref count may not be 1? Answer: if the ref-count is not 1, then it clones it. This is perfect for copy-on-write-style code. So beautiful. 😍 <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:7">↩︎</a></p></li><li id="fn:8"><p>My experience is that, due to language limitations we really should fix, many async constructs force you into <code>'static</code> bounds which in turn force you into <code>Rc</code> and <code>Arc</code> where you’d otherwise have been able to use <code>&amp;</code>. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:8">↩︎</a></p></li><li id="fn:9"><p>I’ve been writing more Swift and digging it. I have to say, I love how they are not afraid to “go big”. I admire the ambition I see in designs like SwiftUI and their approach to async. I don’t think they bat 100, but it’s cool they’re swinging for the stands. I want Rust to <a href="https://smallcultfollowing.com/babysteps/ /blog/2022/02/09/dare-to-ask-for-more-rust2024/">dare to ask for more</a>! <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:9">↩︎</a></p></li><li id="fn:10"><p>Well, not <em>only</em> that. They also allow class fields to be assigned when aliased which, to avoid stale references and iterator invalidation, means you have to move everything into ref-counted boxes and adopt persistent collections, which in turn comes at a performance cost and makes Swift a harder sell for lower-level foundational systems (though by no means a non-starter, in my opinion). <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:10">↩︎</a></p></li><li id="fn:11"><p>Though I’d also wager that many eventually find themselves scratching their heads about a ref-count cycle. I’ve not dug into how Swift handles those, but I see references to “weak handles” flying around, so I assume they’ve not (yet?) adopted a cycle collector. To be clear, you can get a ref-count cycle in Rust too! It’s harder to do since we discourage interior mutability, but not that hard. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:11">↩︎</a></p></li></ol></div></description> <pubDate>Mon, 13 Oct 2025 11:39:16 +0000</pubDate></item><item> <title>Mozilla Thunderbird: State of the Thunder 13: How We Make Our Roadmap</title> <guid isPermaLink="false">https://blog.thunderbird.net/?p=3885</guid> <link>https://blog.thunderbird.net/2025/10/state-of-the-thunder-13-how-we-make-our-roadmap/</link> <description><p><img alt="" class="attachment-640x360 size-640x360 wp-post-image" height="360" src="https://blog.thunderbird.net/files/2025/10/Blog-banner-State-of-the-Thunder-768x432.png" width="640" /></p><p>Welcome back to our thirteenth episode of State of the Thunder! Nothing unlucky about this latest installment, as Managing Director Ryan Sipes walks us through how Thunderbird creates its roadmap. Unlike other companies where roadmaps are driven solely by business needs, Thunderbird is working with our community governance and feedback from the wider user community to keep us honest even as we move forward. </p> <p>Want to find out how to join future State of the Thunders? Be sure to join our <a href="https://thunderbird.topicbox.com/groups/planning">Thunderbird planning mailing list</a> for all the details. </p> <h3>Open Source, Open Roadmaps</h3> <p>In other companies, product managers tend to draft roadmaps based on business needs. Publishing that roadmap might be an afterthought, or might not happen at all. Thunderbird, however, is open source, so that’s not our process.</p> <p>A quick history lesson provides some needed context. Eight years ago, Thunderbird was solely a community project driven by a community council. We didn’t have a roadmap like we do today. With the earlier loss of funding and support, the project was in triage mode. Since then, thanks to a wonderful user community who has donated their skill, time, and money, we’ve changed our roadmap process.</p> <p>The Supernova release (Thunderbird 115) was where we first really focused on making a roadmap with a coherent product vision: a modernized app in performance and appearance. We developed this roadmap with input from the community, even if there was pushback to a UI change.</p> <h3>The 2026 Roadmap Process</h3> <p>At this point, the project has bylaws for the roadmap process, which unites the Thunderbird Council, MZLA staff, and user feedback. Over the past year we’ve added two new roadmaps: one for the Android app and another for ThunderbirdPro. (Note, iOS doesn’t have a roadmap yet. Our current goal is: let’s be able to receive email!) But even with these changes and additions, the <a href="https://www.mozilla.org/en-US/about/manifesto/">Mozilla Manifesto</a> is still at the heart of everything we do. We firmly believe that making roadmaps with community governance and feedback from the larger community keeps us honest and helps us make products that genuinely improve people’s lives.</p> <p>Want to see how our 2025-2026 Roadmaps are taking shape? Check out the <a href="https://developer.thunderbird.net/planning/roadmap">Desktop Roadmap</a>, as well the mobile roadmaps for <a href="https://developer.thunderbird.net/planning/android-roadmap">Android</a> and <a href="https://developer.thunderbird.net/planning/ios-roadmap">iOS</a>.</p> <h3>Questions</h3> <h4>Integrating Community Contributions</h4> <p>In the past, community contributors have picked up “nice to have” issues and developed them alongside us. Or people want to pursue problems or challenges that affect them the most. Sometimes, either of these scenarios coincide with our roadmap, and we get features like the new drag and drop folders! </p> <p>Needless to say, we love when the community helps us get the product where we hope it will go. Sometimes, we have to pause development because of shifted priorities, and we’re trying to get better at updating contributors when these shifts happen on places like the <a href="https://thunderbird.topicbox.com/groups/planning">tb-planning</a> and <a href="https://thunderbird.topicbox.com/groups/mobile-planning">mobile-planning</a> mailing lists.</p> <p>And these community contributions aren’t just code! Testing is a crucial way to help make Thunderbird shine on desktop and mobile. Community suggestions on Mozilla Connect help us dream big, as we discussed in the last two episodes. Reporting bugs, either on <a href="https://bugzilla.mozilla.net">Bugzilla</a> for the desktop app or <a href="https://github.com/thunderbird/thunderbird-android/issues/">GitHub</a> for the Android app, help us know when things aren’t working. We encourage our community to learn more <a href="https://council.thunderbird.net/">about the Council</a>, and don’t be afraid to get in touch with them at council@thunderbird.net.</p> <h4>Telemetry and the Roadmap</h4> <p>While we know there are passionate debates on telemetry in the open source community, we want to mention how respectful telemetry can make Thunderbird better. Our telemetry helps us see what features are important, and which ones just clutter up the UI. We don’t collect Personally Identifying Information (PII), and our code is open so you can check us on this. Unlike Outlook, who shares their data with 801 partners, we don’t. You can read all about what we use and how we use it <a href="https://www.thunderbird.net/privacy/">here</a>.</p> <p>So if you have telemetry turned off, please, we ask you to turn it on, and if it’s already on, to keep it on! Especially if you’re a Linux user, enabling telemetry helps us have a better gauge of our Linux user base and how to best support you.</p> <h4>Roadmap Categories and Organizing</h4> <p>Should we try to ‘bucket’ similar items on our roadmap and spread development evenly between them, or should we concentrate on the bucket that needs it most? The answer to this question depends on who you ask! Sometimes we’re focused on a particular area of focus, like UI work in Supernova and current UX work in Calendar. Sometimes we’re working to pay down tech debt across our code. That effort in reducing tech debt can pave the way for future work, like the current efforts to modernize our database so we can have a true Conversation View and other features. Sometimes roadmaps reveal obstacles you have to overcome, and Ryan thinks we’re getting faster at this.</p> <h3>Where to see the roadmaps</h3> <p>The current desktop roadmap is <a href="https://developer.thunderbird.net/planning/roadmap">here</a>, while the current Android roadmap is on our <a href="https://github.com/orgs/thunderbird/projects/19">GitHub repo</a>. In the future, we’re hoping to update where these roadmaps live, how they look, and how you can interact with them. (Ryan is particularly partial to <a href="https://obsidian.md/roadmap/">Obsidian’s roadmap.</a>) We ultimately want our roadmaps to be storytelling devices, and to keep them more updated to any recent changes.</p> <h3>Current Calls for Involvement</h3> <p>Join us for the last few days of <a href="https://thunderbird.topicbox.com/groups/planning/T00a28d546ed1b7d1/ews-in-thunderbird-144-0b1-call-for-testing">testing EWS mail support</a>! Also, we had a fantastic time with the Ask a Fox replython, and would love if you helped us <a href="https://blog.thunderbird.net/2024/08/video-how-to-answer-thunderbird-questions-on-mozilla-support/">answer support questions</a> on <a href="https://support.mozilla.org">SUMO</a>.</p> <h3>Watch the Video (also on <a href="https://tilvids.com/w/mvHZHm2JXzbrxwMBvLDorc">PeerTube</a>)</h3> <figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper"> </div></figure> <h3>Listen to the Podcast</h3> <p></p><p>The post <a href="https://blog.thunderbird.net/2025/10/state-of-the-thunder-13-how-we-make-our-roadmap/">State of the Thunder 13: How We Make Our Roadmap</a> appeared first on <a href="https://blog.thunderbird.net">The Thunderbird Blog</a>.</p></description> <pubDate>Fri, 10 Oct 2025 18:37:37 +0000</pubDate> <dc:creator>Monica Ayhens-Madon</dc:creator></item><item> <title>The Mozilla Blog: Shake to Summarize recognized with special mention in TIME’s Best Inventions of 2025</title> <guid isPermaLink="false">https://blog.mozilla.org/?p=82133</guid> <link>https://blog.mozilla.org/en/firefox/shake-to-summarize-time-best-inventions/</link> <description><figure class="wp-block-image size-large"><img alt="Illustration featuring a TIME magazine cover titled “Best Inventions of 2025,” showing a humanoid robot folding clothes, alongside a smartphone displaying the Firefox logo and a screen reading “Summarizing…” with a dessert recipe below it." class="wp-image-82134" height="576" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/Blog-Header-3-1024x576.png" width="1024" />&lt;figcaption class="wp-element-caption"&gt;Cover credit: Photography by Spencer Lowell for TIME&lt;/figcaption&gt;</figure> <p><em>Shake to Summarize has been recognized with a <a href="https://time.com/collections/best-inventions-special-mentions/7320805/firefox-shake-to-summarize/" rel="noreferrer noopener" target="_blank"><strong>Special Mention</strong></a> in<strong> </strong><a href="https://time.com/collections/best-inventions-2025/" rel="noreferrer noopener" target="_blank"><strong>TIME’s Best Inventions of 2025</strong></a>.</em></p> <p>Each year TIME<strong> </strong>spotlights a range of new industry-defining innovations across consumer electronics, health tech, apps and beyond. This year, <a href="https://blog.mozilla.org/firefox/shake-to-summarize/" rel="noreferrer noopener" target="_blank">Firefox’s Shake to Summarize feature</a> made the list for bringing a smart solution to a modern user problem: information overload. </p> <p>With a single shake or tap, users on iOS devices can get to the heart of an article in seconds. The cool part? Summaries adapt to what you’re reading: recipes pull out the steps for cooking, sports focus on game scores and stats, and news highlights the key takeaways from a story.</p> <p>“We’re thrilled to see Firefox earn a TIME Best Inventions 2025 Special Mention! Our work on Shake to Summarize reflects how Firefox is evolving,” said <a href="https://blog.mozilla.org/en/firefox/promoted/" rel="noreferrer noopener" target="_blank">Anthony Enzor-DeMeo</a>, general manager of Firefox. “We’re reimagining our browser to fit seamlessly into modern life, helping people browse with less clutter and more focus. The feature is also part of our efforts to give mobile users a cleaner UI and smarter tools that make browsing on the go fast, seamless, and even fun.”</p> <figure class="wp-block-embed aligncenter is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper"> </div></figure> <p>Launched in September 2025 and currently available to English-language users in the U.S., Shake to Summarize generates summaries using Apple Intelligence on iPhone 15 Pro or later running iOS 26 or above, and Mozilla-hosted AI for other devices running iOS 16 or above.</p> <p>“This recognition is a testament to the incredible work of our UX, design, product, and engineering teams who brought this innovation to life, showcasing that Firefox continues to lead with purpose, creativity, and a deep commitment to user-centric design. Big thank you!” added Enzor-DeMeo.</p> <p>The Firefox team is working on making the feature available to more users and for those on Android. In the meantime, iOS users can already make the most of Shake to Summarize available in the <a href="https://apps.apple.com/us/app/firefox-private-web-browser/id989804926?ppid=908b3bb9-aa78-4a60-8f7f-2407cd3227bc" rel="noreferrer noopener" target="_blank">Apple app store</a> now.</p> <a class="ft-c-inline-cta" href="https://www.mozilla.org/firefox/new/?utm_source=blog.mozilla.org&amp;utm_medium=referral&amp;utm_campaign=blog-nav"> <div class="ft-c-inline-cta__media"> <img alt="" class="attachment-1x1 size-1x1" height="800" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2021/10/Visual-Guidelines-800x800.png" width="800" /> </div> <div class="ft-c-inline-cta__content"> <h3>Take control of your internet</h3> <span>Download Firefox</span> </div></a><p>The post <a href="https://blog.mozilla.org/en/firefox/shake-to-summarize-time-best-inventions/">Shake to Summarize recognized with special mention in TIME’s Best Inventions of 2025</a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p></description> <pubDate>Thu, 09 Oct 2025 14:28:43 +0000</pubDate> <dc:creator>Christina Petrova</dc:creator></item><item> <title>Mozilla Thunderbird: State Of The Bird 2024/25</title> <guid isPermaLink="false">https://blog.thunderbird.net/?p=3844</guid> <link>https://blog.thunderbird.net/2025/10/state-of-the-bird-2024-25/</link> <description><p><img alt="" class="attachment-640x360 size-640x360 wp-post-image" height="360" src="https://blog.thunderbird.net/files/2025/10/Annual-Report4-768x432.jpg" width="640" /></p><p>The past twelve months have been another remarkable chapter in Thunderbird’s journey. Together, we started expanding Thunderbird beyond its strong desktop roots, introducing it to smartphones and web browsers to make it more accessible to more people. Thunderbird for Android arrived in the fall and has been steadily improving thanks to our growing mobile team, as well as feedback and contributions from our growing global family. A few months later, in December 2024, we celebrated an extraordinary milestone: 20 years of Thunderbird! We also looked toward a sustainable future with the announcement of Thunderbird Pro, with one of its first services, Appointment, already finding an audience in closed beta. </p> <p>The past year also saw a shift in how Thunderbird evolves. Although we recently released our latest annual ESR update (codenamed Eclipse), the bigger news is that our team built the new Monthly Release channel, which is now the default for most of you. This change means you’ll see more frequent updates that make Thunderbird feel fresher, more responsive, and more in tune with your personalized needs. <br />Before diving into all the details, I want to pause and express our deepest gratitude to the incredible global community that makes all of this possible. To the hundreds of thousands of people who donated financially, the volunteers who contributed their time and expertise, and the beta testers who carefully helped us polish each update: thank you! Thunderbird <em>thrives</em> because of you. Every milestone we celebrate is a shared achievement, and a shining example of the power of community-driven, open source software development.</p> <div class="wp-block-spacer" style="height: 59px;"></div> <h3><strong>Team and Product Updates</strong></h3> <h4><strong>Desktop and release updates</strong></h4> <p>In December 2024, we celebrated Thunderbird’s 20th anniversary. Two decades of proving that email software can be both powerful and principled was not without its ups and downs, but that milestone reaffirmed something we hear so often from our community: Thunderbird continues to matter deeply to people all over the world. </p> <p>One of the biggest changes this year was the introduction of a new monthly release channel, simply called “Thunderbird Release.” Making this shift required an enormous amount of coordination and care across our desktop and release teams. Unlike the long-standing Extended Support Release (ESR), which provides a single major update every July, the new Thunderbird Release delivers monthly updates. This approach means we can bring you useful improvements and new features significantly faster, while keeping the stability and reliability you rely on.</p> <p>Over the past year, our desktop team focused heavily on introducing changes that people have been asking for. Specifically, changes that make Thunderbird feel more efficient, intuitive, and modern. We improved visual consistency across system themes, gave you more ways to control the appearance of your message lists and how they’re organized, modernized notifications with native OS integration and quick actions, and moved closer to full Microsoft Exchange support. </p> <p>Many of you who switched from the ESR to the new Thunderbird Release channel started seeing these updates as early as April. For those who stuck with the ESR, the annual update, codenamed Eclipse, arrived in July. Thanks to the solid foundation established in those smaller monthly updates, Eclipse enjoyed the smoothest rollout of any annual release in Thunderbird’s history. </p> <p><em>In-depth details on Desktop development can be found in our monthly </em><a href="https://blog.thunderbird.net/tag/development-digest/"><em>Developer Digest</em></a><em> updates on our blog. </em></p> <h4><strong>Thunderbird Mobile</strong></h4> <h5>Android</h5> <p>It took longer than we originally anticipated, but Thunderbird has finally arrived as a true smartphone app. The launch of Thunderbird for Android in October 2024 was one of our most exciting steps forward in years. Releasing it took more than two years of active development, beta testing, and invaluable community feedback. </p> <p>This milestone was made possible by transforming the much-loved K-9 Mail app into something we could proudly call Thunderbird. That process included a full redesign of the interface, including bringing it up to modern design standards, and building an easy way for people to bring their existing Thunderbird desktop accounts directly into the Android app.</p> <p>We’ve been encouraged by the enthusiastic response to Thunderbird on Android, but we’re also listening closely to your feedback. Our team, together with community contributors, has one very focused goal: to make Thunderbird the best Android email app available. </p> <h5>iOS</h5> <p>We’ve also seen the overwhelming demand to build a version of Thunderbird for the iOS community. Unlike the Android app, the iOS app is being built from the ground up. </p> <p>Fortunately, Thunderbird for iOS took some major steps forward this year. We published the initial repository (a central location for open-source project files and code) for the Thunderbird mobile team and contributors to work together, and we’re laying the groundwork for public testing. </p> <p>Our goal for the first public alpha will be to support manual account setup and basic inbox viewing to meet Apple’s minimum review standards. These early pre-release versions will be distributed through TestFlight, allowing Thunderbird for iOS to benefit from your real-world feedback. </p> <p>When we started building Thunderbird for iOS, a core decision was made to use a modern foundation (JMAP) designed for mobile devices. This will allow for, among other advantages, faster mail synchronization and more efficient resource usage. The first pieces of that foundation are already in place, with the basic ability to view folders and messages. We’ve also set up internal tools that will make regular updates, language translations, and community testing possible. </p> <p>Thunderbird for iOS is still in the early stages of development, but momentum is strong, our team is growing, and we’re confidently moving toward the first community-accessible release. </p> <p><em>In depth details on mobile development can be found in our monthly </em><a href="https://blog.thunderbird.net/tag/android-progress-report/"><em>Mobile Progress Report</em></a><em> on our blog. </em></p> <h4><strong>Thundermail and Thunderbird Pro services</strong></h4> <p>It’s no secret we’ve been building additional web services under the Thunderbird Pro name, and 2025 marked a pivotal moment in our vision for a complete, open-source Thunderbird ecosystem. </p> <p>This year we announced Thundermail, a dedicated email service by Thunderbird. During the past decade, we’ve seen a large move away from dedicated email clients to products like Gmail, partially because of the robust ecosystem around them. The plan for Thundermail is to eventually offer an alternative webmail solution that protects your privacy, and doesn’t use your messages to train AI or show you ads. </p> <p>Here’s what else we’ve been working on in addition to Thundermail: </p> <p>During its current beta, Thunderbird Appointment saw great improvements in managing your schedule, with many of the changes focused on reliability and visual polish.</p> <p>Thunderbird Send, an app for securely sharing encrypted files, also saw forward momentum. Together, these services are steadily moving toward a wider beta launch this fall, and we’re excited to see how you’ll use them to improve your personal and professional lives. </p> <p>All of the work going into Thundermail and Thunderbird Pro services is guided by a clear goal: providing you with an ethical alternative to the closed-off “walled gardens” that dominate our digital communication. You shouldn’t have to sacrifice your values and give up your personal data to enjoy convenience and powerful features. </p> <p><em>In depth details on Thunderbird Pro development can be found in our </em><a href="https://blog.thunderbird.net/tag/tbpro/"><em>Thunderbird Pro</em></a><em> updates on our blog. </em></p> <div class="wp-block-spacer" style="height: 52px;"></div> <h3><strong>2024 Financial Picture</strong></h3> <p>The generosity of our donors continues to power everything we do, and the importance of these financial contributions cannot be understated. In 2024, the Thunderbird project once again saw continued growth in donations which paved the way for Thundermail and the Thunderbird Pro services you just read about. It also gave us the opportunity to grow our mobile development team, improve our user support outreach, and expand our connections to the community. </p> <p>Here’s a detailed breakdown of our donation revenue in 2024, and why many of these statistics are so meaningful. </p> <h4><strong>Contribution Revenue</strong></h4> <p>In 2024, financial contributions to Thunderbird reached $10.3 million, representing a 19% increase over the previous year. This support came courtesy of more than 539,000 transactions from more than 335,000 individual donors. A healthy 25% of these contributions were given as recurring monthly support.</p> <p>What makes this so meaningful to us isn’t the total revenue, or the scale of the donations. It’s how those donations break down. The average contribution was $18.88, with a median of $16.66. Among our recurring donors, the average monthly gift was only $6.25. In fact, 53% of all donations were $20 or less, and 94% were $35 or less. Only 17 contributions were $1,000 or more. </p> <p>What does this represent when we go beyond the numbers? It means Thunderbird isn’t sustained by a handful of wealthy benefactors or corporate sponsors. Rather, it is sustained by a global community of people who believe in what we’ve built and what we’re still building, and they come together to keep it moving forward.</p> <p>And that global reach continues to inspire us. We received contributions from more than 200 countries. The top ten contributing countries – Germany, the United States, France, the United Kingdom, Switzerland, the Netherlands, Japan, Italy, Austria, and Canada – accounted for 83% of our total revenue.</p> <figure class="wp-block-image size-full"><a href="https://blog.thunderbird.net/files/2025/10/Annual-Report1.jpg"><img alt="" class="wp-image-3862" height="1041" src="https://blog.thunderbird.net/files/2025/10/Annual-Report1.jpg" width="2000" /></a></figure> <p>But products aren’t just numbers and code. Products are the people that work on them. To support the ambitions of our expanding roadmap, our team grew significantly in 2024. We added 14 new team members throughout the year, closing out 2024 with 43 full-time staff members. Much of this growth strengthened our mobile development, web services, and desktop + release teams. 80% of our staff focuses on technical work – things like product development and infrastructure – but we also added more roles to actively support users, improve community outreach, and smooth out internal operations. </p> <h4><strong>Expenses</strong></h4> <p>When we talk about how we use financial contributions, we’re really talking about <a href="https://www.thunderbird.net/en-US/about/">investments in our shared values</a>. The majority of our spending goes to personnel; the talented individuals who write code, design interfaces, test features, and support our users. Infrastructure is the next largest expense, followed by administrative costs to keep operations running smoothly. </p> <p>Below is a breakdown of our 2024 expenses:</p> <figure class="wp-block-image size-full"><a href="https://blog.thunderbird.net/files/2025/10/Annual-Report.jpg"><img alt="" class="wp-image-3856" height="1480" src="https://blog.thunderbird.net/files/2025/10/Annual-Report.jpg" width="2000" /></a></figure> <div class="wp-block-spacer" style="height: 58px;"></div> <h3><strong>Community Snapshot</strong></h3> <h4><strong>Contributor &amp; Community Growth</strong></h4> <p>For two decades, Thunderbird has survived and thrived because of its dedicated open-source community. In 2024, we continued using our<a href="https://thunderbird.biterg.io"> Bitergia dashboard</a> to give our community a clear view of the project’s overall activity across the board. (You can read more about how we collaborated on and use this beneficial tool<a href="https://blog.thunderbird.net/2024/12/visualizing-the-thunderbird-community-with-bitergia/"> here</a>.)<br /></p> <p>This dashboard helps us track participation, identify and celebrate successes, and find areas to improve, which is especially important as we expand the Thunderbird ecosystem with new products and services. </p> <p>For this report, we’ve highlighted some of the most notable community metrics and growth milestones from 2024. </p> <p>For reference, <strong>Github</strong> and <strong>Bugzilla</strong> measure developer contributions. <strong>TopicBox</strong> measures activity across our many mailing lists. <strong>Pontoon</strong> measures the activity from volunteers who help us translate and localize Thunderbird. <strong>SUMO</strong> (the Mozilla support website) measures the impact of Thunderbird’s support volunteers who engage with our users and respond to their varied support questions.</p> <figure class="wp-block-image size-full"><a href="https://blog.thunderbird.net/files/2025/10/Annual-Report2-scaled.jpg"><img alt="" class="wp-image-3849" height="2560" src="https://blog.thunderbird.net/files/2025/10/Annual-Report2-scaled.jpg" width="1502" /></a></figure> <p>We estimate that in 2024, the total number of people who contributed to Thunderbird – by writing code, answering support questions, providing translations, or other meaningful areas – is more than 20,000. </p> <p>It’s especially encouraging to see the number of translation locales increase from 58 to 70, as Thunderbird continues to find new users around the world. </p> <p>But there are areas of opportunity, too. For example, making it less complicated for people who want to start contributing to Thunderbird. We’ve started addressing this by recording two Community Office Hours videos, talking about how to write Knowledge Base articles, and how to effectively answer questions on the Mozilla Support website. </p> <p><strong>Mozilla Connect</strong> is another portal that lets anyone interested in the betterment of Thunderbird suggest ideas, openly discuss them, and vote on them. In 2024, four desktop ideas as well as four of your ideas in our relatively new mobile space were implemented, and we saw more than 500 new thoughtful ideas suggested across mobile and desktop. Our staff and community are watching for your ideas, so <a href="https://connect.mozilla.org">keep them coming! </a></p> <div class="wp-block-spacer" style="height: 57px;"></div> <h3><strong>Thank you</strong></h3> <p>As we close out this year’s <em>State of the Bird</em>, we want to once again shine a light on the incredible global community of Thunderbird supporters. Whether you’ve contributed your valuable time, financial donations, or simply shared Thunderbird with colleagues, friends, and family, your support continues to brighten Thunderbird’s future. </p> <p>After all, products aren’t just numbers on a chart. Products are the people who create them, support them, improve them, and believe in crucial concepts like privacy, digital wellbeing, and open standards. </p> <p>We’re so very grateful to you.</p><p>The post <a href="https://blog.thunderbird.net/2025/10/state-of-the-bird-2024-25/">State Of The Bird 2024/25</a> appeared first on <a href="https://blog.thunderbird.net">The Thunderbird Blog</a>.</p></description> <pubDate>Wed, 08 Oct 2025 10:02:00 +0000</pubDate> <dc:creator>Ryan Sipes</dc:creator></item><item> <title>Niko Matsakis: SymmACP: extending Zed's ACP to support Composable Agents</title> <guid isPermaLink="false">https://smallcultfollowing.com/babysteps/blog/2025/10/08/symmacp/</guid> <link>https://smallcultfollowing.com/babysteps/blog/2025/10/08/symmacp/?utm_source=atom_feed</link> <description><p>This post describes <strong>SymmACP</strong> – a proposed extension to Zed’s <a href="https://agentclientprotocol.com/overview/introduction">Agent Client Protocol</a> that lets you build AI tools like Unix pipes or browser extensions. Want a better TUI? Found some cool slash commands on GitHub? Prefer a different backend? With SymmACP, you can mix and match these pieces and have them all work together without knowing about each other.</p><p>This is pretty different from how AI tools work today, where everything is a monolith – if you want to change one piece, you’re stuck rebuilding the whole thing from scratch. SymmACP allows you to build out new features and modes of interactions in a layered, interoperable way. This post explains how SymmACP would work by walking through a series of examples.</p><p>Right now, SymmACP is just a thought experiment. I’ve sketched these ideas to the Zed folks, and they seemed interested, but we still have to discuss the details in this post. My plan is to start prototyping in <a href="https://symposium-dev.github.io/symposium/">Symposium</a> – if you think the ideas I’m discussing here are exciting, please join the <a href="https://symposium-dev.zulipchat.com/">Symposium Zulip</a> and let’s talk!</p><h3>“Composable agents” let you build features independently and then combine them</h3><p>I’m going to explain the idea of “composable agents” by walking through a series of features. We’ll start with a basic CLI agent<sup id="fnref:1"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:1">1</a></sup> tool – basically a chat loop with access to some MCP servers so that it can read/write files and execute bash commands. Then we’ll show how you could add several features on top:</p><ol><li>Addressing time-blindness by helping the agent know what time it is.</li><li>Injecting context and “personality” to the agent.</li><li>Spawning long-running, asynchronous tasks.</li><li>A copy of Q CLI’s <code>/tangent</code> mode that lets you do a bit of “off the books” work that gets removed from your history later.</li><li>Implementing <a href="https://symposium-dev.github.io/symposium/get-started/walkthroughs.html">Symposium’s interactive walkthroughs</a>, which give the agent a richer vocabulary for communicating with you than just text.</li><li>Smarter tool delegation.</li></ol><p><strong>The magic trick is that each of these features will be developed as separate repositories.</strong> What’s more, they could be applied to any base tool you want, so long as it speaks SymmACP. And you could also combine them with different front-ends, such as a TUI, a web front-end, builtin support from <a href="https://zed.dev/">Zed</a> or <a href="https://zed.dev/blog/jetbrains-on-acp">IntelliJ</a>, etc. Pretty neat.</p><p>My hope is that if we can centralize on SymmACP, or something like it, then we could move from everybody developing their own bespoke tools to an interoperable ecosystem of ideas that can build off of one another.</p><h3>let mut SymmACP = ACP</h3><p>SymmACP begins with ACP, so let’s explain what ACP is. ACP is a wonderfully simple protocol that lets you abstract over CLI agents. Imagine if you were using an agentic CLI tool except that, instead of communication over the terminal, the CLI tool communicates with a front-end over JSON-RPC messages, currently sent via stdin/stdout.</p><pre class="mermaid">flowchart LR Editor &lt;-.-&gt;|JSON-RPC via stdin/stdout| Agent[CLI Agent] </pre><p>When you type something into the GUI, the editor sends a JSON-RPC message to the agent with what you typed. The agent responds with a stream of messages containing text and images. If the agent decides to invoke a tool, it can request permission by sending a JSON-RPC message back to the editor. And when the agent has completed, it responds to the editor with an “end turn” message that says “I’m ready for you to type something else now”.</p><pre class="mermaid">sequenceDiagram participant E as Editor participant A as Agent participant T as Tool (MCP) E-&gt;&gt;A: prompt("Help me debug this code") A-&gt;&gt;E: request_permission("Read file main.rs") E-&gt;&gt;A: permission_granted A-&gt;&gt;T: read_file("main.rs") T-&gt;&gt;A: file_contents A-&gt;&gt;E: text_chunk("I can see the issue...") A-&gt;&gt;E: text_chunk("The problem is on line 42...") A-&gt;&gt;E: end_turn </pre><h3>Telling the agent what time it is</h3><p>OK, let’s tackle our first feature. If you’ve used a CLI agent, you may have noticed that they don’t know what time it is – or even what <em>year</em> it is. This may sound trivial, but it can lead to some real mistakes. For example, they may not realize that some information is outdated. Or when they do web searches for information, they can search for the wrong thing: I’ve seen CLI agents search the web for “API updates in 2024” for example, even though it is 2025.</p><p>To fix this, many CLI agents will inject some extra text along with your prompt, something like <code>&lt;current-date date="2025-10-08" time="HH:MM:SS"/&gt;</code>. This gives the LLM the context it needs.</p><p>So how could use ACP to build that? The idea is to create a <strong>proxy</strong>. This proxy would wrap the original ACP server:</p><pre class="mermaid">flowchart LR Editor[Editor/VSCode] &lt;--&gt;|ACP| Proxy[Datetime Proxy] &lt;--&gt;|ACP| Agent[CLI Agent] </pre><p>This proxy will take every “prompt” message it receives and decorate it with the date and time:</p><pre class="mermaid">sequenceDiagram participant E as Editor participant P as Proxy participant A as Agent E-&gt;&gt;P: prompt("What day is it?") P-&gt;&gt;A: prompt("&lt;current-date .../&gt; What day is it?") A-&gt;&gt;P: text_chunk("It is 2025-10-08.") P-&gt;&gt;E: text_chunk("It is 2025-10-08.") A-&gt;&gt;P: end_turn P-&gt;&gt;E: end_turn </pre><p>Simple, right? And of course this can be used with any editor and any ACP-speaking tool.</p><h3>Next feature: Injecting “personality” to the agent</h3><p>Let’s look at another feature that basically “falls out” from ACP: injecting personality. Most agents give you the ability to configure “context” in various ways – or what Claude Code calls <a href="https://docs.claude.com/en/docs/claude-code/memory">memory</a>. This is useful, but I and others have noticed that if what you want is to change how Claude “behaves” – i.e., to make it more collaborative – it’s not really enough. You really need to kick off the conversation by reinforcing that pattern.</p><p>In Symposium, <a href="https://github.com/symposium-dev/symposium/blob/7f437fdf02ab52cd0bd3070d25feaad387b6d23f/symposium/mcp-server/src/server.rs#L885">the “yiasou” prompt</a> (also available as “hi”, for those of you who don’t speak Greek 😛) is meant to be run as the first thing in the conversation. But there’s nothing an MCP server can do to <em>ensure</em> that the user kicks off the conversation with <code>/symposium:hi</code> or something similar. Of course, if Symposium were implemented as an ACP Server, we absolutely could do that:</p><pre class="mermaid">sequenceDiagram participant E as Editor participant P as Proxy participant A as Agent E-&gt;&gt;P: prompt("I'd like to work on my document") P-&gt;&gt;A: prompt("/symposium:hi") A-&gt;&gt;P: end_turn P-&gt;&gt;A: prompt("I'd like to work on my document") A-&gt;&gt;P: text_chunk("Sure! What document is that?") P-&gt;&gt;E: text_chunk("Sure! What document is that?") A-&gt;&gt;P: end_turn P-&gt;&gt;E: end_turn </pre><h3>Proxies are a better version of hooks</h3><p>Some of you may be saying, “hmm, isn’t that what <a href="https://docs.claude.com/en/docs/claude-code/hooks">hooks</a> are for?” And yes, you could do this with hooks, but there’s two problems with that. First, hooks are non-standard, so you have to do it differently for every agent.</p><p>The second problem with hooks is that they’re <strong>fundamentally limited</strong> to what the hook designer envisioned you might want. You only get hooks at the places in the workflow that the tool gives you, and you can only control what the tool lets you control. The next feature starts to show what I mean: as far as I know, it cannot readily be implemented with hooks the way I would want it to work.</p><h3>Next feature: long-running, asynchronous tasks</h3><p>Let’s move on to our next feature, long-running asynchronous tasks. This feature is going to have to go beyond the current capabilities of ACP into the expanded “SymmACP” feature set.</p><p>Right now, when the server invokes an MCP tool, it executes in a blocking way. But sometimes the task it is performing might be long and complicated. What you would really like is a way to “start” the task and then go back to working. When the task is complete, you (and the agent) could be notified.</p><p>This comes up for me a lot with “deep research”. A big part of my workflow is that, when I get stuck on something I don’t understand, I deploy a research agent to scour the web for information. Usually what I will do is ask the agent I’m collaborating with to prepare a research prompt summarizing the things we tried, what obstacles we hit, and other details that seem relevant. Then I’ll pop over to <a href="https://claude.ai/">claude.ai</a> or <a href="https://gemini.google.com/">Gemini Deep Research</a> and paste in the prompt. This will run for 5-10 minutes and generate a markdown report in response. I’ll download that and give it to my agent. Very often this lets us solve the problem.<sup id="fnref:2"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:2">2</a></sup></p><p>This research flow works well but it is tedious and requires me to copy-and-paste. What I would ideally want is an MCP tool that does the search for me and, when the results are done, hands them off to the agent so it can start processing immediately. But in the meantime, I’d like to be able to continue working with the agent while we wait. Unfortunately, the protocol for tools provides no mechanism for asynchronous notifications like this, from what I can tell.</p><h3>SymmACP += tool invocations + unprompted sends</h3><p>So how would I do it with SymmACP? Well, I would want to extend the ACP protocol as it is today in two ways:</p><ol><li>I’d like the ACP proxy to be able to provide tools that <em>the proxy</em> will execute. Today, the agent is responsible for executing all tools; the ACP protocol only comes into play when requesting <em>permission</em>. But it’d be trivial to have MCP tools where, to execute the tool, the agent sends back a message over ACP instead.</li><li>I’d like to have a way for the <em>agent</em> to initiate responses to the <em>editor</em>. Right now, the editor always initiatives each communication session with a prompt; but, in this case, the agent might want to send messages back unprompted.</li></ol><p>In that case, we could implement our Research Proxy like so:</p><pre class="mermaid">sequenceDiagram participant E as Editor participant P as Proxy participant A as Agent E-&gt;&gt;P: prompt("Why is Rust so great?") P-&gt;&gt;A: prompt("Why is Rust so great?") A-&gt;&gt;P: invoke tool("begin_research") activate P P-&gt;&gt;A: ok A-&gt;&gt;P: "I'm looking into it!" P-&gt;&gt;E: "I'm looking into it!" A-&gt;&gt;P: end_turn P-&gt;&gt;E: end_turn Note over E,A: Time passes (5-10 minutes) and the user keeps working... Note over P: Research completes in background P-&gt;&gt;A: &lt;research-complete/&gt; deactivate P A-&gt;&gt;P: "Research says Rust is fast" P-&gt;&gt;E: "Research says Rust is fast" A-&gt;&gt;P: end_turn P-&gt;&gt;E: end_turn </pre><p>What’s cool about this is that the proxy encapsulates the entire flow: it knows how to do the research, and it manages notifying the various participants when the research completes. (Also, this leans on one detail I left out, which is that )</p><h3>Next feature: tangent mode</h3><p>Let’s explore our next feature, <a href="https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line-experimental-features.html">Q CLI’s <code>/tangent</code> mode</a>. This feature is interesting because it’s a simple (but useful!) example of history editing. The way <code>/tangent</code> works is that, when you first type <code>/tangent</code>, Q CLI saves your current state. You can then continue as normal but when you <em>next</em> type <code>/tangent</code>, your state is restored to where you were. This, as the name suggests, lets you explore a side conversation without polluting your main context.</p><p>The basic idea for supporting tangent in SymmACP is that the proxy is going to (a) intercept the tangent prompt and remember where it began; (b) allow the conversation to continue as normal; and then (c) when it’s time to end the tangent, create a new session and replay the history up until the point of the tangent<sup id="fnref:3"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:3">3</a></sup>.</p><h3>SymACP += replay</h3><p>You can <em>almost</em> implement “tangent” in ACP as it is, but not quite. In ACP, the agent always owns the session history. The editor can create a new session or load an older one; when loading an older one, the agent “replays” “replays” the events so that the editor can reconstruct the GUI. But there is no way for the <em>editor</em> to “replay” or construct a session to the <em>agent</em>. Instead, the editor can only send prompts, which will cause the agent to reply. In this case, what we want is to be able to say “create a new chat in which I said this and you responded that” so that we can setup the initial state. This way we could easily create a new session that contains the messages from the old one.</p><p>So how this would work:</p><pre class="mermaid">sequenceDiagram participant E as Editor participant P as Proxy participant A as Agent E-&gt;&gt;P: prompt("Hi there!") P-&gt;&gt;A: prompt("Hi there!") Note over E,A: Conversation proceeds E-&gt;&gt;P: prompt("/tangent") Note over P: Proxy notes conversation state P-&gt;&gt;E: end_turn E-&gt;&gt;P: prompt("btw, ...") P-&gt;&gt;A: prompt("btw, ...") Note over E,A: Conversation proceeds E-&gt;&gt;P: prompt("/tangent") P-&gt;&gt;A: new_session P-&gt;&gt;A: prompt("Hi there!") Note over P,A: ...Proxy replays conversation... </pre><h3>Next feature: interactive walkthroughs</h3><p>One of the nicer features of Symposium is the ability to do <a href="https://symposium-dev.github.io/symposium/get-started/walkthroughs.html">interactive walkthroughs</a>. These consist of an HTML sidebar as well as inline comments in the code:</p><img alt="Walkthrough screenshot" src="https://smallcultfollowing.com/babysteps/ /assets/2025-symmacp/walkthrough.png" width="100%" /><p>Right now, this is implemented by a kind of hacky dance:</p><ul><li>The agent invokes an MCP tool and sends it the walkthrough in markdown. This markdown includes commands meant to be placed on particular lines, identified not by line number (agents are bad at line numbers) but by symbol names or search strings.</li><li>The MCP tool parses the markdown, determines the line numbers for comments, and creates HTML. It sends that HTML over IPC to the VSCode extension.</li><li>The VSCode receives the IPC message, displays the HTML in the sidebar, and creates the comments in the code.</li></ul><p>It works, but it’s a giant Rube Goldberg machine.</p><h3>SymmACP += Enriched conversation history</h3><p>With SymmACP, we would structure the passthrough mechanism as a proxy. Just as today, it would provide an MCP tool to the agent to receive the walkthrough markdown. It would then convert that into the HTML to display on the side along with the various comments to embed in the code. But this is where things are different.</p><p>Instead of sending that content over IPC, what I would want to do is to make it possible for proxies to deliver extra information along with the chat. This is relatively easy to do in ACP as is, since it provides for various capabilities, but I think I’d want to go one step further</p><p>I would have a proxy layer that manages walkthroughs. As we saw before, it would provide a tool. But there’d be one additional thing, which is that, beyond just a chat history, it would be able to convey additional state. I think the basic conversation structure is like:</p><ul><li>Conversation<ul><li>Turn<ul><li>User prompt(s) – could be zero or more</li><li>Response(s) – could be zero or more</li><li>Tool use(s) – could be zero or more</li></ul></li></ul></li></ul><p>but I think it’d be useful to (a) be able to attach metadata to any of those things, e.g., to add extra context <em>about the conversation</em> or <em>about a specific turn</em> (or even a specific <em>prompt</em>), but also additional kinds of events. For example, tool approvals are an <em>event</em>. And presenting a walkthrough and adding annotations are an event too.</p><p>The way I imagine it, one of the core things in SymmACP would be the ability to serialize your state to JSON. You’d be able to ask a SymmACP paricipant to summarize a session. They would in turn ask any delegates to summarize and then add their own metadata along the way. You could also send the request in the <em>other</em> direction – e.g., the agent might present its state to the editor and ask it to augment it.</p><h3>Enriched history would let walkthroughs be extra metadata</h3><p>This would mean a walkthrough proxy could add extra metadata into the chat transcript like “the current walkthrough” and “the current comments that are in place”. Then the <em>editor</em> would either <em>know</em> about that metadata or not. If it doesn’t, you wouldn’t see it in your chat. Oh well – or perhaps we do something HTML like, where there’s a way to “degrade gracefully” (e.g., the walkthrough could be presented as a regular “response” but with some metadata that, if you know to look, tells you to interpret it differently). But if the editor DOES know about the metadata, it interprets it specially, throwing the walkthrough up in a panel and adding the comments into the code.</p><p>With enriched histories, I think we can even say that in SymmACP, the ability to load, save, and persist sessions <em>itself</em> becomes an extension, something that can be implemented by a proxy; the base protocol only needs the ability to conduct and serialize a conversation.</p><h3>Final feature: Smarter tool delegation.</h3><p>Let me sketch out another feature that I’ve been noodling on that I think would be pretty cool. It’s well known that there’s a problem that LLMs get confused when there are too many MCP tools available. They get distracted. And that’s sensible, so would I, if I were given a phonebook-size list of possible things I could do and asked to figure something out. I’d probably just ignore it.</p><p>But how do humans deal with this? Well, we don’t take the whole phonebook – we got a shorter list of <em>categories</em> of options and then we drill down. So I go to the File Menu and <em>then</em> I get a list of options, not a flat list of commands.</p><p>I wanted to try building an MCP tool for IDE capabilities that was similar. There’s a bajillion set of things that a modern IDE can “do”. It can find references. It can find definitions. It can get type hints. It can do renames. It can extract methods. In fact, the list is even open-ended, since extensions can provide their <em>own</em> commands. I don’t know what all those things <em>are</em> but I have a sense for the <em>kinds of things</em> an IDE can do – and I suspect models do too.</p><p>What if you gave them a single tool, “IDE operation”, and they could use plain English to describe what they want? e.g., <code>ide_operation("find definition for the ProxyHandler that referes to HTTP proxies")</code>. Hmm, this is sounding a lot like a delegate, or a sub-agent. Because now you need to use a second LLM to interpret that request – you probably want to do something like, give it a list of sugested IDE capabilities and the ability to find out full details and ask it to come up with a plan (or maybe directly execute the tools) to find the answer.</p><p>As it happens, MCP <em>has</em> a capability to enable tools to do this – it’s called (somewhat oddly, in my opinion) “sampling”. It allows for “callbacks” from the MCP tool to the LLM. But literally <em>nobody</em> implements it, from what I can tell.<sup id="fnref:4"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:4">4</a></sup> But sampling is kind of limited anyway. With SymmACP, I think you could do much more interesting things.</p><h3>SymmACP.contains(simultaneous_sessions)</h3><p>The key is that ACP already permits a single agent to “serve up” many simultaneous sessions. So that means that if I have a proxy, perhaps one supplying an MCP tool definition, I could use it to start <em>fresh</em> sessions – combine that with the “history replay” capability I mentioned above, and the tool can control exactly what context to bring over into that session to start from, as well, which is very cool (that’s a challenge for MCP servers today, they don’t get access to the conversation history).</p><pre class="mermaid">sequenceDiagram participant E as Editor participant P as Proxy participant A as Agent A-&gt;&gt;P: ide_operation("...") activate P P-&gt;&gt;A: new_session activate P activate A P-&gt;&gt;A: prompt("Using these primitive operations, suggest a way to do '...'") A-&gt;&gt;P: ... A-&gt;&gt;P: end_turn deactivate P deactivate A Note over P: performs the plan P-&gt;&gt;A: result from tool deactivate P </pre><h3>Conclusion</h3><p>Ok, this post sketched a variant on <a href="https://agentclientprotocol.com/overview/introduction">ACP</a> that I call SymmACP. SymmACP extends ACP with</p><ul><li>the ability for either side to provide the initial state of a conversation, not just the server</li><li>the ability for an “editor” to provide an MCP tool to the “agent”</li><li>the ability for agents to respond without an initial prompt</li><li>the ability to serialize conversations and attach extra state (already kind of present)</li></ul><p>Most of these are modest extensions to ACP, in my opinion, and easily doable in a backwards fashion just by adding new capabilities. <strong>But together they unlock the ability for anyone to craft extensions to agents and deploy them in a composable way.</strong> I am super excited about this. This is exactly what I wanted Symposium to be all about.</p><p>It’s worth noting the old adage: “with great power, comes great responsibility”. These proxies and ACP layers I’ve been talking about are really like IDE extensions. They can effectively do <em>anything</em> you could do. There are obvious security concerns. Though I think that approaches like Microsoft’s <a href="https://opensource.microsoft.com/blog/2025/08/06/introducing-wassette-webassembly-based-tools-for-ai-agents/">Wassette</a> are key here – it’d be awesome to have a “capability-based” notion of what a “proxy layer” is, where everything compiles to WASM, and where users can tune what a given proxy can actually <em>do</em>.</p><p>I plan to start sketching a plan to drive this work in <a href="https://symposium-dev.github.io/symposium/">Symposium</a> and elsewhere. My goal is to have a completely open and interopable client, one that can be based on any agent (including local ones) and where you can pick and choose which parts you want to use. I expect to build out lots of custom functionality to support Rust development (e.g., explaining and diagnosting trait errors using the new trait solver is high on my list…and macro errors…) but also to have other features like walkthroughs, collaborative interaction style, etc that are all language independent – and I’d love to see language-focused features for other langauges, especially Python and TypeScript (because <a href="https://smallcultfollowing.com/babysteps/blog/2025/07/31/rs-py-ts-trifecta/">“the new trifecta”</a>) and Swift and Kotlin (because mobile). If that vision excites you, come join the <a href="https://symposium-dev.zulipchat.com/">Symposium Zulip</a> and let’s chat!</p><h3>Appendix: A guide to the agent protocols I’m aware of</h3><p>One question I’ve gotten when discussing this is how it compares to the other host of protocols out there. Let me give a brief overview of the related work and how I understand its pros and cons:</p><ul><li><em><a href="https://modelcontextprotocol.io/docs/getting-started/intro">Model context protocol (MCP)</a>:</em> The queen of them all. A protocol that provides a set of tools, prompts, and resources up to the agent. Agents can invoke tools by supplying appropriate parameters, which are JSON. Prompts are shorthands that users can invoke using special commands like <code>/</code> or <code>@</code>, they are essentially macros that expand “as if the user typed it” (but they can also have parameters and be dynamically constructed). <em>Resources</em> are just data that can be requested. MCP servers can either be local or hosted remotely. Remote MCP has only recently become an option and auth in particular is limited.<ul><li>Comparison to SymmACP: MCP provides tools that the agent can invoke. SymmACP builds on it by allowing those tools to be provided by outer layers in the proxy chain. SymmACP is oriented at controlling the whole chat “experience”.</li></ul></li><li><em><a href="https://agentclientprotocol.com/overview/introduction">Zed’s Agent Client Protocol (ACP)</a>:</em> The basis for SymmACP. Allows editors to create and manage sessions. Focused only on local sessions, since your editor runs locally.<ul><li>Comparison to SymmACP: That’s what this post is all about! SymmACP extends ACP with new capabilities that let intermediate layers manipulate history, provide tools, and provide extended data upstream to support richer interaction patterns than jus chat. PS I expect we may want to support more remote capabilities, but it’s kinda orthogonal in my opinion (e.g., I’d like to be able to work with an agent running over in a cloud-hosted workstation, but I’d probably piggyback on ssh for that).</li></ul></li><li><em><a href="https://developers.googleblog.com/en/a2a-a-new-era-of-agent-interoperability/">Google’s Agent-to-Agent Protocol (A2A)</a> and <a href="https://www.ibm.com/think/topics/agent-communication-protocol">IBM’s Agent Communication Protocol (ACP)</a><sup id="fnref:5"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:5">5</a></sup>:</em> From what I can tell, Google’s “agent-to-agent” protocol is <em>kinda</em> like a mix of MCP and OpenAPI. You can ping agents that are running remotely and get them to send you “agent cards”, which describe what operations they can perform, how you authenticate, and other stuff like that. It looks to me quite similar to MCP except that it has richer support for remote execution and in particular supports things like long-running communication, where an agent may need to go off and work for a while and then ping you back on a webhook.<ul><li><em>Comparison to MCP:</em> To me, A2A looks like a variant of MCP that is more geared to remote execution. MCP has a method for tool discovery where you ping the server to get a list of tools; A2A has a similar mechanism with Agent Cards. MCP can run locally, which A2A cannot afaik, but A2A has more options about auth. MCP can only be invoked synchronously, whereas A2A supports long-running operations, progress updates, and callbacks. It seems like the two could be merged to make a single whole.</li><li><em>Comparison to SymmACP:</em> I think A2A is orthogonal from SymmACP. A2A is geared to agents that provide services to one another. SymmACP is geared towards building new development tools for interacting with agents. It’s possible you could build something like SymmACP <em>on</em> A2A but I don’t know what you would really gain by it (and I think it’d be easy to do later).</li></ul></li></ul><div class="footnotes"><hr /><ol><li id="fn:1"><p>Everybody uses agents in various ways. I like Simon Willison’s <a href="https://simonwillison.net/2025/May/22/tools-in-a-loop/">“agents are models using tools in a loop”</a> definition; I feel that an “agentic CLI tool” fits that definition, it’s just that part of the loop is reading input from the user. I think “fully autonomous” agents are a subset of all agents – many agent processes interact with the outside world via tools etc. From a certain POV, you can view the agent “ending the turn” as invoking a tool for “gimme the next prompt”. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:1">↩︎</a></p></li><li id="fn:2"><p>Research reports are a <strong>major</strong> part of how I avoid hallucination. You can see an example of one such report I commissioned on the <a href="https://symposium-dev.github.io/symposium/research/lsp-overview/index.html">details of the Language Server Protocol here</a>; if we were about to embark on something that required detailed knowledge of LSP, I would ask the agent to read that report first. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:2">↩︎</a></p></li><li id="fn:3"><p>Alternatively: clear the session history and rebuild it, but I kind of prefer the functional view of the world, where a given session never changes. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:3">↩︎</a></p></li><li id="fn:4"><p>I started an implementation for Q CLI but got distracted – and, for reasons that should be obvious, I’ve started to lose interest. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:4">↩︎</a></p></li><li id="fn:5"><p>Yes, you read that right. There is another ACP. Just a mite confusing when you google search. =) <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:5">↩︎</a></p></li></ol></div></description> <pubDate>Wed, 08 Oct 2025 08:54:08 +0000</pubDate></item><item> <title>The Mozilla Blog: Firefox profiles: Private, focused spaces for all the ways you browse</title> <guid isPermaLink="false">https://blog.mozilla.org/?p=82094</guid> <link>https://blog.mozilla.org/en/firefox/profile-management/</link> <description><p>Every part of your life has its own rhythm: work, school, family, personal projects. Beginning Oct. 14, we’re rolling out a new <a href="https://support.mozilla.org/kb/profile-management#w_is-this-feature-available-on-android-or-ios">profile management feature in Firefox</a> so you can keep them separate and create distinct spaces — each with its own bookmarks, logins, history, extensions and themes. It’s an easy way to stay organized, focused and private.</p> <div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/firefox-profiles.png" rel="noreferrer noopener" target="_blank"><img alt="Firefox Profiles feature shown with an illustration of three foxes and a setup screen for creating and customizing browser profiles." class="wp-image-82095" height="576" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/firefox-profiles-1024x576.png" style="width: 675px;" width="1024" /></a></figure></div> <h3><strong>Spaces that lighten your load</strong></h3> <p>Profiles don’t just keep you organized; they also reduce data mixing and <a href="https://blog.mozilla.org/firefox/multitasking/">ease cognitive load</a>. By keeping your different roles online neatly separate, you spend less mental energy juggling contexts and avoid awkward surprises (like your weekend plans popping up in a work presentation). And, like everything in Firefox, profiles are built on our <a href="https://blog.mozilla.org/privacy-security/mozilla-anti-tracking-milestones-timeline/">strong privacy foundation</a>.</p> <p>We also <a href="https://blog.mozilla.org/firefox/shifting-left-for-better-accessibility/">worked with disabled people</a> to make profiles not only compliant, but genuinely delightful to use for everyone. That collaboration shaped everything from the visual design (avatars, colors, naming) to the way profiles keep sensitive data (like medical information) private. It’s an example of how designing for accessibility boundaries benefits all of us.</p> <h3><strong>What makes profiles in Firefox different</strong></h3> <p>Other browsers offer profiles mainly for convenience. Firefox goes further by making them part of our mission to put you in control of your online life.</p> <ul><li><strong>Privacy first:</strong> Firefox is built with privacy as a default. We don’t know your age, gender, precise location, name of your profile, or other information Big Tech collects and profits from. Each profile keeps its own browsing data separate. No mixing, no surprise leaks.<br /></li> <li><strong>Custom spaces:</strong> Pick colors and themes to make each profile easy to spot at a glance. You can even upload your own avatar. Your work profile can feel buttoned-up, while your personal profile reflects your style.</li></ul> <div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/profiles-1.png" rel="noreferrer noopener" target="_blank"><img alt="Firefox Profile Manager showing Work and Personal profiles, with an option to create a new one, on a desktop with a forest background." class="wp-image-82118" height="533" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/profiles-1-1024x533.png" style="width: 675px;" width="1024" /></a></figure></div> <p>Profiles in Firefox aren’t just a way to clean up your tabs. They’re a way to set boundaries, protect your information and make the internet a little calmer. Because when your browser respects your focus and your privacy, it frees you up to do what actually matters — work, connect, create, explore — on your own terms.</p> <a class="ft-c-inline-cta" href="https://www.mozilla.org/firefox/new/?utm_source=blog.mozilla.org&amp;utm_medium=referral&amp;utm_campaign=blog-nav"> <div class="ft-c-inline-cta__media"> <img alt="" class="attachment-1x1 size-1x1" height="800" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2021/10/Visual-Guidelines-800x800.png" width="800" /> </div> <div class="ft-c-inline-cta__content"> <h4>Take control of your internet</h4> <span>Download Firefox</span> </div></a><p>The post <a href="https://blog.mozilla.org/en/firefox/profile-management/">Firefox profiles: Private, focused spaces for all the ways you browse</a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p></description> <pubDate>Tue, 07 Oct 2025 14:11:44 +0000</pubDate> <dc:creator>Susmitha Burra</dc:creator></item><item> <title>Niko Matsakis: The Handle trait</title> <guid isPermaLink="false">https://smallcultfollowing.com/babysteps/blog/2025/10/07/the-handle-trait/</guid> <link>https://smallcultfollowing.com/babysteps/blog/2025/10/07/the-handle-trait/?utm_source=atom_feed</link> <description><p>There’s been a lot of discussion lately around ergonomic ref-counting. We had a lang-team design meeting and then a quite impactful discussion at the RustConf Unconf. I’ve been working for weeks on a follow-up post but today I realized what should’ve been obvious from the start – that if I’m taking that long to write a post, it means the post is too damned long. So I’m going to work through a series of smaller posts focused on individual takeaways and thoughts. And for the first one, I want to (a) bring back some of the context and (b) talk about an interesting question, <strong>what should we call the trait</strong>. My proposal, as the title suggests, is <code>Handle</code> – but I get ahead of myself.</p><h3>The story thus far</h3><p>For those of you who haven’t been following, there’s been an ongoing discussion about how best to have ergonomic ref counting:</p><ul><li>It began with the first Rust Project Goals program in 2024H2, where Jonathan Kelley from Dioxus wrote a <a href="https://dioxus.notion.site/Dioxus-Labs-High-level-Rust-5fe1f1c9c8334815ad488410d948f05e">thoughtful blog post about a path to high-level Rust</a> that eventually became a 2024H2 <a href="https://rust-lang.github.io/rust-project-goals/2024h2/ergonomic-rc.html">project goal towards ergonomic ref-counting</a>.</li><li>I wrote a <a href="https://smallcultfollowing.com/babysteps/series/claim/">series of blog posts about a trait I called <code>Claim</code></a>.</li><li>Josh and I talked and Josh opened <a href="https://github.com/rust-lang/rfcs/pull/3680">RFC #3680</a>, which proposed a <code>use</code> keyword and <code>use ||</code> closures. Reception, I would say, was mixed; yes, this is tackling a real problem, but there were lots of concerns on the approach. <a href="https://github.com/rust-lang/rfcs/pull/3680#issuecomment-2625526944">I summarized the key points here</a>.</li><li>Santiago implemented experimental support for (a variant of) <a href="https://github.com/rust-lang/rfcs/pull/3680">RFC #3680</a> as part of the <a href="https://rust-lang.github.io/rust-project-goals/2025h1/ergonomic-rc.html">2025H1 project goal</a>.</li><li>I authored a <a href="https://rust-lang.github.io/rust-project-goals/2025h2/ergonomic-rc.html">2025H2 project goal proposing that we create an alternative RFC focused on higher-level use-cases</a> which prompted Josh and I have to have a long and fruitful conversation in which he convinced me that this was not the right approach.</li><li>We had a lang-team design meeting on 2025-08-27 in which I presented this <a href="https://hackmd.io/@rust-lang-team/B12TpGhKle">survey and summary of the work done thus far</a>.</li><li>And then at the <a href="https://2025.rustweek.org/unconf/">RustConf 2025 Unconf</a> we had a big group discussion on the topic that I found very fruitful, as well as various follow-up conversations with smaller groups.</li></ul><h3>This blog post is about “the trait”</h3><p>The focus of this blog post is on one particular question: what should we call “The Trait”. In virtually every design, there has been <em>some kind</em> of trait that is meant to identify <em>something</em>. But it’s been hard to get a handle<sup id="fnref:1"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:1">1</a></sup> on what precisely that <em>something</em> is. What is this trait for and what types should implement it? Some things are clear: whatever The Trait is, <code>Rc&lt;T&gt;</code> and <code>Arc&lt;T&gt;</code> should implement it, for example, but that’s about it.</p><p>My original proposal was for a trait named <a href="https://smallcultfollowing.com/babysteps/blog/2024/06/21/claim-auto-and-otherwise/"><code>Claim</code></a> that was meant to convey a “lightweight clone” – but really the trait was <a href="https://smallcultfollowing.com/babysteps/blog/2024/06/26/claim-followup-1/#what-i-really-proposed">meant to replace <code>Copy</code> as the definition of which clones ought to be explicit</a><sup id="fnref:2"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:2">2</a></sup>. Jonathan Kelley had a similar proposal but called it <code>Capture</code>. In <a href="https://github.com/rust-lang/rfcs/pull/3680">RFC #3680</a> the proposal was to call the trait <code>Use</code>.</p><p>The details and intent varied, but all of these attempts had one thing in common: they were very <em>operational</em>. That is, the trait was always being defined in terms of <em>what</em> it does (or doesn’t do) but not <em>why</em> it does it. And that I think will always be a weak grounding for a trait like this, prone to confusion and different interpretations. For example, what is a “lightweight” clone? Is it O(1)? But what about things that are O(1) with very high probability? And of course, O(1) doesn’t mean <em>cheap</em> – it might copy 22GB of data every call. That’s O(1).</p><p>What you want is a trait where it’s fairly clear when it should and should not be implemented and not based on taste or subjective criteria. And <code>Claim</code> and friends did not meet the bar: in the Unconf, several new Rust users spoke up and said they found it very hard, based on my explanations, to judge whether their types ought to implement The Trait (whatever we call it). That has also been a persitent theme from the RFC and elsewhere.</p><h3>“Shouldn’t we call it <em>share</em>?” (hat tip: Jack Huey)</h3><p>But really there <em>is</em> a semantic underpinning here, and it was Jack Huey who first suggested it. Consider this question. What are the differences between cloning a <code>Mutex&lt;Vec&lt;u32&gt;&gt;</code> and a <code>Arc&lt;Mutex&lt;Vec&lt;u32&gt;&gt;&gt;</code>?</p><p>One difference, of course, is cost. Cloning the <code>Mutex&lt;Vec&lt;u32&gt;&gt;</code> will deep-clone the vector, cloning the <code>Arc</code> will just increment a referece count.</p><p>But the more important difference is what I call <em>“entanglement”</em>. When you clone the <code>Arc</code>, you don’t get a new value – you get back a <em>second handle to the same value</em>.<sup id="fnref:3"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:3">3</a></sup></p><h3>Entanglement changes the meaning of the program</h3><p>Knowing which values are “entangled” is key to understanding what your program does. A big part of how the borrow checker<sup id="fnref:4"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:4">4</a></sup> achieves reliability is by reducing “entaglement”, since it becomes a relative pain to work with in Rust.</p><p>Consider the following code. What will be the value of <code>l_before</code> and <code>l_after</code>?</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">l_before</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">v1</span><span class="p">.</span><span class="n">len</span><span class="p">();</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kd">let</span><span class="w"> </span><span class="n">v2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">v1</span><span class="p">.</span><span class="n">clone</span><span class="p">();</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">v2</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">new_value</span><span class="p">);</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kd">let</span><span class="w"> </span><span class="n">l_after</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">v1</span><span class="p">.</span><span class="n">len</span><span class="p">();</span><span class="w"></span></span></span></code></pre></div><p>The answer, of course, is “depends on the type of <code>v1</code>”. If <code>v1</code> is a <code>Vec</code>, then <code>l_after == l_before</code>. But if <code>v1</code> is, say, a struct like this one:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">struct</span> <span class="nc">SharedVec</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">data</span>: <span class="nc">Arc</span><span class="o">&lt;</span><span class="n">Mutex</span><span class="o">&lt;</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;&gt;</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="n">SharedVec</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">push</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">value</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">data</span><span class="p">.</span><span class="n">lock</span><span class="p">().</span><span class="n">unwrap</span><span class="p">().</span><span class="n">push</span><span class="p">(</span><span class="n">value</span><span class="p">);</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">len</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">usize</span> <span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">data</span><span class="p">.</span><span class="n">lock</span><span class="p">().</span><span class="n">unwrap</span><span class="p">().</span><span class="n">len</span><span class="p">()</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"></span></span></span></code></pre></div><p>then <code>l_after == l_before + 1</code>.</p><p>There are many types that act like a <code>SharedVec</code>: it’s true for <code>Rc</code> and <code>Arc</code>, of course, but also for things like <a href="https://docs.rs/bytes/latest/bytes/struct.Bytes.html"><code>Bytes</code></a> and channel endpoints like <a href="https://doc.rust-lang.org/std/sync/mpsc/struct.Sender.html"><code>Sender</code></a>. All of these are examples of “handles” to underlying values and, when you clone them, you get back a second handle that is indistinguishable from the first one.</p><h3>We have a name for this concept already: handles</h3><p>Jack’s insight was that we should focus on the <em>semantic concept</em> (sharing) and not on the operational details (how it’s implemented). This makes it clear when the trait ought to be implemented. I liked this idea a lot, although I eventually decided I didn’t like the name <code>Share</code>. The word isn’t specific enough, I felt, and users might not realize it referred to a specific concept: “shareable types” doesn’t really sound right. But in fact there <em>is</em> a name already in common use for this concept: handles (see e.g. <a href="https://docs.rs/tokio/latest/tokio/runtime/struct.Handle.html"><code>tokio::runtime::Handle</code></a>).</p><p>This is how I arrived at my proposed name and definition for The Trait, which is <code>Handle</code>:<sup id="fnref:5"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:5">5</a></sup></p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="sd">/// Indicates that this type is a *handle* to some</span></span></span><span class="line"><span class="cl"><span class="sd">/// underlying resource. The `handle` method is</span></span></span><span class="line"><span class="cl"><span class="sd">/// used to get a fresh handle.</span></span></span><span class="line"><span class="cl"><span class="sd"></span><span class="k">trait</span><span class="w"> </span><span class="n">Handle</span>: <span class="nb">Clone</span> <span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">final</span><span class="w"> </span><span class="k">fn</span> <span class="nf">handle</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Self</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Clone</span>::<span class="n">clone</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"></span></span></span></code></pre></div><h3>We would lint and advice people to call <code>handle</code></h3><p>The <code>Handle</code> trait includes a method <code>handle</code> which is <em>always</em> equivalent to <code>clone</code>. The purpose of this method is to signal to the reader that the result is a second handle to the same underlying value.</p><p>Once the <code>Handle</code> trait exists, we should lint on calls to <code>clone</code> when the receiver is known to implement <code>Handle</code> and encourage folks to call <code>handle</code> instead:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">impl</span><span class="w"> </span><span class="n">DataStore</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">fn</span> <span class="nf">store_map</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">map</span>: <span class="kp">&amp;</span><span class="nc">Arc</span><span class="o">&lt;</span><span class="n">HashMap</span><span class="o">&lt;..</span><span class="p">.</span><span class="o">&gt;&gt;</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">stored_map</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">map</span><span class="p">.</span><span class="n">clone</span><span class="p">();</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// -----</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">//</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// Lint: convert `clone` to `handle` for</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// greater clarity.</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"></span></span></span></code></pre></div><p>Compare the above to the version that the lint suggests, using <code>handle</code>, and I think you will get an idea for how <code>handle</code> increases clarity of what is happening:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="k">impl</span><span class="w"> </span><span class="n">DataStore</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">fn</span> <span class="nf">store_map</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">map</span>: <span class="kp">&amp;</span><span class="nc">Arc</span><span class="o">&lt;</span><span class="n">HashMap</span><span class="o">&lt;..</span><span class="p">.</span><span class="o">&gt;&gt;</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">stored_map</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">map</span><span class="p">.</span><span class="n">handle</span><span class="p">();</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"></span></span></span></code></pre></div><h3>What it means to be a <em>handle</em></h3><p>The defining characteristic of a <em>handle</em> is that it, when cloned, results in a second value that accesses the same underlying value. This means that the two handles are “entangled”, with interior mutation that affects one handle showing up in the other. Reflecting this, most handles have APIs that consist exclusively or almost exclusively of <code>&amp;self</code> methods, since having unique access to the <em>handle</em> does not necessarily give you unique access to the <em>value</em>.</p><p>Handles are generally only significant, semantically, when interior mutability is involved. There’s nothing <em>wrong</em> with having two handles to an immutable value, but it’s not generally distinguishable from two copies of the same value. This makes persistent collections an interesting grey area: I would probably implement <code>Handle</code> for something like <code>im::Vec&lt;T&gt;</code>, particularly since something like a <code>im::Vec&lt;Cell&lt;u32&gt;&gt;</code> <em>would</em> make entaglement visible, but I think there’s an argument against it.</p><h3>Handles in the stdlib</h3><p>In the stdlib, handle would be implemented for exactly one <code>Copy</code> type (the others are values):</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="c1">// Shared references, when cloned (or copied),</span></span></span><span class="line"><span class="cl"><span class="c1">// create a second reference:</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span>: <span class="o">?</span><span class="nb">Sized</span><span class="o">&gt;</span><span class="w"> </span><span class="n">Handle</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="o">&amp;</span><span class="n">T</span><span class="w"> </span><span class="p">{}</span><span class="w"></span></span></span></code></pre></div><p>It would be implemented for ref-counted pointers (but not <code>Box</code>):</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="c1">// Ref-counted pointers, when cloned,</span></span></span><span class="line"><span class="cl"><span class="c1">// create a second reference:</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span>: <span class="o">?</span><span class="nb">Sized</span><span class="o">&gt;</span><span class="w"> </span><span class="n">Handle</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">Rc</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span>: <span class="o">?</span><span class="nb">Sized</span><span class="o">&gt;</span><span class="w"> </span><span class="n">Handle</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">Arc</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span></span></span></code></pre></div><p>And it would be implemented for types like channel endpoints, that are implemented with a ref-counted value under the hood:</p><div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="c1">// mpsc "senders", when cloned, create a</span></span></span><span class="line"><span class="cl"><span class="c1">// second sender to the same underlying channel:</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span>: <span class="o">?</span><span class="nb">Sized</span><span class="o">&gt;</span><span class="w"> </span><span class="n">Handle</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">mpsc</span>::<span class="n">Sender</span><span class="w"> </span><span class="p">{}</span><span class="w"></span></span></span></code></pre></div><h3>Conclusion: a design axiom emerges</h3><p>OK, I’m going to stop there with this “byte-sized” blog post. More to come! But before I go, let me layout what I believe to be a useful “design axiom” that we should adopt for this design:</p><blockquote><p><strong>Expose entanglement.</strong> Understanding the difference between a <em>handle</em> to an underlying value and the value itself is necessary to understand how Rust works.</p></blockquote><p>The phrasing feels a bit awkward, but I think it is the key bit anyway.</p><div class="footnotes"><hr /><ol><li id="fn:1"><p>That. my friends, is <em>foreshadowing</em>. Damn I’m good. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:1">↩︎</a></p></li><li id="fn:2"><p>I described <code>Claim</code> as a kind of “lightweight clone” but in the Unconf someone pointed out that “heavyweight copy” was probably a better description of what I was going for. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:2">↩︎</a></p></li><li id="fn:3"><p>And, not coincidentally, the types where cloning leads to entanglement tend to also be the types where cloning is cheap. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:3">↩︎</a></p></li><li id="fn:4"><p>and functional programming… <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:4">↩︎</a></p></li><li id="fn:5"><p>The “final” keyword was proposed by Josh Triplett in RFC 3678. It means that impls cannot change the definition of <code>Handle::handle</code>. There’s been some back-and-forth on whether it ought to be renamed or made more general or what have you; all I know is, I find it an incredibly useful concept for cases like this, where you want users to be able to opt-in to a method being <em>available</em> but <em>not</em> be able to change what it does. You can do this in other ways, they’re just weirder. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:5">↩︎</a></p></li></ol></div></description> <pubDate>Tue, 07 Oct 2025 14:04:55 +0000</pubDate></item><item> <title>Firefox Nightly: Smarter Search, Smoother Tools – These Weeks in Firefox: Issue 190</title> <guid isPermaLink="false">https://blog.nightly.mozilla.org/?p=1908</guid> <link>https://blog.nightly.mozilla.org/2025/10/06/smarter-search-smoother-tools-these-weeks-in-firefox-issue-190/</link> <description><h3>Highlights</h3><ul><li>Google Lens support has been <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1990369">turned on by default</a> in the latest nightly builds.<ul><li>When Google is your default search engine, and you right click an image you’ll see a new context menu entry:</li></ul></li></ul><p><img alt="Context menu entry: Search Image with Google Lens" class="alignnone size-large wp-image-1907" height="328" src="https://blog.nightly.mozilla.org/files/2025/10/headlines190_3-600x328.png" width="600" /></p><ul><li>Semantic history search has now also been <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1988990">enabled</a> in the latest nightly and beta builds.<ul><li>This uses a local machine learning model to suggest entries from history that are related to your searches based on natural language understanding in the address bar.</li></ul></li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=283262">Alexandre Poirot [:ochameau]</a> improved the editor by displaying an editor widget where you can navigate between the different calls to a given function (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1908889">#1908889</a>)</li></ul><p><img alt="DevTools is displaying an editor widget" class="alignnone size-large wp-image-1906" height="493" src="https://blog.nightly.mozilla.org/files/2025/10/headlines190_2-600x493.png" width="600" /></p><ul><li>The WebExtension cookies.set API method rejection on invalid cookies is riding the Firefox 145 release train (after it has been kept as a nightly only behavior for 3 nightly cycles) – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1976509">Bug 1976509</a></li></ul><p> </p><h3>Friends of the Firefox team</h3><h4><a href="https://bugzilla.mozilla.org/buglist.cgi?title=Resolved%20bugs%20(excluding%20employees)&amp;quicksearch=1892101%2C1969417%2C1979919%2C1689380%2C1982968%2C1984296%2C1982767%2C1981384%2C1984788%2C1813675%2C1583902%2C1956493%2C1984661%2C1679997%2C1787457%2C1984872">Resolved bugs (excluding employees)</a></h4><h4>Volunteers that fixed more than one bug</h4><ul><li>Isaac Briandt</li></ul><h4>New contributors (🌟 = first patch)</h4><ul><li>David [:david-loe] <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1986237">improved accessibility of timepicker</a></li><li>Isaac Briandt updated<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1981244"> build-bergamot.py and upload-bergamot.py to utilize zstd compression</a> and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982594">updated Translations RemoteSettings schemas</a></li><li>🌟 Vlad L <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1881524">updated ipv6 representation algorithm</a></li></ul><h3>Project Updates</h3><h4>Add-ons / Web Extensions</h4><h5>Addon Manager &amp; about:addons</h5><ul><li>As part of finalizing the Add-ons telemetry migration from legacy telemetry to Glean, the EnvironmentAddonBuilder (responsible for collecting the activeAddons/Theme/GMPlugins metrics in Glean and mirror it in the legacy telemetry environment) has been refactored out of the TelemetryEnvironment ES module – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1981496">Bug 1981496</a></li></ul><h4>DevTools</h4><ul><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=446518">Sebastian Zartner [:sebo]</a> added inactive CSS icon when overflow* properties are used in non-block, non-flex, non-grid containers (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1583898">#1583898</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=750915">Artem Manushenkov</a> fixed a memory leak in the Inspector (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1986144">#1986144</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=763731">Holger Benl [:hbenl]</a> fixed an issue where screenshots taken in Responsive Design Mode could have unexpected dimensions (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979518">#1979518</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=557153">Nicolas Chevobbe [:nchevobbe]</a> made the Accessibility panel color simulation persist on page reload (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1770707">#1770707</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=283262">Alexandre Poirot [:ochameau]</a> fixed a Debugger crash that could happen when clicking on stacktrace frames from the console (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1985446">#1985446</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=656417">Hubert Boma Manilla (:bomsy)</a> fixed Debugger pretty printing of sources containing characters represented by more than one code unit (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1985689">#1985689</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=656417">Hubert Boma Manilla (:bomsy)</a> updated the version of Babel which we’re using to handle top level await detection, which fixed a few issues (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1900314">#1900314</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=283262">Alexandre Poirot [:ochameau]</a> fixed an issue in the Network pane (reported by Jake), where the search would never complete (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1983792">#1983792</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=559949">Julian Descottes [:jdescottes]</a> fixed a Network Monitor crash that was occurring when setting network override on requests requiring CORS preflight (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1986615">#1986615</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=557153">Nicolas Chevobbe [:nchevobbe]</a> fixed an issue that was affecting the Changes panel on pages with multiple documents (that includes the Browser Toolbox) (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1798774">#1798774</a>)</li></ul><h4>WebDriver BiDi</h4><ul><li>Henrik <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1988250">disabled the BackupService component by default for the Remote Protocol</a> (Marionette / WebDriver BiDi), as it isn’t required for web automation tasks.</li><li>Julian <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1970293">implemented the `browsingContext.downloadEnd` event</a>, which is emitted either when a download is completed or canceled.</li><li>Sasha implemented the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1987935">“emulation.setUserAgentOverride” command</a> for WebDriver BiDi, allowing clients to override the user agent string per browsing context, user context, or globally in Firefox + also fixed <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1705326">Bug 1705326 – navigator.userAgent still returns custom UA after clearing browsingContext.customUserAgent if a reload happened while the custom UA was set</a></li><li>Bug fixes<ul><li>Julian <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1986938">updated the browsingContext.downloadWillBegin event to emit the correct `navigation` id</a>, either the same one as the corresponding `browsingContext.navigationStarted` event, or null if the download was started by a link with a `download` attribute.</li><li>Julian fixed a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1986615">crash occurring when `network.provideResponse` was used</a> to override a response requiring a CORS preflight.</li><li>Julian fixed a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1989919">bug with network events incorrectly flagged as blocked</a> (`isBlocked=true`), even if they were not blocked for technical reasons – eg. coming from memory cache or using `data` scheme.</li><li>Julian updated the `network.beforeRequestSent` events to have <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1985552">`destination` set to “document” for top-level loads</a>.</li><li>Julian fixed an encoding issue with `network.getData` which will now <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1986022">always use utf-8 when serializing as text</a>.</li><li>Julian also updated `network.getData` to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1986025">no longer throw if the response body is empty</a>.</li></ul></li></ul><h4>Lint, Docs and Workflow</h4><ul><li><a href="https://blog.nightly.mozilla.org/2025/09/19/add-ons-fixes-and-devtools-snacks-these-weeks-in-firefox-issue-188/#:~:text=We%E2%80%99re,reviewbot,-%2E">First mentioned a month ago</a>, the tier-3 TypeScript linter has <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1990475">now been fixed</a> so that it runs when the components it watches are touched. Previously it would only be run when the type information was changed.</li><li>ESLint<ul><li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1991124">We discovered</a> the <a href="https://searchfox.org/firefox-main/source/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/require-jsdoc.mjs">require-jsdoc rules</a> were not being applied due to a mistake when upgrading to flat config or ESLint v9. These have now been re-enabled, with follow-ups being landed to fix the new issues raised since the mistake was introduced.</li><li>The <a href="https://firefox-source-docs.mozilla.org/code-quality/lint/linters/eslint-plugin-mozilla/rules/no-browser-refs-in-toolkit.html">no-browser-refs-in-toolkit rule</a> has now <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1990309">been promoted to an error</a>, except for cases where it currently fails (stays as a warning). Please avoid introducing new cases.</li><li>The <a href="https://github.com/eslint/config-inspector">ESLint configuration inspector</a> should <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1990241">now be working</a> when run against firefox-main. This is a very useful tool for inspecting the configuration and determining which globals and rules are applied to which files.</li><li>Gijs <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1971088">updated</a> our documentation for <a href="https://firefox-source-docs.mozilla.org/code-quality/lint/linters/eslint.html#i-have-valid-code-that-is-failing-the-no-undef-rule-or-can-t-be-parsed">ESLint environments</a>, which no longer work in the same way with v9.<ul><li>/** eslint-env foo */ no longer works.</li><li>The files either need the correct extensions, or adding to eslint-file-globals.config.mjs. See <a href="https://searchfox.org/firefox-main/rev/9140dac1eab834541a75792a78a5ed2fbee39142/eslint-file-globals.config.mjs#5-21">the comments at the top of the file</a> for more information.</li></ul></li></ul></li></ul><h4>Information Management/Sidebar</h4><ul><li>There’s been a few fixes for the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1970666">drag-to-pin work</a> that’s in 143; these will be in the dot release.<ul><li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1988996">Add a check for promo card to ensure we don’t show it prematurely</a></li><li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1989344">1989344 – Adjust interaction cue timing for drag to pin</a></li></ul></li><li>Nikki has improved tab animation for vertical and horizontal tabs with <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1983124">tab stacking</a></li><li>Split View work is still early days but the meta bug is <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1980370">here</a>.</li><li>We’re aiming to get sidebar.revamp turned on by default in Nightly only in 145 so we’re greening up a few tests then work on some old sidebar parity bugs before enabling this in release.</li></ul><h4>Profile Management</h4><ul><li>Jared fixed bug 1941854, [Windows] Additional window (skeleton UI) opens with Profile Selector on Firefox startup</li><li>Maile fixed bug 1955173, The favicons of the Profiles about: pages are not displayed properly in the List all tabs menu</li><li>Niklas fixed bug 1965598, The Usage Profile Group ID should be shared by all profiles in a group</li><li>Jaws fixed bug 1987317, Firefox won’t launch a profile if the library of that profile is open</li><li>Jaws fixed bug 1988882, SelectableProfileService uses the wrong value for the rgb color property</li><li>Jaws fixed bug 1990020, Small fixes in SelectableProfileService</li></ul><h4>Search and Navigation</h4><ul><li>Work continues on modularising and re-using the address bar code to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1974218">replace the existing search bar</a>.<ul><li>This will allow us to simplify the existing code, remove dependence on the toolkit autocomplete widget, and bring more features to the separate search bar.</li></ul></li><li></li><li>Search Engines identifiers and telemetry.<ul><li>We’ve now <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1877721">removed</a> nsISearchEngine.identifier, and deprecated nsISearchEngine.telemetryId. nsISearchEngine.id still exists.<ul><li>These are fields that would contain a mixture of information about a search engine (an identifier, partner code and sometimes more). This would analysis via telemetry more difficult.</li></ul></li><li>If you’re reporting search engine information either via telemetry or to other systems, please use the separate id / partnerCode fields on nsISearchEngine or check with the search team for your case.</li></ul></li></ul><h4>Storybook/Reusable Components/Acorn Design System</h4><ul><li>moz-button supports type=”split”(<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1858811">Bug 1858811</a>). Setting menuId on the split button links its “More options” button to a panel-list with the same id. (<a href="https://firefoxux.github.io/firefox-desktop-components/?path=/story/ui-widgets-button--split-button">Storybook</a>)</li></ul><p><img alt="Split button component" class="alignnone size-large wp-image-1905" height="308" src="https://blog.nightly.mozilla.org/files/2025/10/headlines190_1-600x308.png" width="600" /></p><ul><li>Support for the support-page attribute was added to the moz-box-item (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1990839">Bug 1990839</a>)</li><li>New –font-size-xxlarge (2.2rem – 33px) token was added. (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1961988">Bug 1961988</a>)</li><li>Usage of border-radius was updated to use design tokens values (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1983938">Bug 1983938</a>)</li></ul></description> <pubDate>Mon, 06 Oct 2025 20:11:37 +0000</pubDate> <dc:creator>Anna Kulyk</dc:creator></item><item> <title>Mozilla Thunderbird: VIDEO: Conversation View</title> <guid isPermaLink="false">https://blog.thunderbird.net/?p=3830</guid> <link>https://blog.thunderbird.net/2025/10/video-conversation-view/</link> <description><p><img alt="" class="attachment-640x360 size-640x360 wp-post-image" height="360" src="https://blog.thunderbird.net/files/2025/10/blog-banner-community-hours2-768x432.jpg" width="640" /></p><p>Welcome back to another edition of the Community Office Hours! This month, we’re showing you our first steps towards a long awaited feature: a genuine Conversation View! Our guests are Alessandro Castellani, Director of Desktop and Mobile Apps and Geoff Lankow, Sr. Staff Software Engineer on the Desktop team. They recently attended a work week in Vancouver that brought together developers and designers to create our initial vision and plan to bring Conversation View from dream to reality. Before Geoff flew home, he joined Alessandro and us to discuss his backend database work that will make Conversation View possible. We also had a peek at the workweek itself, other features possible with our new database, and our tentative delivery timeline.</p> <p>We’ll be back next month with an Office Hours all about Exchange Support for email, which is landing soon in our monthly Release channel. </p> <h3>September Office Hours: Conversation View</h3> <p>Some of you might be asking, “what IS Conversation View?” Basically, it’s a Gmail-like visualization of a message thread when reading emails. So, in contrast to the current threaded view, you have all the messages in a thread. This both includes your replies and any other messages that may have been moved to a different folder.</p> <p>So, why hasn’t Thunderbird been able to do this already? The short answer is that our code is old. Netscape Navigator old. Our current ‘database,’ Mork, makes a mail folder summary (an .msf file) per folder. These files are text-based unicode and are NOT human readable. In Thunderbird 3, we introduced Gloda, our Global Search and Indexer, to try and work around Mork’s limitations. It indexes what’s in the .msf file and stores the data in a SQLite file. But as you might already know, Gloda itself is clunky and slow.</p> <h3>Modern Solutions for Modern Problems</h3> <p>If we want Conversation View (and other features users now expect), we need to bring Thunderbird further into the 21st century. Hence, our work on a new database, which we’re calling Panorama. It’s a single SQLite database with all your messages. Panorama indexes emails as soon as they’re received, and since it’s SQLite, it’s not only fast, but it can be read by so many tools.</p> <p>Since all of your messages will be in a single SQLite database, we can do more than enable a true Conversation view. Panorama will improve global search, enable improved filters, and more. Needless to say, we’re excited about all the possibilities!</p> <h3>Conversation View Workweek</h3> <p>To get these possibilities started, we decided to bring developers and designers together for a Conversation View Workweek in Vancouver in early September. This brought people out of Zoom calls, emails, and Matrix messages, and across the Pacific Ocean in Geoff’s case, into one place to discuss technical and design challenges. </p> <p>We’ve spoken previously about our design system and how we’ve collaborated between <a href="https://blog.thunderbird.net/2025/03/video-the-thunderbird-design-system/">design and development</a> on features like <a href="https://blog.thunderbird.net/2025/04/video-the-new-account-hub/">Account Hub</a>. In-person collaboration, especially for something as complicated as a new database and message view, was invaluable. By the end of the week, developers and designers alike had plenty to show for their efforts.</p> <h3>Next Steps</h3> <p>Before you get too excited, the new database and Conversation view won’t land until after next year’s ESR release. There’s a lot of work to do, including testing Panorama in a standalone space until we’re ready to run Mork and Panorama alongside each other, along with the old and new code referencing each database. We need the migration to be seamless and easily reversible, and so we want to take the time to get this absolutely right.</p> <p>Want to stay up to date on our progress? We recommend subscribing to our Planning and <a href="https://thunderbird.topicbox.com/groups/ux">UX</a> mailing lists, State of the Thunder <a href="https://www.youtube.com/playlist?list=PLMY3ZzVsXXyqSVZHS10hold60Uqb97xzD">videos</a> and <a href="https://blog.thunderbird.net/tag/state-of-the-thunder/">blog posts</a>, and the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1920833">meta bug on Bugzilla</a>.</p> <h4>VIDEO (Also <a href="https://tilvids.com/w/h1KPSVsB7BfL5LxtEU4PB6">on Peertube</a>):</h4> <figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper"> </div></figure> <h3>Slides:</h3> <div class="wp-block-file"><a href="https://blog.thunderbird.net/files/2025/10/Conversation-View-Community-Office-Hours-Presentation.pdf" id="wp-block-file--media-2d726133-12fc-4117-a5e6-734962ae66d2">Conversation-View-Community-Office-Hours-Presentation</a><a class="wp-block-file__button wp-element-button" href="https://blog.thunderbird.net/files/2025/10/Conversation-View-Community-Office-Hours-Presentation.pdf">Download</a></div> <h3>Resources:</h3><p>The post <a href="https://blog.thunderbird.net/2025/10/video-conversation-view/">VIDEO: Conversation View</a> appeared first on <a href="https://blog.thunderbird.net">The Thunderbird Blog</a>.</p></description> <pubDate>Mon, 06 Oct 2025 18:08:18 +0000</pubDate> <dc:creator>Monica Ayhens-Madon</dc:creator></item><item> <title>The Mozilla Blog: Building a fairer future for digital advertising: Mozilla partners with Index Exchange</title> <guid isPermaLink="false">https://blog.mozilla.org/?p=82082</guid> <link>https://blog.mozilla.org/en/advertising/index-exchange-partnership/</link> <description><figure class="wp-block-image size-large is-resized"><img alt="Black background featuring two white logos: ‘Mozilla Ads’ on the left and ‘Index Exchange’ on the right, separated by a thin vertical line." class="wp-image-82083" height="576" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2025/10/MozillaAds_AWNYFireside_10_03.006-1024x576.jpeg" style="width: 840px; height: auto;" width="1024" /></figure> <p>Advertising can and should work better — for people, for publishers, and for brands. That belief is what drives Mozilla’s growing investment in rebuilding digital advertising around trust, transparency and fairness.</p> <p>For too long, the web’s primary funding model has relied on hidden data collection and opaque ad systems that work around users instead of with them. Mozilla’s approach is different: We’re building an alternative that aligns commercial success with user respect, giving advertisers new ways to show up responsibly in environments people actually trust.<br /><br />“Advertising funds the open internet, but it needs a new foundation,” said Suba Vasudevan, COO of Mozilla.org and SVP at Mozilla Corp. “Advertisers have always cared about brand safety. The missing piece has been trust in the platforms where ads run. That’s the gap Mozilla is closing; making the advertising environment itself something that both brands and users can trust. And we do this all while protecting the privacy of our users’ data.”<br /><br />This week at Advertising Week New York 2025, Mozilla announced a key step in that journey — a partnership with Index Exchange, one of the world’s largest independent ad exchanges. Together, we’re proving that trusted environments can also deliver trusted performance.<br /><br />“Our partnership with Mozilla demonstrates how programmatic can evolve to create stronger outcomes for brands and better experiences for consumers,” said Lori Goode, CMO of Index Exchange. “By uniting Mozilla’s trusted environment with Index’s infrastructure, we’re building a model of programmatic rooted in quality, accountability, and long-term value.”</p> <h3>Creating a new model for responsible advertising</h3> <p>The collaboration between Mozilla and Index Exchange is part of a larger effort to evolve how advertising supports the open web. It’s about expanding options for marketers who want to reach audiences in ways that are both effective and ethical — replacing tracking-heavy systems with transparent, trust-centered design.</p> <p>• <strong>Scale where it matters.</strong> For marketers committed to building on trusted platforms, curated PMP deals with Mozilla and Index Exchange offer a way to connect with engaged audiences in respectful, brand-safe environments — aligning performance goals with user trust in the fastest-growing programmatic channel (~88% of global spend).</p> <p>• <strong>No personal identifiers. </strong>Mozilla and Index Exchange ensure that no personal identifiers or cross-site tracking are ever used — reflecting our shared commitment to respect users and create ad experiences people can trust.</p> <p>• <strong>Future-ready monetization. </strong>Firefox research shows that even privacy-minded users welcome thoughtful personalization when it improves their experience — but only when delivered responsibly and with clear user control.<br /><br />• <strong>A unique audience opportunity. </strong>Firefox reaches hundreds of millions of people worldwide, offering marketers the chance to build connections in a trusted, brand-safe environment with engaged audiences often underrepresented on other platforms.</p> <h3>On stage at Advertising Week New York</h3> <p>Mozilla and Index Exchange will debut the partnership during a keynote conversation, “Adding Trust to Your Ad Buy: The Smartest Spend in Marketing Today,” on the Advertising Week Innovation Stage, Monday, Oct. 6. The session will explore how advertisers can drive performance by investing in trust — not just in creative or campaigns, but in the platforms that power them.<br /><br />At Mozilla, we’ve always believed that advertising, done responsibly, can help sustain the open web. This partnership is proof of that belief — a tangible example of how innovation and trust can go hand in hand, delivering value for advertisers and for the internet itself. For more about Mozilla Ads, visit: <a href="https://www.mozilla.org/en-US/advertising/">https://www.mozilla.org/en-US/advertising/</a>.</p><p>The post <a href="https://blog.mozilla.org/en/advertising/index-exchange-partnership/">Building a fairer future for digital advertising: Mozilla partners with Index Exchange</a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p></description> <pubDate>Mon, 06 Oct 2025 16:53:52 +0000</pubDate> <dc:creator>Jennifer Guerra</dc:creator></item><item> <title>Support.Mozilla.Org: Ask a Fox: A full week celebration of community power</title> <guid isPermaLink="false">https://blog.mozilla.org/sumo/?p=4185</guid> <link>https://blog.mozilla.org/sumo/2025/10/02/ask-a-fox/</link> <description><p>From September 22–28, the Mozilla Support team ran our first-ever <a href="http://community.mozilla.org/campaigns/ask-a-fox/"><b>Mozilla – Ask a Fox</b></a> virtual hackathon. In collaboration with the Thunderbird team, we invited contributors, community members, and staff to jump into the Mozilla Community Forums, lend a hand to Firefox and Thunderbird users, and experience the power of Mozillians coming together.</p><h3>Rallying the Community</h3><p>The idea was simple: we want to bring not only our long time community members, but newcomers and Mozilla staff together for one-week of focused engagement. The result was extraordinary.</p><ul><li>The event generated strong momentum for both new and returning community members. This was reflected in the <b>significant growth in total contributors, which rose by 41.6 %</b>.</li><li>For the past year, our Community Forum had been struggling to maintain a strong reply rate as inbound questions grew. During the event, however, we achieved our <b>highest weekly reply rate of the year</b>, which was more than 50% above our daily average from the first half of 2025.</li><li><b>Time to first response (TTFR) also improved by 44.6%</b>, which signal significant improvement in community responsiveness. The event also highlighted the importance of time to first response (TTFR) not just for users, but for the community as a whole. We saw a clear correlation: <i>the faster users received their first reply, the more likely they were to return and continue the conversation.</i></li></ul><p>Together, we showed just how responsive and effective our community can be when we rally around a common goal.</p><h3>More Than Answering Forum Questions</h3><p>Ask a Fox wasn’t only about answering questions—it was about connection. Throughout the week, we hosted special AMAs with the <a href="https://www.youtube.com/watch?v=GFF5NBSN-8I&amp;t=2980s"><b>WebCompat</b></a>, <a href="https://www.youtube.com/watch?v=apYYhHJINFY&amp;t=3249s"><b>Web Performance</b></a>, and <a href="https://www.youtube.com/watch?v=ldnv11tF6iY&amp;t=245s"><b>Thunderbird</b></a> teams, giving contributors the chance to engage directly with product experts. We also ran two Community Get Together calls to gather, share stories, and celebrate the spirit of collaboration.</p><p>For some added fun, we also launched a and ⚡ emoji hunt accross our Knowledge Base articles.</p><h3>Recognizing contributors</h3><p>We’re grateful for the incredible participation during the event and want to recognize the contributors who went above and beyond. Those who participated in our challenges should receive exclusive <a href="https://support.mozilla.org/badges/">SUMO badges</a> in their profile by now. And the following top five contributors for each product will soon receive a $25 swag voucher from us to shop our limited-edition Ask a Fox swag collection, available in the <a href="https://mozilla-na.myspreadshop.com/ask+a+fox?collection=NfnWgqXmlH">NA</a>/<a href="https://mozilla-europe.myspreadshop.ie/ask+a+fox?collection=MHMWMgYnoP">EU</a> swag store.</p><p><b>Firefox desktop (including Enterprise)</b></p><p>Congrats to <a href="https://support.mozilla.org/user/plwt/">Paul</a><b>, </b><a href="https://support.mozilla.org/user/denyshon/">Denyshon</a>, <a href="https://support.mozilla.org/user/jonzn4SUSE/">Jonz4SUSE</a>, <a href="https://support.mozilla.org/user/@next/">@next</a>, and <a href="https://support.mozilla.org/user/jscher2000/">jscher2000</a>.</p><p><b>Firefox for Android</b></p><p>Congrats to <a href="https://support.mozilla.org/user/plwt/">Paul</a>, <a href="https://support.mozilla.org/en-US/user/TyDraniu/">TyDraniu</a>, <a href="https://support.mozilla.org/user/pcp04/">GerardoPcp04</a>, <a href="https://support.mozilla.org/user/Mad_Maks/">Mad_Maks</a>, and <a href="https://support.mozilla.org/user/sjohnn/">sjohnn</a>.</p><p><b>Firefox for iOS </b></p><p>Congratulations to <a href="https://support.mozilla.org/user/plwt/">Paul</a>, <a href="https://support.mozilla.org/user/simon.c.lord/">Simon.c.lord</a>, <a href="https://support.mozilla.org/en-US/user/TyDraniu/">TyDraniu</a>, <a href="https://support.mozilla.org/user/Mad_Maks/">Mad_Maks</a>, and <a href="https://support.mozilla.org/user/Mozilla-assistent/">Mozilla-assistent</a>.</p><p><b>Thunderbird (including Thunderbird for Android)</b></p><p>Congratulations to <a href="https://support.mozilla.org/user/davidsk/">Davidsk</a>, <a href="https://support.mozilla.org/user/sfhowes/">Sfhowes</a>, <a href="https://support.mozilla.org/user/mozilla98/">Mozilla98</a>, <a href="https://support.mozilla.org/user/MattAuSupport/">MattAuSupport</a>, and <a href="https://support.mozilla.org/user/christ1/">Christ1</a>.</p><p> </p><p>We also want to extend a warm welcome to newcomers who made impressive impact during the event: <a href="https://support.mozilla.org/user/mozilla98/">mozilla98</a>, <a href="https://support.mozilla.org/user/starretreat/">starretreat</a>, <a href="https://support.mozilla.org/user/sjohnn/">sjohnn</a>, <a href="https://support.mozilla.org/user/Vexi/">Vexi</a>, <a href="https://support.mozilla.org/user/Mark/">Mark</a>, <a href="https://support.mozilla.org/user/Mapenzi/">Mapenzi</a>, <a href="https://support.mozilla.org/user/cartdaniel437/">cartdaniel437</a>, <a href="https://support.mozilla.org/user/hariiee1277/">hariiee1277</a>, and <a href="https://support.mozilla.org/user/thisisharsh7/">thisisharsh7</a>.</p><p>And finally, congratulations to <a href="https://support.mozilla.org/user/Vinnl/">Vincent</a>, winner of the staff award for the highest number of replies during the week.</p><hr /><p>Ask a Fox was more than a campaign—it was a celebration of what makes Mozilla unique: a global community of people who care deeply about helping others and shaping a better web. Whether you answered one question or one hundred, your contribution mattered.</p><p>This event reminded us that when Mozillians come together, we can amplify our impact in powerful ways. And this is just the beginning—we’re excited to carry this momentum forward, continue improving the Community Forums, and build an even stronger, more responsive Mozilla community for everyone.</p></description> <pubDate>Thu, 02 Oct 2025 09:57:47 +0000</pubDate> <dc:creator>Rizki Kelimutu</dc:creator></item><item> <title>Mozilla Localization (L10N): Localizer Spotlight: Selim</title> <guid isPermaLink="false">https://blog.mozilla.org/l10n/?p=1784</guid> <link>https://blog.mozilla.org/l10n/2025/09/30/localizer-spotlight-selim/</link> <description><p style="text-align: left;"><b>About You</b></p><p>My name is <a href="https://pontoon.mozilla.org/contributors/Qkxrfae9uxCIC_PmnqAsJREVw8U/">Selim</a> and I’m the Turkish localization manager. I’m from İstanbul, Türkiye. I’ve been contributing to Mozilla since 2010.</p><p><b>Your Contributions</b></p><div class="wp-caption alignright" id="attachment_1785" style="width: 444px;"><a href="https://blog.mozilla.org/l10n/files/2025/09/selim-brussels.jpg"><img alt="Selim (first left) with fellow Turkish Mozillians Onur, Didem and Serkan (Mozilla Summit Brussels)" class="wp-image-1785" height="287" src="https://blog.mozilla.org/l10n/files/2025/09/selim-brussels-e1759172589317-600x397.jpg" width="434" /></a><p class="wp-caption-text" id="caption-attachment-1785">Selim (first left) with fellow Turkish Mozillians Onur, Didem and Serkan (Mozilla Summit Brussels)</p></div><p><em><strong>Q:</strong> Over the years, do you remember how many projects you’ve been involved in (including ones that may no longer exist)?</em></p><p><strong>A:</strong> It’s been so many! I began with Firefox 15 years ago, but I think I’ve been involved in around 30 projects over the years. We currently have 23 projects active in Pontoon, and I’ve been involved in every single one of them to some degree.</p><p><em><strong>Q:</strong> Roughly how many Mozilla events have you joined — whether localization meetups, company-wide gatherings, MozFest, or others?</em></p><p><strong>A: </strong>I’ve attended six of them. My first one was the Mozilla Balkans Meetup 2011 in Sofia. Then I had the chance to meet fellow Mozillians in Zagreb, Brussels, Berlin, Paris, and my hometown İstanbul. They were all great experiences, both enlightening and rewarding.</p><p><em><strong>Q:</strong> Looking back, are there any contributions or milestones you feel especially proud of?</em></p><p><strong>A:</strong> When I first began contributing, my intention was to complete a few missing translations I had noticed in Firefox. However, I quickly realized that the project was huge and there was much more to it than met the eye. Its Turkish localization was around 85% complete at that time, but the community lacked the resources to push it forward. I took it as my duty to reach 100% first, and then spellcheck and fix all existing translations. It took me a few months to get there, but Firefox has clearly had the best Turkish localization among all browsers ever since.</p><p><b>Your Background</b></p><p><em><strong>Q:</strong> Does your professional background support or connect with your work in localization?</em></p><p><strong>A:</strong> I currently work as a freelance editor and translator, translating and editing print magazines (mostly tech, popular science, and general knowledge titles), and localizing software and websites.</p><p>And the event that kickstarted my career in publishing and professional translation was volunteering for localization. (No, not Firefox. It didn’t even exist yet!) Back in high school, I began localizing an open-source CMS called PHP-Nuke to be used on my school’s website. PHP-Nuke became very popular in a short amount of time, and a computer magazine editor approached me to build the magazine’s website using open-source tools, including PHP-Nuke. I’ve been an avid reader of those magazines since my childhood but never imagined that one day I’d be working for Türkiye’s best-selling computer magazine!</p><p>In time, I began translating and writing articles for the magazine as a freelancer and joined the editorial staff after graduating from university.</p><p>I’ve written hundreds of software and website reviews and kept noticing that some of them were high-quality products that needed better localization. Now, with a better understanding of how things work and with some technical background, I began contributing to more and more open-source projects in my free time, and Firefox was one of them.</p><p>I was lucky that the previous Turkish contributors did a great job “localizing” Firefox, not just translating it. I learned a great deal from them, and it had a huge impact on my later professional work.</p><p>I was also approached and/or approved by several clients who had seen my volunteer localization work.</p><p>So, in a way, my professional background does support my work in localization — and vice versa.</p><p><em><strong>Q:</strong> In what ways has being part of Mozilla’s localization community influenced you — whether in problem-solving, leadership, or collaborating across cultures?</em></p><p><strong>A:</strong> Once I started contributing, I quickly realized that Mozilla had something none of the other projects I had contributed to previously had: a community that I felt part of. These people <i>loved </i>the internet, and they were having fun localizing stuff, just like me.</p><p>The localization community helped me improve myself both professionally and personally in a lot of ways: I learned how to collaborate better with a team of volunteers from different backgrounds, how to use different translation tools, how to properly report bugs, how to deal with different time zones, and how to get out of my comfort zone and talk to people from abroad both in virtual and face-to-face events.</p><p><b>Your Community</b></p><p><em><strong>Q:</strong> As a long-time contributor, what motivates you to continue after all these years?</em></p><p><strong>A:</strong> First and foremost, I believe in Mozilla’s mission wholeheartedly. But there’s a practical motivation too: Turkish is spoken by tens of millions of people, so the potential impact of localization is huge. Ensuring my fellow nationals have access to high-quality, localized open-source software is a driving force. And I’m still having fun doing it!</p><p><em><strong>Q:</strong> Many communities struggle with onboarding or retaining contributors, especially after COVID limited in-person events. What are the challenges you face as a manager and how do you address them? And how do you engage with active contributors today? Do you have a process or approach for welcoming newcomers?</em></p><p><strong>A:</strong> The Turkish community had its fair share of struggles with onboarding and retaining contributors, but it never became a huge challenge because of an advantage we had: The first iteration of the community started very early. Firefox 1.0 was already available in Turkish, and they maintained a good localization percentage for most Mozilla products, even if not 100%. So when I joined, there were things to do but not a single project that needed to be started from scratch. They were maintainable by one or two enthusiastic localizers. And when I took on the manager role, I always tried to keep it that way. I did approve a number of new projects, but not before ensuring that we had the resources to always keep them at least 90% complete.</p><p>But that creates a dilemma: New Turkish contributors usually face strings that are harder to grasp without context or are more difficult to translate, because the easier and more visible strings have already been translated. I guess that makes newcomers frustrated and they leave after translating a few strings. In fact, over the past 10 years, we’ve had only one contributor (<a href="https://pontoon.mozilla.org/contributors/VB0eftwM_mnLHjP8UDNrurc_mzk/">Grk</a>) who has translated more than 10,000 strings (apart from myself), and two contributors (<a href="https://pontoon.mozilla.org/contributors/tQetFmUNDeSWuQYsEjhTDVQdyNw/">Ali</a> and <a href="https://pontoon.mozilla.org/contributors/rLfANGZKSoM1QVtAYg9lpSI6qro/">Osman</a>) with more than 1,000 strings. I’d like to thank them once again for their awesome contributions.</p><p>The Turkish community has always been very small: just a few people contributing at a time, and that has worked for us. So I’m not anxiously trying to onboard or retain contributors, but if I see an enthusiastic newcomer, I try to guide them by commenting on their translations or sending a welcome email to let them know how things work.</p><p><b>Something Fun</b><br /><em><strong>Q:</strong> Could you share a few fun or unexpected facts about yourself that people might not know?</em></p><p><strong>A: </strong>Certainly:</p><ul><li>I’m a metalhead, and the first thing I ever translated as a hobby was the lyrics of a Sentenced song. I’ve been translating song lyrics ever since, and <a href="https://www.sozbuyucusu.com/">I have a blog</a> where I publish them.</li><li>My favorite documentary is <a href="https://en.wikipedia.org/wiki/Helvetica_(film)"><i>Helvetica</i></a>.</li><li>I built my first website when I was 13, by manually typing HTML in Windows Notepad. That’s when I discovered the internet’s endless possibilities and fell in love with it.</li></ul></description> <pubDate>Tue, 30 Sep 2025 00:03:10 +0000</pubDate> <dc:creator>Peiying Mo</dc:creator></item><item> <title>Matthew Gaudet: Summer of Sharpening</title> <guid isPermaLink="false">52c2f0cde4b0537e2cba526e:57f70c5c440243051b0c3ce8:68dab97df724e53f95683011</guid> <link>https://www.mgaudet.ca/technical/2025/9/29/summer-of-sharpening</link> <description><p>As we head into fall, I wanted to write up a bit of an experience report on a project I ran this summer with a few other people on the SpiderMonkey team. </p><p>A few of us on the team chose to block off some time during the summer to do intentional professional development. Exploring topics that we hadn’t looked into, often due to a feeling of time starvation.</p><p>Myself, I blocked off 2 hours every Friday through the summer. </p><p>In order to turn this into a <strong>team</strong> exercise, rather than just a personal development period, I create a shared document where I encouraged people to write up their experiments, so that we could read about their exploits. </p><h3>How did it go?</h3><p>Well, I don’t think -anyone- did 2 hours every week But I think most people did a little bit of exploration. </p><p>I’ve blogged already a bit about some of the topics I worked on for sharpening time: <a href="https://www.mgaudet.ca/technical/2025/5/28/exploring-a-language-runtime-with-bpftrace">Both my</a> blog posts <a href="https://www.mgaudet.ca/technical/2025/5/28/finding-hot-allocation-sites-with-bpftrace">about eBPF</a> were a result of this practice. Other things I looked into that I didn’t get a chance to blog about include: </p><ul><li>Learning about Instruments, and in particular Processor Trace (so painfully slow)</li><li>Exploring <a href="https://github.com/plasma-umass/coz">Coz</a>, the causal profiler (really focused on multihreaded workloads in a way that didn’t produce value for me)</li><li>Playing with Zed (clangd so slow for some reason)</li><li>‘vibe coding’ (AI can do some things, but man, local minima are a pain).</li><li>Exploring different options for Android emulation</li><li>Watching WWDC videos on performance optimization (nice overview, mostly stuff I knew).</li></ul><p>I was very happy overall with the results, and have already created another document for next year to capture some ideas that we could look into next year. </p></description> <pubDate>Mon, 29 Sep 2025 16:54:00 +0000</pubDate> <dc:creator>Matthew Gaudet</dc:creator></item><item> <title>The Servo Blog: This month in Servo: variable fonts, network tools, SVG, and more!</title> <guid isPermaLink="true">https://servo.org/blog/2025/09/25/this-month-in-servo/</guid> <link>https://servo.org/blog/2025/09/25/this-month-in-servo/</link> <description><p>Another month, another record number of pull requests merged!August flew by, and with it came <strong>447 pull requests</strong> from Servo contributors.It was also the final month of our <a href="https://www.outreachy.org/">Outreachy</a> cohort; you can read <a href="https://www.jerensl.com/blog/en-final-project-progress-outreachy/">Jerens’</a> and <a href="https://uthmaniv.github.io/">Uthman’s</a> blogs to learn about how it went!</p><h3>Highlights <a class="header-anchor" href="https://servo.org/blog/2025/09/25/this-month-in-servo/#highlights"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><p>Our big new feature this month is rendering <strong>inline SVG elements</strong> (<a href="https://github.com/mukilan">@mukilan</a>, <a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/servo/servo/pull/38188">#38188</a>, <a href="https://github.com/servo/servo/pull/38603">#38603</a>).This improves the appearance of many popular websites.</p><figure> <a href="https://servo.org/img/blog/2025-09-svg.png"><img alt="Screenshot of servoshell with the Google homepage loaded" src="https://servo.org/img/blog/2025-09-svg.png" /></a> &lt;figcaption&gt;Did you know that the Google logo is an SVG element?&lt;/figcaption&gt;</figure><p>We have implemented <strong>named grid line lines and areas</strong> (<a href="https://github.com/nicoburns">@nicoburns</a>, <a href="https://github.com/loirooriol">@loirooriol</a>, <a href="https://github.com/servo/servo/pull/38306">#38306</a>, <a href="https://github.com/servo/servo/pull/38574">#38574</a>, <a href="https://github.com/servo/servo/pull/38493">#38493</a>), still gated behind the <code>layout_grid_enabled</code> preference (<a href="https://github.com/servo/servo/pull/38306">#38306</a>, <a href="https://github.com/servo/servo/pull/38574">#38574</a>).</p><figure> <a href="https://servo.org/img/blog/2025-09-grid.jpg"><img alt="Screenshot of servoshell loading a page demoing a complex grid layout" src="https://servo.org/img/blog/2025-09-grid.jpg" /></a> &lt;figcaption&gt;CSS grids are all around us.&lt;/figcaption&gt;</figure><p>Servo now supports CSS <strong>‘font-variation-settings’</strong> on all main desktop platforms (<a href="https://github.com/simonwuelker">@simonwuelker</a>, <a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/38642">#38642</a>, <a href="https://github.com/servo/servo/pull/38760">#38760</a>, <a href="https://github.com/servo/servo/pull/38831">#38831</a>).This feature is currently gated behind the <code>layout_variable_fonts_enabled</code> preference.We also respect <code>format(*-variations)</code> inside <code>@font-face</code> rules (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/38832">#38832</a>).Additionally, Servo now reads data from <strong>OpenType Collection (.ttc)</strong> system font files on macOS (<a href="https://github.com/nicoburns">@nicoburns</a>, <a href="https://github.com/servo/servo/pull/38753">#38753</a>), and uses <code>Helvetica</code> for the <strong>‘system-ui’</strong> font (<a href="https://github.com/dpogue">@dpogue</a>, <a href="https://github.com/servo/servo/pull/39001">#39001</a>).</p><figure> <details> <img alt="servoshell nightly showcasing variable fonts, with variable weight (`wght`) values smoothly increasing and decreasing (click to pause)" src="https://servo.org/img/blog/2025-09-variations.webp" style="margin: 0;" /> <img src="https://servo.org/img/blog/2025-09-variations-preview.png" style="margin: 0;" /><div alt="servoshell nightly showcasing variable fonts, with variable weight (`wght`) values smoothly increasing and decreasing (click to play)">▶</div> </details> &lt;figcaption&gt;This font can be customized!&lt;/figcaption&gt;</figure><p>Our <a href="https://book.servo.org/hacking/using-devtools.html">developer tools</a> continue to make progress!We now have a functional <strong>network monitor</strong> panel (<a href="https://github.com/uthmaniv">@uthmaniv</a>, <a href="https://github.com/jdm">@jdm</a>, <a href="https://github.com/servo/servo/pull/38216">#38216</a>, <a href="https://github.com/servo/servo/pull/38601">#38601</a>, <a href="https://github.com/servo/servo/pull/38625">#38625</a>),and our JS debugger can show potential breakpoints (<a href="https://github.com/delan">@delan</a>, <a href="https://github.com/atbrakhi">@atbrakhi</a>, <a href="https://github.com/servo/servo/pull/38331">#38331</a>, <a href="https://github.com/servo/servo/pull/38363">#38363</a>, <a href="https://github.com/servo/servo/pull/38333">#38333</a>, <a href="https://github.com/servo/servo/pull/38551">#38551</a>, <a href="https://github.com/servo/servo/pull/38550">#38550</a>, <a href="https://github.com/servo/servo/pull/38334">#38334</a>, <a href="https://github.com/servo/servo/pull/38624">#38624</a>, <a href="https://github.com/servo/servo/pull/38826">#38826</a>, <a href="https://github.com/servo/servo/pull/38797">#38797</a>).Additionally, the layout inspector now <strong>dims nodes that are not displayed</strong> (<a href="https://github.com/simonwuelker">@simonwuelker</a>, <a href="https://github.com/servo/servo/pull/38575">#38575</a>).</p><figure><a href="https://servo.org/img/blog/2025-09-mastodon.png"><img alt="servoshell showing the Servo Mastodon account homepage" src="https://servo.org/img/blog/2025-09-mastodon.png" /></a><a href="https://servo.org/img/blog/2025-09-netmonitor.png"><img alt="The Firefox network monitor, showing a list of network connections for the Servo Mastodon account homepage" src="https://servo.org/img/blog/2025-09-netmonitor.png" /></a> &lt;figcaption&gt;That's a lot of network requests.&lt;/figcaption&gt;</figure><p>We’ve fixed a significant source of crashes in the engine: hit testing using outdated display lists (<a href="https://github.com/servo/servo/issues/37932">issue #37932</a>).<strong>Hit testing</strong> in a web rendering engine is the process that determines which element(s) the user’s mouse is hovering over.</p><p>Previously, this process ran inside of <a href="https://github.com/servo/webrender">WebRender</a>, which receives a display list representing what should be rendered for a particular page.WebRender runs on a separate thread or process from the actual page content, so display lists are updated asynchronously.By the time we do a hit test, the elements reported may not exist anymore, so we could trigger crashes by (for example) moving the mouse quickly over parts of the page that were rapidly changing.</p><p>This was fixed by making the hit test operation synchronous and moving it into the same thread as the actual content being tested against, eliminating the possibility of outdated results (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/kongbai1996">@kongbai1996</a>, <a href="https://github.com/yezhizhen">@yezhizhen</a>, <a href="https://github.com/servo/servo/pull/38480">#38480,</a> <a href="https://github.com/servo/servo/pull/38464">#38464,</a> <a href="https://github.com/servo/servo/pull/38463">#38463,</a> <a href="https://github.com/servo/servo/pull/38884">#38884,</a> <a href="https://github.com/servo/servo/pull/38518">#38518)</a>.</p><h3>Web platform support <a class="header-anchor" href="https://servo.org/blog/2025/09/25/this-month-in-servo/#web-platform-support"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><h4>DOM &amp; JS <a class="header-anchor" href="https://servo.org/blog/2025/09/25/this-month-in-servo/#dom-%26-js"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h4><p>We’ve upgraded to <strong>SpiderMonkey v140</strong> (<a href="https://gitlab.gnome.org/GNOME/gjs/-/blob/master/NEWS#L39-137">changelog</a>) (<a href="https://github.com/jdm">@jdm</a>, <a href="https://github.com/servo/servo/pull/37077">#37077</a>, <a href="https://github.com/servo/servo/pull/38563">#38563</a>).</p><p>Numerous pieces of the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API"><strong>Trusted Types API</strong></a> are now present in Servo(<a href="https://github.com/TimvdLippe">@TimvdLippe</a>, <a href="https://github.com/jdm">@jdm</a>, <a href="https://github.com/servo/servo/pull/38595">#38595</a>, <a href="https://github.com/servo/servo/pull/37834">#37834</a>, <a href="https://github.com/servo/servo/pull/38700">#38700</a>, <a href="https://github.com/servo/servo/pull/38736">#38736</a>, <a href="https://github.com/servo/servo/pull/38718">#38718</a>, <a href="https://github.com/servo/servo/pull/38784">#38784</a>, <a href="https://github.com/servo/servo/pull/38871">#38871</a>, <a href="https://github.com/servo/servo/pull/8623">#8623</a>, <a href="https://github.com/servo/servo/pull/38874">#38874</a>, <a href="https://github.com/servo/servo/pull/38872">#38872</a>, <a href="https://github.com/servo/servo/pull/38886">#38886</a>), all gated behind the <code>dom_trusted_types_enabled</code> preference.</p><p>The <a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API"><strong>IndexedDB</strong></a> implementation (gated behind <code>dom_indexeddb_enabled</code>) is progressing quickly (<a href="https://github.com/arihant2math">@arihant2math</a>, <a href="https://github.com/jdm">@jdm</a>, <a href="https://github.com/rodion">@rodion</a>, <a href="https://github.com/kkoyung">@kkoyung</a>, <a href="https://github.com/servo/servo/pull/28744">#28744</a>, <a href="https://github.com/servo/servo/pull/38737">#38737</a>, <a href="https://github.com/servo/servo/pull/38836">#38836</a>, <a href="https://github.com/servo/servo/pull/38813">#38813</a>, <a href="https://github.com/servo/servo/pull/38819">#38819</a>, <a href="https://github.com/servo/servo/pull/38115">#38115</a>, <a href="https://github.com/servo/servo/pull/38944">#38944</a>, <a href="https://github.com/servo/servo/pull/38740">#38740</a>, <a href="https://github.com/servo/servo/pull/38891">#38891</a>, <a href="https://github.com/servo/servo/pull/38723">#38723</a>, <a href="https://github.com/servo/servo/pull/38850">#38850</a>, <a href="https://github.com/servo/servo/pull/38735">#38735</a>), now reporting errors via <code>IDBRequest</code> interface and supporting autoincrement keys.</p><p>A prototype implementation of the <a href="https://developer.mozilla.org/en-US/docs/Web/API/CookieStore"><strong>CookieStore</strong> API</a> is now implemented and gated by the <code>dom_cookiestore_enabled</code> preference (<a href="https://github.com/sebsebmc">@sebsebmc</a>, <a href="https://github.com/servo/servo/pull/37968">#37968</a>, <a href="https://github.com/servo/servo/pull/38876">#38876</a>).</p><p>Servo now passes over <strong>99.6% of the <a href="https://drafts.fxtf.org/geometry/">CSS geometry</a> test suite</strong>, thanks to an implementation of <strong>matrixTransform() on DOMPointReadOnly</strong>, making all geometry interfaces serializable, and adding the <strong>SVGMatrix and SVGPoint aliases</strong> (<a href="https://github.com/lumiscosity">@lumiscosity</a>, <a href="https://github.com/servo/servo/pull/38801">#38801</a>, <a href="https://github.com/servo/servo/pull/38828">#38828</a>, <a href="https://github.com/servo/servo/pull/38810">#38810</a>).</p><p>You can now use the <a href="https://developer.mozilla.org/en-US/docs/Web/API/TextEncoderStream"><strong>TextEncoderStream</strong> API</a> (<a href="https://github.com/minghuaw">@minghuaw</a>, <a href="https://github.com/servo/servo/pull/38466">#38466</a>).Streams that are piped now correctly pass through <code>undefined</code> values, too (<a href="https://github.com/gterzian">@gterzian</a>, <a href="https://github.com/servo/servo/pull/38470">#38470</a>).We also fixed a crash in the result of <strong>pipeTo() on ReadableStream</strong> (<a href="https://github.com/gterzian">@gterzian</a>, <a href="https://github.com/servo/servo/pull/38385">#38385</a>).</p><p>We’ve implemented <strong>getModifierState() on MouseEvent</strong> (<a href="https://github.com/PotatoCP">@PotatoCP</a>, <a href="https://github.com/servo/servo/pull/38535">#38535</a>), and made a number of changes involving DOM events: <strong>‘mouseleave’ events</strong> are fired when the pointer leaves an &lt;iframe&gt; (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/servo/servo/pull/38539">#38539</a>), pasting from the clipboard into a text input triggers an <strong>‘input’ event</strong> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/37100">#37100</a>), <strong>focus now occurs after ‘mousedown’</strong> instead of ‘click’ (<a href="https://github.com/yezhizhen">@yezhizhen</a>, <a href="https://github.com/servo/servo/pull/38589">#38589</a>), we ignore ‘mousedown’ and ‘mouseup’ events for elements that are disabled (<a href="https://github.com/yezhizhen">@yezhizhen</a>, <a href="https://github.com/servo/servo/pull/38671">#38671</a>), and removing an event handler attribute like ‘onclick’ clears all relevant event listeners (<a href="https://github.com/TimvdLippe">@TimvdLippe</a>, <a href="https://github.com/kotx">@kotx</a>, <a href="https://github.com/servo/servo/pull/38734">#38734</a>, <a href="https://github.com/servo/servo/pull/39011">#39011</a>).</p><p>Servo now supports <strong>scrollIntoView()</strong> (<a href="https://github.com/abdelrahman1234567">@abdelrahman1234567</a>, <a href="https://github.com/servo/servo/pull/38230">#38230</a>), and fires a <strong>‘scroll’ event</strong> whenever a page is scrolled (<a href="https://github.com/stevennovaryo">@stevennovaryo</a>, <a href="https://github.com/servo/servo/pull/38321">#38321</a>).You can now focus an element without scrolling, by passing the <code>{preventScroll: true}</code> option to focus() (<a href="https://github.com/abdelrahman1234567">@abdelrahman1234567</a>, <a href="https://github.com/servo/servo/pull/38495">#38495</a>).</p><p><strong>navigator.sendBeacon()</strong> is now implemented, gated behind the <code>dom_navigator_sendbeacon_enabled</code> preference (<a href="https://github.com/TimvdLippe">@TimvdLippe</a>, <a href="https://github.com/servo/servo/pull/38301">#38301</a>).Similarly, the <strong>AbortSignal.abort()</strong> static method is hidden behind <code>dom_abort_controller_enabled</code> (<a href="https://github.com/Taym95">@Taym95</a>, <a href="https://github.com/servo/servo/pull/38746">#38746</a>).</p><p>The <strong>HTMLDocument</strong> interface now exists as a property on the <code>Window</code> object (<a href="https://github.com/leo030303">@leo030303</a>, <a href="https://github.com/servo/servo/pull/38433">#38433</a>).Meanwhile, the <strong>CSS</strong> window property is now a <a href="https://webidl.spec.whatwg.org/#idl-namespaces">WebIDL namespace</a> (<a href="https://github.com/simonwuelker">@simonwuelker</a>, <a href="https://github.com/servo/servo/pull/38579">#38579</a>).We also implemented the new <strong>QuotaExceededError</strong> interface (<a href="https://github.com/rmeno12">@rmeno12</a>, <a href="https://github.com/servo/servo/pull/38507">#38507</a>, <a href="https://github.com/servo/servo/pull/38720">#38720</a>), which replaces previous usages of DOMException with the <code>QUOTA_EXCEEDED_ERR</code> name.</p><p>Our 2D canvas implementation now supports <strong>addPath() on Path2D</strong> (<a href="https://github.com/arthmis">@arthmis</a>, <a href="https://github.com/servo/servo/pull/37838">#37838</a>) and the <strong>restore()</strong> methods on <strong>CanvasRenderingContext2D</strong> and <strong>OffscreenCanvas</strong> now pop all applied clipping paths (<a href="https://github.com/sagudev">@sagudev</a>, <a href="https://github.com/servo/servo/pull/38496">#38496</a>).Additionally, we now support <strong>using web fonts in the 2D canvas</strong> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/38979">#38979</a>).Meanwhile, the performance continues to improve in the new <a href="https://github.com/linebender/vello?tab=readme-ov-file#vello">Vello</a>-based backends (<a href="https://github.com/sagudev">@sagudev</a>, <a href="https://github.com/servo/servo/pull/38406">#38406</a>, <a href="https://github.com/servo/servo/pull/38356">#38356</a>, <a href="https://github.com/servo/servo/pull/38440">#38440</a>, <a href="https://github.com/servo/servo/pull/38437">#38437</a>), with asynchronous uploading also showing improvements (<a href="https://github.com/sagudev">@sagudev</a>, <a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/37776">#37776</a>).</p><p>Muting media elements with the <strong>‘mute’</strong> HTML attribute now works during the initial resource load (<a href="https://github.com/rayguo17">@rayguo17</a>, <a href="https://github.com/jschwe">@jschwe</a>, <a href="https://github.com/servo/servo/pull/38462">#38462</a>).</p><p>Modifying stylesheets now integrates better with incremental layout, in both light trees and shadow trees (<a href="https://github.com/coding-joedow">@coding-joedow</a>, <a href="https://github.com/servo/servo/pull/38530">#38530</a>, <a href="https://github.com/servo/servo/pull/38529">#38529</a>).Note that calling setProperty() on a readonly CSSStyleDeclaration correctly throws an exception (<a href="https://github.com/simonwuelker">@simonwuelker</a>, <a href="https://github.com/servo/servo/pull/38677">#38677</a>).</p><h4>CSS <a class="header-anchor" href="https://servo.org/blog/2025/09/25/this-month-in-servo/#css"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h4><p>We’ve upgraded to the upstream <strong>Stylo</strong> revision as of August 1, 2025.</p><p>We now support custom CSS properties with the <strong>CSS.registerProperty()</strong> method (<a href="https://github.com/simonwuelker">@simonwuelker</a>, <a href="https://github.com/servo/servo/pull/38682">#38682</a>), as well as custom element states with the <strong>‘states’ property on ElementInternals</strong> (<a href="https://github.com/simonwuelker">@simonwuelker</a>, <a href="https://github.com/servo/servo/pull/38564">#38564</a>).</p><p>Flexbox cross sizes can no longer end up negative through stretching (<a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/servo/servo/pull/38521">#38521</a>), while ‘stretch’ on flex items now stretches to the line if possible (<a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/servo/servo/pull/38526">#38526</a>).</p><p><strong>Overflow calculations are more accurate</strong>, now that we ignore ‘position: fixed’ children of the root element (<a href="https://github.com/stevennovaryo">@stevennovaryo</a>, <a href="https://github.com/servo/servo/pull/38618">#38618</a>), compute overflow for &lt;body&gt; separate from the viewport (<a href="https://github.com/shubhamg13">@shubhamg13</a>, <a href="https://github.com/servo/servo/pull/38825">#38825</a>), check for ‘overflow: visible’ in parents and children (<a href="https://github.com/shubhamg13">@shubhamg13</a>, <a href="https://github.com/servo/servo/pull/38443">#38443</a>), and propagate ‘overflow’ to the viewport correctly (<a href="https://github.com/shubhamg13">@shubhamg13</a>, <a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/servo/servo/pull/38598">#38598</a>).</p><p>‘color’ and ‘text-decoration’ properties no longer inherit into the contents of &lt;select&gt; elements (<a href="https://github.com/simonwuelker">@simonwuelker</a>, <a href="https://github.com/servo/servo/pull/38570">#38570</a>).</p><p>Negative outline offsets work correctly (<a href="https://github.com/lumiscosity">@lumiscosity</a>, <a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/38418">#38418</a>).</p><p>Video elements no longer fall back to a preferred aspect ratio of 2 (<a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/servo/servo/pull/38705">#38705</a>).</p><p>‘position: sticky’ elements are handled correctly inside CSS transforms (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/servo/servo/pull/38391">#38391</a>).</p><h3>Performance &amp; Stability <a class="header-anchor" href="https://servo.org/blog/2025/09/25/this-month-in-servo/#performance-%26-stability"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><p>We fixed several panics this month, involving IntersectionObserver and missing stacking contexts (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/38473">#38473</a>), unpaintable canvases and text (<a href="https://github.com/gterzian">@gterzian</a>, <a href="https://github.com/servo/servo/pull/38664">#38664</a>), serializing ‘location’ properties on Window objects (<a href="https://github.com/jdm">@jdm</a>, <a href="https://github.com/servo/servo/pull/38709">#38709</a>), and navigations canceled before HTTP headers are received (<a href="https://github.com/gterzian">@gterzian</a>, <a href="https://github.com/servo/servo/pull/38739">#38739</a>).</p><p>We also fixed a number of performance pitfalls.The document rendering loop is now <strong>throttled to 60 FPS</strong> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/servo/servo/pull/38431">#38431</a>), while <strong>animated images do less work</strong> when advancing the current frame (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/38857">#38857</a>).In addition, elements with <strong>CSS images will not trigger page reflow</strong> until their image data is fully available (<a href="https://github.com/coding-joedow">@coding-joedow</a>, <a href="https://github.com/servo/servo/pull/38916">#38916</a>).</p><p>Finally, we made improvements to memory usage and binary size.Inline stylesheets are now deduplicated, which can have a significant impact on pages with <strong>lots of form inputs</strong> or <strong>custom elements</strong> with common styles (<a href="https://github.com/coding-joedow">@coding-joedow</a>, <a href="https://github.com/servo/servo/pull/38540">#38540</a>).We also removed many unused pieces of the ICU library, <strong>saving 16MB</strong> from the final binary.</p><h3>Embedding <a class="header-anchor" href="https://servo.org/blog/2025/09/25/this-month-in-servo/#embedding"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><p>Servo has declared a <strong>Minimum Supported Rust Version</strong> (1.85.0), and this is verified with every new pull request (<a href="https://github.com/jschwe">@jschwe</a>, <a href="https://github.com/servo/servo/pull/37152">#37152</a>).</p><p>Evaluating JS from the embedding layer now <strong>reports an error</strong> if the evaluation failed for any reason (<a href="https://github.com/rodio">@rodio</a>, <a href="https://github.com/servo/servo/pull/38602">#38602</a>).</p><p>Our <strong>WebDriver</strong> implementation now passes 80% of the implementation conformance tests.This is the result of lots of work on handling user prompts (<a href="https://github.com/PotatoCP">@PotatoCP</a>, <a href="https://github.com/servo/servo/pull/38591">#38591</a>), computing obscured/disabled elements while clicking (<a href="https://github.com/yezhizhen">@yezhizhen</a>, <a href="https://github.com/servo/servo/pull/38497">#38497</a>, <a href="https://github.com/servo/servo/pull/38841">#38841</a>, <a href="https://github.com/servo/servo/pull/38436">#38436</a>, <a href="https://github.com/servo/servo/pull/38490">#38490</a>, <a href="https://github.com/servo/servo/pull/38383">#38383</a>), and improving window focus behaviours (<a href="https://github.com/yezhizhen">@yezhizhen</a>, <a href="https://github.com/servo/servo/pull/38889">#38889</a>, <a href="https://github.com/servo/servo/pull/38909">#38909</a>).We also implemented the <strong>Get Window Handles</strong> command (<a href="https://github.com/longvatrong111">@longvatrong111</a>, <a href="https://github.com/yezhizhen">@yezhizhen</a>, <a href="https://github.com/servo/servo/pull/38622">#38622</a>, <a href="https://github.com/servo/servo/pull/38745">#38745</a>), added support for getting element boolean attributes (<a href="https://github.com/kkoyung">@kkoyung</a>, <a href="https://github.com/servo/servo/pull/38401">#38401</a>), and added more accurate errors for a number of commands (<a href="https://github.com/yezhizhen">@yezhizhen</a>, <a href="https://github.com/longvatrong111">@longvatrong111</a>, <a href="https://github.com/servo/servo/pull/38620">#38620</a>, <a href="https://github.com/servo/servo/pull/38357">#38357</a>).The <strong>Element Clear</strong> command now clears <code>&lt;input type="file"&gt;</code> elements correctly (<a href="https://github.com/PotatoCP">@PotatoCP</a>, <a href="https://github.com/servo/servo/pull/38536">#38536</a>), and <strong>Element Send Keys</strong> now appends to file inputs with the ‘multiple’ attribute.</p><h3>servoshell <a class="header-anchor" href="https://servo.org/blog/2025/09/25/this-month-in-servo/#servoshell"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><p>We now <strong>display favicons</strong> of each top-level page in the tab bar (<a href="https://github.com/simonwuelker">@simonwuelker</a>, <a href="https://github.com/servo/servo/pull/36680">#36680</a>).</p><figure><a href="https://servo.org/img/blog/2025-09-favicon.png"><img alt="servoshell showing a diffie favicon in the tab bar" src="https://servo.org/img/blog/2025-09-favicon.png" /></a></figure><p>Resizing the browser window to a very small dimension no longer crashes the browser (<a href="https://github.com/leo030303">@leo030303</a>, <a href="https://github.com/servo/servo/pull/38461">#38461</a>).Element hit testing in full screen mode now works as expected (<a href="https://github.com/yezhizhen">@yezhizhen</a>, <a href="https://github.com/servo/servo/pull/38328">#38328</a>).</p><p>Various popup dialogs, such as the &lt;select&gt; option chooser dialog, can now be closed without choosing a value (<a href="https://github.com/TimvdLippe">@TimvdLippe</a>, <a href="https://github.com/servo/servo/pull/38373">#38373</a>, <a href="https://github.com/servo/servo/pull/38949">#38949</a>).Additionally, the browser now responds to a popup closing without any other inputs (<a href="https://github.com/lumiscosity">@lumiscosity</a>, <a href="https://github.com/servo/servo/pull/39038">#39038</a>).</p><h3>Donations <a class="header-anchor" href="https://servo.org/blog/2025/09/25/this-month-in-servo/#donations"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><p>Thanks again for your generous support!We are now receiving <strong>5552 USD/month</strong> (+18.3% over July) in recurring donations.</p><p>Historically this has helped cover the cost of our <a href="https://ci0.servo.org/">speedy</a> <a href="https://ci1.servo.org/">CI</a> <a href="https://ci2.servo.org/">servers</a> and <a href="https://www.outreachy.org/alums/2025-06/#:~:text=Servo">Outreachy interns</a>.Thanks to your support, we’re now setting up <strong><a href="https://ci3.servo.org/">two</a> <a href="https://ci4.servo.org/">new</a> CI servers for benchmarking</strong>, and <strong><a href="https://servo.org/blog/2025/09/17/your-donations-at-work-funding-jdm/">funding the work of our long-time maintainer</a> Josh Matthews</strong> (@jdm), with a particular focus on helping more people contribute to Servo.</p><p>Keep an eye out for <a href="https://github.com/servo/servo/issues/38141">further CI improvements</a> in the coming months, including <a href="https://github.com/servo/ci-runners/issues/21"><strong>ten-minute WPT builds</strong></a>, <strong>macOS arm64 builds</strong>, and <strong>faster pull request checks</strong>.</p><p>Servo is also on <a href="https://thanks.dev/">thanks.dev</a>, and already <strong>15 GitHub users</strong> (−7 from July) that depend on Servo are sponsoring us there.If you use Servo libraries like <a href="https://crates.io/crates/url/reverse_dependencies">url</a>, <a href="https://crates.io/crates/html5ever/reverse_dependencies">html5ever</a>, <a href="https://crates.io/crates/selectors/reverse_dependencies">selectors</a>, or <a href="https://crates.io/crates/cssparser/reverse_dependencies">cssparser</a>, signing up for <a href="https://thanks.dev/">thanks.dev</a> could be a good way for you (or your employer) to give back to the community.</p><figure class="_fig" style="width: 100%; margin: 1em 0;"><div class="_flex"> <div style="text-align: right;"> <div><strong>5552</strong> USD/month</div> <div></div> <div></div> <div style="padding-right: 1em;"><strong>10000</strong></div> </div> <progress max="10000" value="5552"></progress></div></figure><p>As always, use of these funds will be decided transparently in the Technical Steering Committee.For more details, head to our <a href="https://servo.org/sponsorship/">Sponsorship page</a>.</p></description> <pubDate>Thu, 25 Sep 2025 00:00:00 +0000</pubDate></item><item> <title>Niko Matsakis: Symposium: exploring new AI workflows</title> <guid isPermaLink="false">https://smallcultfollowing.com/babysteps/blog/2025/09/24/symposium/</guid> <link>https://smallcultfollowing.com/babysteps/blog/2025/09/24/symposium/?utm_source=atom_feed</link> <description><div style="overflow: auto;"><img alt="Screenshot of the Symposium app" src="https://smallcultfollowing.com/babysteps/ /assets/2025-09-24-symposium/logo-alcove.png" style="float: left; margin-right: 15px; margin-bottom: 10px;" width="25%" /><p>This blog post gives you a tour of <a href="https://github.com/symposium-dev/symposium">Symposium</a>, a wild-and-crazy project that I’ve been obsessed with over the last month or so. Symposium combines an MCP server, a VSCode extension, an OS X Desktop App, and some <a href="https://github.com/symposium-dev/symposium/blob/main/symposium/mcp-server/src/guidance/main.md">mindful prompts</a> to forge new ways of working with agentic CLI tools.</p></div><p>Symposium is currently focused on my setup, which means it works best with VSCode, Claude, Mac OS X, and Rust. But it’s meant to be unopinionated, which means it should be easy to extend to other environments (and in particular it already works great with other programming languages). The goal is not to compete with or replace those tools but to combine them together into something new and better.</p><p>In addition to giving you a tour of Symposium, this blog post is an invitation: <a href="https://github.com/symposium-dev/symposium">Symposium is an open-source project</a>, and I’m looking for people to explore with me! If you are excited about the idea of inventing new styles of AI collaboration, join the <a href="https://symposium-dev.zulipchat.com">symposium-dev Zulip</a>. Let’s talk!</p><h3>Demo video</h3><p>I’m not normally one to watch videos online. But in this particular case, I do think a movie is going to be worth 1,000,000 words. Therefore, I’m embedding a short video (6min) demonstrating how Symposium works below. Check it out! But don’t worry, if videos aren’t your thing, you can just read the rest of the post instead.</p><div style="padding-bottom: 56.25%; height: 0; overflow: hidden;"> </div> <p>Alternatively, if you <em>really</em> love videos, you can watch the <a href="https://youtu.be/HQcIp-IBj0Q">first version I made, which went into more depth</a>. That version came in at 20 minutes, which I decided was…a bit much. 😁</p><h3>Taskspaces let you juggle concurrent agents</h3><p>The Symposium story begins with <code>Symposium.app</code>, an OS X desktop application for managing <em>taskspaces</em>. A taskspace is a clone of your project<sup id="fnref:1"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:1">1</a></sup> paired with an agentic CLI tool that is assigned to complete some task.</p><p>My observation has been that most people doing AI development spend a lot of time waiting while the agent does its thing. Taskspaces let you switch quickly back and forth.</p><p>Before I was using taskspaces, I was doing this by jumping between different projects. I found that was really hurting my brain from context switching. But jumping between <em>tasks</em> in a project is much easier. I find it works best to pair a complex topic with some simple refactorings.</p><p>Here is what it looks like to use Symposium:</p><img alt="Screenshot of the Symposium app" src="https://smallcultfollowing.com/babysteps/ /assets/2025-09-24-symposium/taskspaces.png" width="100%" /><p>Each of those boxes is a taskspace. It has both its own isolated directory on the disk and an associated VSCode window. When you click on the taskspace, the app brings that window to the front. It can also hide other windows by positioning them exactly behind the first one in a stack<sup id="fnref:2"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:2">2</a></sup>. So it’s kind of like a mini window manager.</p><p>Within each VSCode window, there is a terminal running an agentic CLI tool that has the Symposium <a href="https://modelcontextprotocol.io/docs/getting-started/intro">MCP server</a>. If you’re not familiar with MCP, it’s a way for an LLM to invoke custom tools; it basically just gives the agent a list of available tools and a JSON scheme for what arguments they expect.</p><p>The Symposium MCP server does a bunch of things–we’ll talk about more of them later–but one of them is that it lets the agent interact with taskspaces. The agent can use the MCP server to post logs and signal progress (you can see the logs in that screenshot); it can also spawn new taskspaces. I find that last part very handy.</p><p>It often happens to me that while working on one idea, I find opportunities for cleanups or refactorings. Nowadays I just spawn out a taskspace with a quick description of the work to be done. Next time I’m bored, I can switch over and pick that up.</p><h3>An aside: the Symposium app is written in Swift, a language I did not know 3 weeks ago</h3><p>It’s probably worth mentioning that the Symposium app is written in Swift. I did not know Swift three weeks ago. But I’ve now written about 6K lines and counting. I feel like I’ve got a pretty good handle on how it works.<sup id="fnref:3"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:3">3</a></sup></p><p>Well, it’d be more accurate to say that I have <em>reviewed</em> about 6K lines, since most of the time Claude generates the code. I mostly read it and offer suggestions for improvement<sup id="fnref:4"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:4">4</a></sup>. When I do dive in and edit the code myself, it’s interesting because I find I don’t have the muscle memory for the syntax. I think this is pretty good evidence for the fact that agentic tools help you get started in a new programming language.</p><h3>Walkthroughs let AIs explain code to you</h3><p>So, while taskspaces let you jump between tasks, the rest of Symposium is dedicated to helping you complete an individual task. A big part of that is trying to go beyond the limits of the CLI interface by connecting the agent up to the IDE. For example, the Symposium MCP server has a tool called <code>present_walkthrough</code> which lets the agent present you with a markdown document that explains how some code works. These walkthroughs show up in a side panel in VSCode:</p><img alt="Walkthrough screenshot" src="https://smallcultfollowing.com/babysteps/ /assets/2025-09-24-symposium/walkthrough.png" width="100%" /><p>As you can see, the walkthroughs can embed mermaid, which is pretty cool. It’s sometimes so clarifying to see a flowchart or a sequence diagram.</p><p>Walkthroughs can also embed <em>comments</em>, which are anchored to particular parts of the code. You can see one of those in the screenshot too, on the right.</p><p>Each comment has a Reply button that lets you respond to the comment with further questions or suggest changes; you can also select random bits of text and use the “code action” called “Discuss in Symposium”. Both of these take you back to the terminal where your agent is running. They embed a little bit of XML (<code>&lt;symposium-ref id="..."/&gt;</code>) and then you can just type as normal. The agent can then use another MCP tool to expand that reference to figure out what you are referring to or what you are replying to.</p><p>To some extent, this “reference the thing I’ve selected” functionality is “table stakes”, since Claude Code already does it. But Symposium’s version works anywhere (Q CLI doesn’t have that functionality, for example) and, more importantly, it lets you embed multiple refrences at once. I’ve found that to be really useful. Sometimes I’ll wind up with a message that is replying to one comment while referencing two or three other things, and the <code>&lt;symposium-ref/&gt;</code> system lets me do that no problem.</p><h3>Integrating with IDE knowledge</h3><p>Symposium also includes an <code>ide-operations</code> tool that lets the agent connect to the IDE to do things like “find definitions” or “find references”. To be honest I haven’t noticed this being that important (Claude is surprisingly handy with awk/sed) but I also haven’t done much tinkering with it. I know there are other MCP servers out there too, like <a href="https://github.com/oraios/serena">Serena</a>, so maybe the right answer is just to import one of those, but I think there’s a lot of interesting stuff we <em>could</em> do here by integrating deeper knowledge of the code, so I have been trying to keep it “in house” for now.</p><h3>Leveraging Rust conventions</h3><p>Continuing our journey down the stack, let’s look at one more bit of functionality, which are MCP tools aimed at making agents better at working with Rust code. By far the most effective of these so far is one I call <a href="https://symposium-dev.github.io/symposium/design/mcp-tools/rust-development.html#get_rust_crate_source"><code>get_rust_crate_source</code></a>. It is very simple: given the name of a crate, it just checks out the code into a temporary directory for the agent to use. Well, actually, it does a <em>bit</em> more than that. If the agent supplies a search string, it also searches for that string so as to give the agent a “head start” in finding the relevant code, and it makes a point to highlight code in the examples directory in particular.</p><h3>We could do a lot more with Rust…</h3><p>My experience has been that this tool makes all the difference. Without it, Claude just geneates plausible-looking APIs that don’t really exist. With it, Claude generally figures out exactly what to do. But really it’s just scratching the surface of what we can do. I am excited to go deeper here now that the basic structure of Symposium is in place – for example, I’d love to develop Rust-specific code reviewers that can critique the agent’s code or offer it architectural advice<sup id="fnref:5"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:5">5</a></sup>, or a tool like <a href="https://github.com/plasma-umass/CWhy">CWhy</a> to help people resolve Rust trait errors or macro problems.</p><h3>…and can we decentralize it?</h3><p>But honestly what I’m <em>most</em> excited about is the idea of <strong>decentralizing</strong>. I want Rust library authors to have a standard way to attach custom guidance and instructions that will help agents use their library. I want an AI-enhanced variant of <code>cargo upgrade</code> that automatically bridges over major versions, making use of crate-supplied metadata about what changed and what rewrites are needed. Heck, I want libraries to be able to ship with MCP servers implemented in WASM (<a href="https://opensource.microsoft.com/blog/2025/08/06/introducing-wassette-webassembly-based-tools-for-ai-agents/">Wassette</a>, anyone?) so that Rust developers using that library can get custom commands and tools for working with it. I don’t 100% know what this looks like but I’m keen to explore it. If there’s one thing I’ve learned from Rust, it’s always bet on the ecosystem.</p><h3>Looking further afield, can we use agents to help humans collaborate better?</h3><p>One of the things I am very curious to explore is how we can use agents to help humans collaborate better. It’s oft observed that coding with agents can be a bit lonely<sup id="fnref:6"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:6">6</a></sup>. But I’ve also noticed that structuring a project for AI consumption requires relatively decent documentation. For example, one of the things I did recently for Symposium was to create a Request for Dialogue (RFD) process – a simplified version of Rust’s RFC process. My motivation was partly in anticipation of trying to grow a community of contributors, but it was also because most every major refactoring or feature work I do begins with iterating on docs. The doc becomes a central tracking record so that I can clear the context and rest assured that I can pick up where I left off. But a nice side-effect is that the project has more docs than you might expect, considering, and I hope that will make it easier to dive in and get acquainted.</p><p>And what about other things? Like, I think that taskspaces should really be associated with github issues. If we did that, could we do a better job at helping new contributors pick up an issue? Or at providing mentoring instructions to get started?</p><p>What about memory? I really want to add in some kind of automated memory system that accumulates knowledge about the system more automatically. But could we then share that knowledge (or a subset of it) across users, so that when I go to hack on a project, I am able to “bootstrap” with the accumulated observations of other people who’ve been working on it?</p><p>Can agents help in guiding and shepherding design conversations? At work, when I’m circulating a document, I will typically download a copy of that document with people’s comments embedded in it. Then I’ll use pandoc to convert that into Markdown with HTML comments and then ask Claude to read it over and help me work through the comments systematically. Could we do similar things to manage unwieldy RFC threads?</p><p>This is part of what gets me excited about AI. I mean, don’t get me wrong. I’m scared too. There’s no question that the spread of AI will change a lot of things in our society, and definitely not always for the better. But it’s also a huge opportunity. AI is empowering! Suddenly, learning new things is just <em>vastly</em> easier. And when you think about the potential for integrating AI into community processes, I think that it could easily be used to bring us closer together and maybe even to make progress on previously intractable problems in open-source<sup id="fnref:7"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:7">7</a></sup>.</p><h3>Conclusion: Want to build something cool?</h3><p>As I said in the beginning, this post is two things. Firstly, it’s an advertisement for Symposium. If you think the stuff I described sounds cool, give Symposium a try! You can find <a href="https://symposium-dev.github.io/symposium/install.html">installation instructions</a> here. I gotta warn you, as of this writing, I think I’m the only user, so I would not at all be surprised to find out that there’s bugs in setup scripts etc. But hey, try it out, find bugs and tell me about them! Or better yet, fix them!</p><p>But secondly, and more importantly, this blog post is an invitation to come out and play<sup id="fnref:8"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:8">8</a></sup>. I’m keen to have more people come and hack on Symposium. There’s so much we could do! I’ve identified a number of <a href="http://smallcultfollowing.com/babysteps/atom.xml">“good first issue” bugs</a>. Or, if you’re keen to take on a larger project, I’ve got a set of invited “Request for Dialogue” projects you could pick up and make your own. And if none of that suits your fancy, feel free to pitch you own project – just join the <a href="https://symposium-dev.zulipchat.com">Zulip</a> and open a topic!</p><div class="footnotes"><hr /><ol><li id="fn:1"><p>Technically, a git worktree. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:1">↩︎</a></p></li><li id="fn:2"><p>That’s what the “Stacked” box does; if you uncheck it, the windows can be positioned however you like. I’m also working on a tiled layout mode. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:2">↩︎</a></p></li><li id="fn:3"><p>Well, mostly. I still have some warnings about something or other not being threadsafe that I’ve been ignoring. Claude assures me they are not a big deal (Claude can be so lazy omg). <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:3">↩︎</a></p></li><li id="fn:4"><p>Mostly: “Claude will you please for the love of God stop copying every function ten times.” <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:4">↩︎</a></p></li><li id="fn:5"><p>E.g., don’t use a tokio mutex you fool, <a href="https://ryhl.io/blog/actors-with-tokio/">use an actor</a>. That is one particular bit of advice I’ve given more than once. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:5">↩︎</a></p></li><li id="fn:6"><p>I’m kind of embarassed to admit that Claude’s dad jokes have managed to get a laugh out of me on occassion, though. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:6">↩︎</a></p></li><li id="fn:7"><p>Narrator voice: <em>burnout. he means maintainer burnout.</em> <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:7">↩︎</a></p></li><li id="fn:8"><p>Tell me you went to high school in the 90s without telling me you went to high school in the 90s. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:8">↩︎</a></p></li></ol></div></description> <pubDate>Wed, 24 Sep 2025 20:39:46 +0000</pubDate></item><item> <title>Mozilla Thunderbird: Thunderbird Monthly Development Digest: August 2025</title> <guid isPermaLink="false">https://blog.thunderbird.net/?p=3822</guid> <link>https://blog.thunderbird.net/2025/09/thunderbird-monthly-development-digest-august-2025/</link> <description><p><img alt="" class="attachment-640x360 size-640x360 wp-post-image" height="360" src="https://blog.thunderbird.net/files/2025/09/blog-banner-developer1-768x432.jpg" width="640" /></p><p>Hello again from the Thunderbird development team! As autumn settles in, we’re balancing the steady pace of ongoing projects with some forward-looking planning for 2026. Alongside coding and testing, some of our recent attention has gone into budgets, roadmaps, and setting priorities for the year ahead. It’s not the most glamorous work, but it’s essential for keeping our momentum strong and ensuring that the big features we’re building today continue to deliver value well into the future. In the meantime, plenty of exciting progress has landed across the application, and here are some of the highlights.</p> <h3 class="wp-block-heading"><strong>Exchange support for email is here</strong></h3> <p>Exchange support has officially landed in Thunderbird 144, which will roll out as our October monthly release. A big final push from the team saw a number of important features make it in before the merge:</p> <ul><li>Undo/Redo operations for move/copy/delete</li> <li>Notifications</li> <li>Basic Search</li> <li>Folder Repair</li> <li>Remote message content display &amp; blocking</li> <li>Status Bar feedback messaging</li> <li>Account Settings screen changes</li> <li>Autosync manager for message downloads</li> <li>Attachment delete &amp; detach</li> <li>First set of advanced server settings</li> <li>Experimental tenant-specific configuration options (behind a preference) now being tested with early adopters</li></ul> <p>The QA team is continuing to work through their test plans with support from a small beta test group, and their findings will guide the documentation and support we share more broadly with users on monthly release 144, as well as the priorities to tackle before we head into the next chapter.</p> <p>Looking ahead, the team is already focused on:</p> <ul><li>Expanding advanced server settings for more complex environments</li> <li>Improving search functionality</li> <li>Folder Quotas &amp; Subscriptions</li> <li>Refining the user experience as more real-world feedback comes in</li> <li>A planning session to scope work to support calendar and address book via EWS</li></ul> <p><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1847846"><u>Keep track of feature delivery here.</u></a></p> <h3 class="wp-block-heading"><strong>Conversation View Work Week</strong></h3> <p>One of the biggest milestones this month was our dedicated Conversation View Work Week which recently wrapped up, where designers and engineers gathered in person to tackle one of Thunderbird’s most anticipated UX features. </p> <p>The team aligned early on goals and scope, rapidly iterated on wireframes and high-fidelity mockups, and built out initial front-end components powered by the new Panorama database. </p> <p>By the end of the week, we had working prototypes that collapsed threads into a Gmail-style conversation view, demonstrated the new LiveView architecture, and produced detailed design documentation. It was an intense but rewarding sprint that laid the foundation for a more modern and intuitive Thunderbird experience.</p> <h3 class="wp-block-heading"><strong>Account Hub</strong></h3> <p>We’ve now added the ability to manually edit an EWS configuration, as well as allow for users to create an advanced EWS configuration through the manual configuration step</p> <p>The ability to cancel any loading operation in account hub for email has been completed and will be added to daily shortly</p> <ul><li>This also had the side effect of users who click “Stop” in the account old setup with an OAuth window open now closing the OAuth window automatically</li> <li>We will be uplifting this change to beta and then ESR</li></ul> <p>Progress is being made with adding a step for 3rd party hosting credentials confirmation, with the UI complete and the logic being worked on</p> <ul><li>This progress will have to take into account changes from the cancel loading patch, as there are conflicting changes</li> <li>Once this feature is complete, it will be uplifted to beta, and then ESR</li></ul> <p>Work will soon be starting to enable the creation of address books through account hub by default.</p> <p>Follow progress in the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1981786"><u>Meta Bug</u></a></p> <h3 class="wp-block-heading"><strong>Calendar UI Rebuild</strong></h3> <p>After a long pause, work on the Calendar re-write has resumed! We’ve picked things back up by continuing focus on the event read dialog. A number of improvements have already landed, including proper handling of description data and several small bug fixes.</p> <p>We have seven patches under review that cover key areas such as:</p> <ul><li>Accessibility improvements, including proper announcements of event and calendar titles.</li> <li>Adding the footer for acceptance.</li> <li>Updating displays and transitioning current work to use the mod-src protocol.</li> <li>Handling resizing</li></ul> <p>Development is also underway to add attendee support, after which we’ll move on to polishing the remaining pieces of the read dialog UI.</p> <h3 class="wp-block-heading"><strong>Maintenance, Recent Features and Fixes</strong></h3> <p>August was set aside as a focus for maintenance, with a good number of our team dedicated to handling upstream liabilities such as our continued l10n migration to Fluent and module loading changes. In addition to these items, we’ve had help from the development community to deliver a variety of improvements over the past month:</p> <ul><li>Tree restyling following upstream changes – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1978947"><u>solved</u></a></li> <li>An 18 year old bug to enable event duplication via drag &amp; drop – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=411069"><u>solved</u></a></li> <li>A 15 year old bug to sort by unread in threads correctly – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=617855"><u>solved</u></a></li> <li>Implementation of standard colours throughout the application. [<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979362"><u>meta bug</u></a>]</li> <li>Modernization of module inclusion. [<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979960"><u>meta bug</u></a>]</li> <li>and many more which are listed in <a href="https://www.thunderbird.net/en-US/thunderbird/144.0beta/releasenotes/"><u>release notes for beta</u></a>.</li></ul> <p>If you would like to see new features as they land, and help us squash some early bugs, you can try running <a href="https://archive.mozilla.org/pub/thunderbird/nightly/latest-comm-central/"><u>daily</u></a> and check the pushlog to see what has recently landed. This assistance is immensely helpful for catching problems early.</p> <p>—</p> <p><strong>Toby Pilling</strong></p> <p>Senior Manager, Desktop Engineering</p><p>The post <a href="https://blog.thunderbird.net/2025/09/thunderbird-monthly-development-digest-august-2025/">Thunderbird Monthly Development Digest: August 2025</a> appeared first on <a href="https://blog.thunderbird.net">The Thunderbird Blog</a>.</p></description> <pubDate>Wed, 24 Sep 2025 14:22:05 +0000</pubDate> <dc:creator>Toby Pilling</dc:creator></item><item> <title>The Rust Programming Language Blog: crates.io: Malicious crates faster_log and async_println</title> <guid isPermaLink="true">https://blog.rust-lang.org/2025/09/24/crates.io-malicious-crates-fasterlog-and-asyncprintln/</guid> <link>https://blog.rust-lang.org/2025/09/24/crates.io-malicious-crates-fasterlog-and-asyncprintln/</link> <description><p><strong>Updated September 24th, 2025 17:34:38 UTC</strong> - Socket has also published their own <a href="https://socket.dev/blog/two-malicious-rust-crates-impersonate-popular-logger-to-steal-wallet-keys">accompanying blog post</a> about the attack.</p><h3><a class="anchor" href="https://blog.rust-lang.org/2025/09/24/crates.io-malicious-crates-fasterlog-and-asyncprintln/#summary"></a>Summary</h3><p>On September 24th, the crates.io team was notified by Kirill Boychenko from the <a href="https://www.socket.dev/">Socket Threat Research Team</a> of two malicious crates which were actively searching file contents for Etherum private keys, Solana private keys, and arbitrary byte arrays for exfiltration.</p><p>These crates were:</p><ul><li><code>faster_log</code> - Published on May 25th, 2025, downloaded 7181 times</li><li><code>async_println</code> - Published on May 25th, 2025, downloaded 1243 times</li></ul><p>The malicious code was executed at runtime, when running or testing a project depending on them. Notably, they did not execute any malicious code at build time. Except for their malicious payload, these crates copied the source code, features, and documentation of legitimate crates, using a similar name to them (a case of typosquatting<sup class="footnote-reference" id="fr-typosquatting-1"><a href="https://blog.rust-lang.org/2025/09/24/crates.io-malicious-crates-fasterlog-and-asyncprintln/#fn-typosquatting">1</a></sup>).</p><h3><a class="anchor" href="https://blog.rust-lang.org/2025/09/24/crates.io-malicious-crates-fasterlog-and-asyncprintln/#actions-taken"></a>Actions taken</h3><p>The users in question were immediately disabled, and the crates in question were deleted<sup class="footnote-reference" id="fr-deletion-1"><a href="https://blog.rust-lang.org/2025/09/24/crates.io-malicious-crates-fasterlog-and-asyncprintln/#fn-deletion">2</a></sup> from crates.io shortly after. We have retained copies of all logs associated with the users and the malicious crate files for further analysis.</p><p>The deletion was performed at 15:34 UTC on September 24, 2025.</p><h3><a class="anchor" href="https://blog.rust-lang.org/2025/09/24/crates.io-malicious-crates-fasterlog-and-asyncprintln/#analysis"></a>Analysis</h3><p>Both crates were copies of a crate which provided logging functionality, and the logging implementation remained functional in the malicious crates. The original crate had a feature which performed log file packing, which iterated over an associated directories files.</p><p>The attacker inserted code to perform the malicious action during a log packing operation, which searched the log files being processed from that directory for:</p><ul><li>Quoted Ethereum private keys (0x + 64 hex)</li><li>Solana-style Base58 secrets</li><li>Bracketed byte arrays</li></ul><p>The crates then proceeded to exfiltrate the results of this search to <code>https://mainnet[.]solana-rpc-pool[.]workers[.]dev/</code>.</p><p>These crates had no dependent downstream crates on crates.io.</p><p>The malicious users associated with these crates had no other crates or publishes, and the team is actively investigating associative actions in our retained<sup class="footnote-reference" id="fr-retention-1"><a href="https://blog.rust-lang.org/2025/09/24/crates.io-malicious-crates-fasterlog-and-asyncprintln/#fn-retention">3</a></sup> logs.</p><h3><a class="anchor" href="https://blog.rust-lang.org/2025/09/24/crates.io-malicious-crates-fasterlog-and-asyncprintln/#thanks"></a>Thanks</h3><p>Our thanks to Kirill Boychenko from the <a href="https://www.socket.dev/">Socket Threat Research Team</a> for reporting the crates. We also want to thank Carol Nichols from the crates.io team, Pietro Albini from the Rust Security Response WG and Walter Pearce from the <a href="https://foundation.rust-lang.org/">Rust Foundation</a> for aiding in the response.</p><section class="footnotes"><ol class="footnotes-list"><li id="fn-typosquatting"><p>typosquatting is a technique used by bad actors to initiate dependency confusion attacks where a legitimate user might be tricked into using a malicious dependency instead of their intended dependency — for example, a bad actor might try to publish a crate at <code>proc-macro3</code> to catch users of the legitimate <code>proc-macro2</code> crate. <a href="https://blog.rust-lang.org/2025/09/24/crates.io-malicious-crates-fasterlog-and-asyncprintln/#fr-typosquatting-1">↩</a></p></li><li id="fn-deletion"><p>The crates were preserved for future analysis should there be other attacks, and to inform scanning efforts in the future. <a href="https://blog.rust-lang.org/2025/09/24/crates.io-malicious-crates-fasterlog-and-asyncprintln/#fr-deletion-1">↩</a></p></li><li id="fn-retention"><p>One year of logs are retained on crates.io, but only 30 days are immediately available on our log platform. We chose not to go further back in our analysis, since IP address based analysis is limited by the use of dynamic IP addresses in the wild, and the relevant IP address being part of an allocation to a residential ISP. <a href="https://blog.rust-lang.org/2025/09/24/crates.io-malicious-crates-fasterlog-and-asyncprintln/#fr-retention-1">↩</a></p></li></ol></section></description> <pubDate>Wed, 24 Sep 2025 00:00:00 +0000</pubDate> <dc:creator>Walter Pearce</dc:creator></item><item> <title>Mozilla Thunderbird: State of the Thunder 12: Community, Android, and Mozilla Connect</title> <guid isPermaLink="false">https://blog.thunderbird.net/?p=3814</guid> <link>https://blog.thunderbird.net/2025/09/state-of-the-thunder-12-community-android-and-mozilla-connect/</link> <description><p><img alt="" class="attachment-640x360 size-640x360 wp-post-image" height="360" src="https://blog.thunderbird.net/files/2025/09/Blog-banner-State-of-the-Thunder12-768x432.jpg" width="640" /></p><p>We’re back with our twelfth episode of the State of the Thunder! In this episode, we’re talking about community initiatives, filling you in on Android development, and finishing our updates on popular Mozilla Connect requests. </p> <p>Want to find out how to join future State of the Thunders? Be sure to join our <a href="https://thunderbird.topicbox.com/groups/planning">Thunderbird planning mailing list</a> for all the details. </p> <h3>Austin RiverHacks and Ask-A Fox</h3> <p>Thunderbird is a Silver sponsor for <a href="https://austin-ai.org/event/riverhacks-nasa-space-apps-challenge-2025/">Austin RiverHacks NASA Space Apps Challenge 2025</a>! If you’re in or around Austin, Texas from October 4th-5th, and want to join an in-person event where curious minds delve into NASA data to tackle real-life problems, we’d love to see you. </p> <p>This week (as in right now! Check it out and get involved!), we’re joining forces with Firefox for the <a href="https://community.mozilla.org/en/campaigns/ask-a-fox/">Ask-A-Fox event on Mozilla Support</a>! Earn swag, join an incredible community, and help fellow Thunderbird users on desktop and Android! Want a great overview of how to contribute to SUMO? Watch our <a href="https://blog.thunderbird.net/2024/08/video-how-to-answer-thunderbird-questions-on-mozilla-support/">Community Office Hours</a> with advice on getting started.</p> <h3>Android Plans for Q4 2025</h3> <p>It’s hard to believe we’re almost into the last three months of the year! We’ve just released our joint <a href="https://blog.thunderbird.net/2025/09/mobile-progress-report-july-august-2025/">July/August Mobile Progress</a> report. We also want to give you all an update on our overall progress on the <a href="https://github.com/orgs/thunderbird/projects/19">roadmap</a> we created at the beginning of the year. </p> <p>The new Account Drawer, currently in Beta, isn’t finished yet. We’re still working on real, proper unified folders! We’ll have mockups of the account drawer progress before the end of the month and more info in the next beta’s release notes. We’ll also have updates soon on message list status notifications (similar to the desktop). In the single message view, we have improvements coming! This includes making attachments quicker to see and open. </p> <p>The battle for proper IMAP fetch continues. Different server setups complicate this struggle, but we want to get this right, nonetheless. This will bring the Android app more on par with other emails apps.</p> <p>Unfortunately, work on things like message sync, notifications, and Android 15 might delay features like HTML signatures.</p> <h3>Mozilla Connect Updates, Continued</h3> <p>We’re tackling more of the most frequently requested changes and features on Mozilla Connect, and we’re answering questions about native operating system integration, conversation view, and Thunderbird Pro related features!</p> <h4>Native Operating System Integration</h4> <p>When your operating system is capable of something Thunderbird isn’t, we share your frustration. We want things like OS-native progress bars that show you how downloads are going. We’ve started work on OS-native notification actions, like <a href="https://connect.mozilla.org/t5/ideas/delete-a-mail-directly-from-notification/idi-p/15884">deleting messages</a>. We love how helpful and time-saving this is, and want to expand it to things like calendar reminders.</p> <p>There’s possibility and limitation in this, thanks to both Firefox and the OS itself. Firefox enables us more than it restricts us. For example, our work on the progress bar comes straight from Firefox code. Though there are some limits, and Thunderbird’s different needs as a mail client sometimes mean we need to improve an aspect of Firefox to enable further development. But the beauty of open source means we can contribute our improvements upstream! The OS often constrains us more. For example, we’d love snoozeable native OS calendar notifications, but they just aren’t possible yet.</p> <h4>Conversation View</h4> <p>We just finished an entire in-person work week focused on this in Vancouver! <a href="https://connect.mozilla.org/t5/ideas/true-threaded-conversations-in-thunderbird/idi-p/29558">Conversation view</a>, if you’re not familiar with it, includes ALL messages in a conversation, including your replies and messages moved to different folders. This feature, along with others, depends on having a single database for all messages in Thunderbird. Our current database doesn’t do this; instead, each folder is its own database.</p> <p>The new SQLite database, which we’re calling Panorama, will enable a true Conversation View. During the work week, we thought about (and visualized) what the UI will look like. Having developers and designers in the same room was incredibly helpful for a complicated change. (Having a gassy Boston Terrier in said room, less so.) The existing code expects the current database, so we’ll have to rebuild a lot and carefully consider our decisions. The switch to the new database will probably occur next year after the Extended Support Release, behind a preference.</p> <p>This change will help Thunderbird behave like a modern email client! Moving to Panorama will not only move us into the future, but into the present.</p> <h3>Thunderbird Pro Related-Requests</h3> <p>Three Mozilla Connect requests (<a href="https://connect.mozilla.org/t5/ideas/expand-relay-to-create-full-mozmail-e-mail/idi-p/7985">Expanding Firefox Relay</a>, a <a href="https://connect.mozilla.org/t5/ideas/proposal-for-mozilla-email-domain/idi-p/48656">paid Mozilla email domain</a>, and a <a href="https://connect.mozilla.org/t5/ideas/thunderbird-web-i-d-pay-a-sub-fee-for-it/idi-p/17607">Thunderbird webmail</a>) were all out of our control once. But now, with the upcoming Thunderbird Pro offerings, these all will be possible! We’re even experimenting with a webmail experience for Thundermail, in addition to using Thunderbird (or even another email client if you want.) We’ll have an upcoming State of the Thunder dedicated to Thunderbird Pro with more info and updates!</p> <h3>Watch the Video (also on <a href="https://tilvids.com/w/pmPUW6bjXecEyw6uoq7R1t">PeerTube</a>)</h3> <figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper"> </div></figure> <h3>Listen to the Podcast</h3> <p></p><p>The post <a href="https://blog.thunderbird.net/2025/09/state-of-the-thunder-12-community-android-and-mozilla-connect/">State of the Thunder 12: Community, Android, and Mozilla Connect</a> appeared first on <a href="https://blog.thunderbird.net">The Thunderbird Blog</a>.</p></description> <pubDate>Tue, 23 Sep 2025 15:10:45 +0000</pubDate> <dc:creator>Monica Ayhens-Madon</dc:creator></item><item> <title>Firefox Nightly: Firefox 144 Highlights: Faster Add-ons, Smarter DevTools, and Tab Group Boosts – These Weeks in Firefox, Issue 189</title> <guid isPermaLink="false">https://blog.nightly.mozilla.org/?p=1888</guid> <link>https://blog.nightly.mozilla.org/2025/09/22/firefox-144-highlights-faster-add-ons-smarter-devtools-and-tab-group-boosts-these-weeks-in-firefox-issue-189/</link> <description><h3>Highlights</h3><ul><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=772178">Leo Liu [:leoliu]</a> added a panel for AntiTracking debugging (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1972771">#1972771</a>) behind devtools.anti-tracking.enabled</li></ul><p><img alt="A panel in DevTools for AntiTracking debugging" class="alignnone size-large wp-image-1890" height="152" src="https://blog.nightly.mozilla.org/files/2025/09/headlines189_2-600x152.png" width="600" /></p><ul><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=283262">Alexandre Poirot [:ochameau]</a> added a “User-defined” badge in the markup view event tooltip to differentiate them from “native” events (and possibly spotting event not supported in Firefox) (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1977628">#1977628</a>)</li></ul><p><img alt="&quot;User-defined&quot; badge in the DevTools markup view event tooltip" class="alignnone size-large wp-image-1891" height="182" src="https://blog.nightly.mozilla.org/files/2025/09/headlines189_3-600x182.png" width="600" /></p><ul><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=557153">Nicolas Chevobbe [:nchevobbe]</a> added a “Jump to definition” icon for CSS variables in the Inspector Rules view (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1278517">#1278517</a>)</li></ul><p><img alt="A &quot;Jump to definition&quot; icon for CSS variables in the Inspector Rules view" class="alignnone size-large wp-image-1889" height="74" src="https://blog.nightly.mozilla.org/files/2025/09/headlines189_1-600x74.png" width="600" /></p><h3>Friends of the Firefox team</h3><h4>Introductions/Shout-Outs</h4><ul><li>New contributor <a href="https://bugzilla.mozilla.org/user_profile?user_id=409790">Merci chao</a> has filed a whole bunch of valid and useful tab group bugs</li></ul><h4><a href="https://bugzilla.mozilla.org/buglist.cgi?title=Resolved%20bugs%20(excluding%20employees)&amp;quicksearch=1892101%2C1969417%2C1979919%2C1689380%2C1982968%2C1984296%2C1982767%2C1981384%2C1984788%2C1813675%2C1583902%2C1956493%2C1984661%2C1679997%2C1787457%2C1984872">Resolved bugs (excluding employees)</a></h4><h4>Volunteers that fixed more than one bug</h4><ul><li>Alexander Kuleshov</li></ul><h4>New contributors (🌟 = first patch)</h4><ul><li>Josh Berry added <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1984553">groupId to browser.tabs.onUpdated event</a></li><li>Jacqueline Amherst [:jqln] <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1981376">moved gPrivateBrowsingUI to its own file</a> and avoid loading it unless/until we encounter our first private window</li></ul><h3>Project Updates</h3><h4>Add-ons / Web Extensions</h4><h5>Addon Manager &amp; about:addons</h5><ul><li>InstallTrigger API implementation has been fully removed in Firefox 144 🥳 – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1776426">Bug 1776426</a> / <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979227">Bug 1979227</a><ul><li>Thanks to Gregory Pappas for the immense help on this one!</li></ul></li><li>Fixed issue with add-on updates automatically cancelled due to new extension metadata property missing from previously installed add-ons – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1984724">Bug 1984724</a></li><li>Improved spacing between about:addons add-on card message bars and add-ons card header – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1984872">Bug 1984872</a><ul><li>Thanks to Sujal Singh for contributing this improvement to the about:addons cards!</li></ul></li></ul><h5>WebExtensions Framework</h5><ul><li>Fixed Customize mode and keyboard shortcuts issue hit when a user may have clicked to the “extension settings” link from the add-on post-install dialog – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1983869">Bug 1983869</a></li><li>Fixed regression preventing SVG icons associated with extension context menu items to be loaded successfully – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1986618">Bug 1986618</a> (fixed in the Firefox 143, same Firefox version where the regression was initially introduced through <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979338">Bug 1979338</a>).</li></ul><h5>WebExtension APIs</h5><ul><li>In Firefox 144 browser.storage.local and browser.storage.managed WebExtensions API are now also providing a getBytesInUse API method – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1385832">Bug 1385832</a><ul><li>Thanks to Nathan Gross for contributing this enhancement to the WebExtensions storage APIs!</li></ul></li><li>Added missing groupId property to the browser.tabs.onUpdated API method – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1984553">Bug 1984553</a>.<ul><li>Thanks to Josh Berry for reporting and fixing this gap in our WebExtensions API JSONSchema definitions</li><li>NOTE<b>:</b> this change mainly matters for TypeScript type definitions being generated based on our JSONSchema definitions. The groupId property was set in the browser.tabs.onUpdated API event details even without this fix to the JSONSchema.</li></ul></li></ul><h4>DevTools</h4><ul><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=750915">Artem Manushenkov</a><ul><li>documented <a href="https://firefox-source-docs.mozilla.org/devtools-user/web_console/split_console/index.html#:~:text=you%20also%20can%20disable%20the%20split%20console%20altogether">“Enable Split Console” setting</a> and added missing alt attributes for images and updated the screenshot (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1984296">#1984296</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1981384">#1981384</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1984788">#1984788</a>)</li><li>removed unused npm scripts from the debugger folder (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1984661">#1984661</a>)</li><li>added keyboard shortcuts for clearing the console in the clear button title (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1984993">#1984993</a>)</li></ul></li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=446518">Sebastian Zartner [:sebo]</a> added a inactive CSS warning for usage of overflow on non-block containers (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1583902">#1583902</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=764501">Riz</a> removed Chrome frames from Netmonitor stack traces (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1280266">#1280266</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=218550">Robert Longson [:longsonr]</a> fixed an issue where we would show an invalid message to users when devtools.netmonitor.requestBodyLimit=0 (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1986196">#1986196</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=703422">David Shin[:dshin]</a> fixed a Chrome-Only method to make the selector highlighter work for @scope rules (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1980210">#1980210</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=34283">Masayuki Nakano [:masayuki]</a> fixed the “Break on node removal” feature when a node is removed because a parent node’s innerHTML is updated (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1984312">#1984312</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=763731">Holger Benl [:hbenl]</a> fixed an issue with screenshots in Responsive Design Mode (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979518">#1979518</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=283262">Alexandre Poirot [:ochameau]</a> made React avoid updates for devtools in inactive/background tab (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1897765">#1897765</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=283262">Alexandre Poirot [:ochameau]</a> fixed fetching iframe source content in the Debugger (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1977100">#1977100</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=283262">Alexandre Poirot [:ochameau]</a> fixed opening some webpack-internal:///./ source from console stack traces (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982271">#1982271</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=656417">Hubert Boma Manilla (:bomsy)</a> made it possible to see server sent events in the Netmonitor event if the connection is still open (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1830230">#1830230</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=559949">Julian Descottes [:jdescottes]</a> fixed an issue that would crash DevTools (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979448">#1979448</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=559949">Julian Descottes [:jdescottes]</a> improved performance of a regexp we use to check if a given network request is local (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1983755">#1983755</a>)</li></ul><h4>WebDriver BiDi</h4><ul><li>Sasha updated <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1983807">“emulation.setLocaleOverride” and “emulation.setTimezoneOverride” commands to also apply overrides to the existing sandboxes created with WebDriver BiDi</a>.</li><li>Sasha implemented the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1974167">“emulation.setScreenOrientationOverride” command</a>, which allows clients to override screen orientation per browsing or user contexts.</li><li>Henrik <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1986238">reverted the scrollIntoView algorithm for elements in Marionette</a> to always use the instant scroll behavior. This undoes the change introduced in Firefox 97, which had switched the behavior to auto. The reversion addresses potential race conditions when scrolling elements that use smooth behavior.</li><li>Julian updated the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1914407">”browsingContext.navigate” to succeed and stop throwing errors if the navigation was interrupted</a> by another navigation. Typically this could happen with a script updating “window.location”.</li></ul><h4>Lint, Docs and Workflow</h4><ul><li>mlucks <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982463">turned on</a> the ESLint Lit rule, <a href="https://github.com/43081j/eslint-plugin-lit/blob/master/docs/rules/no-value-attribute.md">no-value-attribute</a>.</li><li>Standard8 <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1985946">fixed</a> verbose logging for mach lint.</li></ul><h4>Profile Management</h4><ul><li>We have been <a href="https://docs.google.com/spreadsheets/d/1WONCxwmd17l3iF2ZCxkDSnaAaIZf-rl8CGoIHBYkDSo/edit?gid=600962034#gid=600962034">incrementally rolling out</a>, currently at 5.5%, and profiles <a href="https://sql.telemetry.mozilla.org/dashboard/firefox-profiles-overview">telemetry data</a> looks good.</li><li>OMC and Nimbus completed migration to the multi-profile datastore, their integration testing and telemetry data also looks healthy.</li><li>We are planning for a full rollout in 144 (excluding win 10 users until we have backup support for multiple profiles)</li><li>Closed bugs:<ul><li>Contributor fix! 🎉 Alexander Kuleshov fixed bug 1987225, Remove unused gRestartMode variable.</li></ul></li><li>Other bugs closed out:<ul><li>1950741 When a non-system theme is selected in about:newprofile, overscrolling the page displays a different page background in the overscrolled area <a href="mailto:mlucks@mozilla.com">mlucks@mozilla.com</a></li><li>1950743 Tabbing to the “Explore more themes” link in about:newprofile makes the link’s focus ring span the entire container instead of just the link <a href="mailto:squiles@mozilla.com">squiles@mozilla.com</a></li><li>1966284 hide new profile manager pages (new, edit, delete) from about:about <a href="mailto:mlucks@mozilla.com">mlucks@mozilla.com</a></li><li>1979898 Remove some of the extraneous directories added when using MOZ_APP_DATA <a href="mailto:dtownsend@mozilla.com">dtownsend@mozilla.com</a></li><li>1984193 Add hover tooltips to avatar picker <a href="mailto:mlucks@mozilla.com">mlucks@mozilla.com</a></li><li>1985340 Update Profiles avatars’ alt text to match tooltip text <a href="mailto:mlucks@mozilla.com">mlucks@mozilla.com</a></li><li>1986080 Update Profiles avatars’ aria label text to match tooltip text <a href="mailto:mlucks@mozilla.com">mlucks@mozilla.com</a></li></ul></li></ul><h4>Search and Navigation</h4><ul><li>adw is continuing to work on Google Lens which is a feature that allows users to search images by using the context menu (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1987045">1987045</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1986301">1986301</a>)</li><li>Standard8 has been working on an experiment to send Search Suggestions over Oblivious HTTP for privacy (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1984624">1984624</a>)</li><li>Standard8 converted the urlbar code to use <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1966464">moz-src URIs</a>.</li><li>Mandy has been working on adding localized trending URL results for Perplexity which is still hidden behind an experiment. (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1985515">1985515</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1984201">1984201</a>)</li><li>Dao is working on making the address bar more modular for other features to use. For example, there’s been work done to prepare the search bar. (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1985734">1985734</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1985833">1985833</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1986128">1986128</a>,<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1986129">1986129</a>)</li><li>Mortiz and adw continue to work on displaying relevant dates for suggest (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1986685">1986685</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1986786">1986786</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1981490">1981490</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1986680">1986680</a>,</li><li>Daisuke is working on yelp online suggestions (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1986224">1986224</a>)</li><li>Dale is working on the unified trust panel which will inform users if the site is secure. This is a new design that combines the privacy shield and page information icons and dialogs. (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1976108">1976108</a>)</li></ul><h4>Storybook/Reusable Components/Acorn Design System</h4><ul><li>Some new docs related to Figma Code Connect on <a href="https://firefoxux.github.io/firefox-desktop-components/?path=/docs/docs-figma-code-connect--docs#how-to-find-the-code-connect-snippet">Storybook</a><ul><li>Mostly about adding new Code Connects but that section goes over the usage in Figma Dev Mode</li></ul></li><li>More border-radius tokens filled out and are in the tokens table on <a href="https://firefoxux.github.io/firefox-desktop-components/?path=/story/docs-tokens-table--default">Storybook</a></li><li>Moz-promo now avoids wrapping actions until necessary (prefers being one line) <a href="https://firefoxux.github.io/firefox-desktop-components/?path=/story/ui-widgets-promo--slotted-action">Storybook</a> (<a href="https://firefoxux.github.io/firefox-desktop-components/?path=/story/ui-widgets-promo--slotted-action&amp;args=width:300">narrow example</a>)</li><li>MozLitElements that use the automatic fluent data-l10n-attrs population (setting fluent: true in the property definition) can now have additional per-instance data-l10n-attrs (this attribute is now added to, rather than being replaced) <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1987682">Bug 1987682</a><ul><li>This could be useful especially for moz-button accesskey which is not currently a fluent attribute due to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1945032">Bug 1945032</a> (if you have a hidden HTML element with an accesskey it will still fire, gonna stop doing that in chrome documents since that’s how XUL worked)</li></ul></li></ul><h4>Tab Groups</h4><ul><li>dwalker polished the “active tab in a collapsed group” feature (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979067">1979067</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1971388">1971388</a>)</li><li>jswinarton polishing the collapsed tab group hover preview panel (1981197, 1971235, 1981201, 1983054)<ul><li>Now in Nightly, likely release in Firefox 145</li></ul></li><li>Enormous shout-out to contributor Merci chao for 17 tab group bugs filed in the last month! All of them are written well, actionable, and sometimes even include fixes</li></ul></description> <pubDate>Mon, 22 Sep 2025 10:18:52 +0000</pubDate> <dc:creator>Anna Kulyk</dc:creator></item><item> <title>Mozilla Addons Blog: Now you can roll back to a previous version of your extension</title> <guid isPermaLink="false">https://blog.mozilla.org/addons/?p=9260</guid> <link>https://blog.mozilla.org/addons/2025/09/19/now-you-can-roll-back-to-a-previous-version-of-your-extension/</link> <description><p><img alt="Firefox logo" class="alignleft size-medium wp-image-8750" height="252" src="https://blog.mozilla.org/addons/files/2019/10/Fx-Browser-icon-fullColor-252x252.png" width="252" />In response to feedback we’ve heard from the community, AMO (<a href="http://addons.mozilla.org" rel="noopener" target="_blank">addons.mozilla.org</a>) just introduced a new feature allowing developers the ability to quickly roll back to a previously approved extension version. The most common need for roll-back ability are occasions when developers may release a new version they later discover has critical bugs. Now in such cases, instead of needing to make fast fixes and quickly submit an even newer version, which could be further delayed during a review process, developers are free to revert back to a previously approved version.</p><p>For users who may have already installed the buggy version that’s later pulled, the extension will update to the roll-back version when Firefox checks for the next update (which occurs every 24 hours by default, save for users who’ve turned off automatic updates from the Add-ons Manager).</p><p>To learn more about the new roll-back feature, please visit <a href="https://extensionworkshop.allizom.org/documentation/publish/version-rollback/" rel="noopener" target="_blank">Extension Workshop</a>.</p><p>The post <a href="https://blog.mozilla.org/addons/2025/09/19/now-you-can-roll-back-to-a-previous-version-of-your-extension/">Now you can roll back to a previous version of your extension</a> appeared first on <a href="https://blog.mozilla.org/addons">Mozilla Add-ons Community Blog</a>.</p></description> <pubDate>Fri, 19 Sep 2025 17:18:36 +0000</pubDate> <dc:creator>Scott DeVaney</dc:creator></item><item> <title>Firefox Nightly: Add-ons, Fixes, and DevTools Snacks – These Weeks in Firefox: Issue 188</title> <guid isPermaLink="false">https://blog.nightly.mozilla.org/?p=1885</guid> <link>https://blog.nightly.mozilla.org/2025/09/19/add-ons-fixes-and-devtools-snacks-these-weeks-in-firefox-issue-188/</link> <description><h3>Highlights</h3><ul><li>The Timer and TODO List widget are now available to be enabled in Firefox Labs on Nightly and Beta:</li></ul><p><img alt="Lists and timer on Firefox Home checkbox in Settings" class="alignnone size-large wp-image-1887" height="129" src="https://blog.nightly.mozilla.org/files/2025/09/headlines188_2-600x129.png" width="600" /></p><ul><li>Firefox Desktop about:addons add-on card view has been updated to list API, host and data collection permissions as separate permission lists – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1956493">Bug 1956493</a></li><li>Firefox Suggest:<ul><li>Moritz has been working on the important dates feature, which highlights country-specific holidays. This is now enabled by default in Firefox 143beta (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1985394">1985394</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982011">1982011</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1983077">1983077</a>)</li></ul></li></ul><h3>Friends of the Firefox team</h3><h4><a href="https://bugzilla.mozilla.org/buglist.cgi?title=Resolved%20bugs%20(excluding%20employees)&amp;quicksearch=1892101%2C1969417%2C1979919%2C1689380%2C1982968%2C1984296%2C1982767%2C1981384%2C1984788%2C1813675%2C1583902%2C1956493%2C1984661%2C1679997%2C1787457%2C1984872">Resolved bugs (excluding employees)</a></h4><h4>Volunteers that fixed more than one bug</h4><ul><li>Artem Manushenkov</li><li>Christina</li></ul><h4>New contributors (🌟 = first patch)</h4><ul><li>Christina <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1679997">added support</a> for specifying the cssOrigin (author, user) when injecting CSS via the WebExtension browser.contentScripts.register method</li><li>Christina <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1956493">also updated about:addons</a> to include “permissions and data” for each addon</li><li>🌟Sujal Singh[:sujaldev] <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1984872">fixed a visual glitch when showing the “unsigned extension” warning</a> in about:addons</li><li>chase.philpot <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1689380">fixed a glitch where AddonManager logging</a> would claim that a download had completed when it had actually failed</li></ul><h3>Project Updates</h3><h4>Add-ons / Web Extensions</h4><h5>Addon Manager &amp; about:addons</h5><ul><li>Fixed missing margin between add-on card warning messagebar and expanded add-on card header – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1984872">Bug 1984872</a><ul><li>Thanks to sujaldev contributing this fix to the add-on card messagebars 🎉</li></ul></li></ul><h5>WebExtension APIs</h5><ul><li>Added support for cssOrigin option to the scripting API and content_scripts manifest.json property – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1679997">Bug 1679997</a></li></ul><h4>DevTools</h4><ul><li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1278517">Bug 1278517 – Jump to CSS variable definition in the CSS rule-view</a></li><li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1972771">Bug 1972771 – Adding a new panel for AntiTracking debugger behind a pref</a></li><li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1897765">Bug 1897765 – Network requests in background tabs where devtools is open jank the parent process main thread</a></li></ul><h4>WebDriver BiDi</h4><ul><li>Henrik <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1965465">cleaned up the test expectations for multiple-status outcomes in all existing WebDriver tests</a> under web-platform-tests. These statuses, typically added by wpt-sync when tests fail in CI, led to inaccurate reporting. Over the past six months, 106 test files on macOS, 39 on Linux, and 51 on Android stopped producing meaningful results due to entries like [OK, TIMEOUT].</li></ul><p>Similar cleanups should be performed for other components to avoid losing test coverage. Alternatively, <a href="https://github.com/mozilla/wpt-sync/blob/master/sync_prod.ini#L102-L103">enable syncbot notifications</a> for your component (opt-in) to automatically get bugs filed, which helps to keep accurate metadata under control.</p><ul><li>Julian fixed a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1983414">bug with the network.addDataCollector command which could lead to errors</a> when receiving certain requests (for instance data: URIs or cached stylesheets)</li><li>Julian <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874365">implemented a new event browsingContext.downloadWillBegin</a>, which is emitted when a download starts. The event is currently only supported on Firefox desktop, support for Android will be added later.</li><li>Sasha added <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1976493">a platform API to set timezone override</a> and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1978027">“emulation.setTimezoneOverride” WebDriver BiDi command</a>, which utilizes this API.</li><li>Sasha fixed the bug when <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1980211">locale override was sometimes shared between browsing contexts</a>. That was happening because the override was shared inside the process. With this fix, the locale override is attached to the realm, so it stays isolated in a browsing context.</li></ul><h4>Lint, Docs and Workflow</h4><ul><li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1944290">Updated ESLint to the latest v9.x version</a> (from 9.6.0).<ul><li>You may need to run ./mach eslint –setup and restart your editor if you haven’t already triggered the updates (e.g. <a href="https://firefox-source-docs.mozilla.org/code-quality/lint/usage.html#vcs-integrations">via the hooks</a>).</li><li>Standard8 also <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1395426">fixed a long standing issue</a> which was blocking the upgrade, where using /* import-globals-from … */ in a cyclic dependency way could cause problems for correctly detecting the globals.</li><li>Also <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1985519">updated</a> the other ESLint related modules to their latest versions.</li><li>Import attributes</li></ul></li><li>Stylelint is now covered under the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1983638">node-licenses checker</a>.</li><li>Jon has started rolling out a new Stylelint rule to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979115">enforce using border-radius tokens</a>.</li><li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1945456">TypeScript</a><ul><li>As part of the work for getting TypeScript ready for production, the TypeScript node_modules install has now been <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1975509">moved to the top-level of firefox-main</a>.</li><li>We’re experimenting with adding a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1986283">tier-3 linter for TypeScript</a>.<ul><li>The main aim here is to start getting feedback on how regressions in TypeScript appear on the reviewbot, and to reduce the likelihood of new issues being introduced on some of the components that we’ve already enabled TypeScript on and which have no outstanding issues currently.</li><li>This is intentionally scope limited to avoid impacting developers whilst we’re still in the set-up phase. Hence, this will report new issues against only a few components:<ul><li>{browser,toolkit}/components/search</li><li>browser/components/urlbar</li></ul></li><li>As this is Tier 3, it won’t show on CI by default, however, failures will show on reviewbot.</li></ul></li><li>There’s still a lot of work to do to get type generation set-up, documentation, and other issues fixed.</li></ul></li></ul><h4>New Tab Page</h4><ul><li>The new Sections UI was enabled by default for users in the US last week! We’ll be rolling it out to more regions in the coming weeks and months.</li></ul><p><img alt="The new Sections UI of the New Tab" class="alignnone size-large wp-image-1886" height="291" src="https://blog.nightly.mozilla.org/files/2025/09/headlines188_1-600x291.png" width="600" /></p><ul><li>Our release channel train-hop experiment has concluded, and we passed our checks! We’re now cleared to start doing these train-hops! (presuming a green light from Release Management and QA, of course)<ul><li>Special thanks to everybody who helped with this! <a href="mailto:pdahiya@mozilla.com"><span>Punam Dahiya</span></a>, <a href="mailto:lgreco@mozilla.com"><span>Luca Greco</span></a>, <a href="mailto:wdurand@mozilla.com"><span>William Durand</span></a>, <a href="mailto:amarchesini@mozilla.com"><span>Andrea Marchesini</span></a>, <a href="mailto:dmeehan@mozilla.com"><span>Donal Meehan</span></a>, <a href="mailto:ahalberstadt@mozilla.com"><span>Andrew Halberstadt</span></a>, <a href="mailto:joelm@mozilla.com"><span>Joel Maher</span></a>, <a href="mailto:beth@mozilla.com"><span>Beth Rennie</span></a>, and anybody who reviewed any of our patches or helped us out in the past few months on this project.</li></ul></li></ul><h4>Search and Navigation</h4><ul><li>Search<ul><li>Drew fixed a bug where Google Lens searches were returning invalid results when searching from an already-searched image (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1985563">1985563</a>)</li></ul></li></ul><ul><li></li></ul><ul><li>Urlbar<ul><li>Dao continued his work on the new searchbar implementation, including fixing some layout issues (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1975010">1975010</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1975011">1975011</a>)</li><li>Moritz landed a series of patches to improve provider concurrency in the urlbar (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1628016">1628016</a>)</li></ul></li></ul><ul><li></li></ul><ul><li></li><li>Firefox Suggest<ul><li><ul><li>Drew and Daisuke landed many improvements and bug fixes for the new market-related suggestions (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1985916">1985916</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1985293">1985293</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1984501">1984501</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982026">1982026</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1985260">1985260</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1985287">1985287</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982024">1982024</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982034">1982034</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982375">1982375</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982535">1982535</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1981770">1981770</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982319">1982319</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982030">1982030</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982565">1982565</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982836">1982836</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1983377">1983377</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1983027">1983027</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982603">1982603</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982031">1982031</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1984262">1984262</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1984214">1984214</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1983984">1983984</a>)</li></ul></li></ul></li></ul><ul><li>Places Database<ul><li>Marco landed a patch that replaces fixed frecency algorithm thresholds with a function that calculates those thresholds dynamically instead (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1982059">1982059</a>)</li><li>Marco also fixed two bugs stemming from crashes related to the Favicons service (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1980992">1980992</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1984088">1984088</a>)</li></ul></li></ul><ul><li></li></ul><ul><li></li></ul><ul><li><ul><li></li></ul></li></ul></description> <pubDate>Fri, 19 Sep 2025 16:56:58 +0000</pubDate> <dc:creator>Anna Kulyk</dc:creator></item><item> <title>The Rust Programming Language Blog: Announcing Rust 1.90.0</title> <guid isPermaLink="true">https://blog.rust-lang.org/2025/09/18/Rust-1.90.0/</guid> <link>https://blog.rust-lang.org/2025/09/18/Rust-1.90.0/</link> <description><p>The Rust team is happy to announce a new version of Rust, 1.90.0. Rust is a programming language empowering everyone to build reliable and efficient software.</p><p>If you have a previous version of Rust installed via <code>rustup</code>, you can get 1.90.0 with:</p><pre class="language-console z-code"><code class="language-console"><span class="z-text z-plain">$ rustup update stable</span></code></pre><p>If you don't have it already, you can <a href="https://www.rust-lang.org/install.html">get <code>rustup</code></a> from the appropriate page on our website, and check out the <a href="https://doc.rust-lang.org/stable/releases.html#version-1900-2025-09-18">detailed release notes for 1.90.0</a>.</p><p>If you'd like to help us out by testing future releases, you might consider updating locally to use the beta channel (<code>rustup default beta</code>) or the nightly channel (<code>rustup default nightly</code>). Please <a href="https://github.com/rust-lang/rust/issues/new/choose">report</a> any bugs you might come across!</p><h4><a class="anchor" href="https://blog.rust-lang.org/2025/09/18/Rust-1.90.0/#what-s-in-1-90-0-stable"></a>What's in 1.90.0 stable</h4><h3><a class="anchor" href="https://blog.rust-lang.org/2025/09/18/Rust-1.90.0/#lld-is-now-the-default-linker-on-x86-64-unknown-linux-gnu"></a>LLD is now the default linker on <code>x86_64-unknown-linux-gnu</code></h3><p>The <code>x86_64-unknown-linux-gnu</code> target will now use the LLD linker for linking Rust crates by default. This should result in improved linking performance vs the default Linux linker (BFD), particularly for large binaries, binaries with a lot of debug information, and for incremental rebuilds.</p><p>In the vast majority of cases, LLD should be backwards compatible with BFD, and you should not see any difference other than reduced compilation time. However, if you do run into any new linker issues, you can always opt out using the <code>-C linker-features=-lld</code> compiler flag. Either by adding it to the usual <code>RUSTFLAGS</code> environment variable, or to a project's <a href="https://doc.rust-lang.org/cargo/reference/config.html"><code>.cargo/config.toml</code></a> configuration file,like so:</p><pre class="language-toml z-code"><code class="language-toml"><span class="z-source z-toml"><span class="z-punctuation z-definition z-table z-begin z-toml">[</span><span class="z-meta z-tag z-table z-toml"><span class="z-entity z-name z-table z-toml">target</span><span class="z-punctuation z-separator z-table z-toml">.</span><span class="z-entity z-name z-table z-toml">x86_64-unknown-linux-gnu</span></span><span class="z-punctuation z-definition z-table z-end z-toml">]</span></span><span class="z-source z-toml"><span class="z-meta z-tag z-key z-toml"><span class="z-entity z-name z-tag z-toml">rustflags</span></span> <span class="z-punctuation z-definition z-key-value z-toml">=</span> <span class="z-punctuation z-definition z-array z-begin z-toml">[</span><span class="z-string z-quoted z-double z-basic z-toml"><span class="z-punctuation z-definition z-string z-begin z-toml">"</span>-Clinker-features=-lld<span class="z-punctuation z-definition z-string z-end z-toml">"</span></span><span class="z-punctuation z-definition z-array z-end z-toml">]</span></span></code></pre><p>If you encounter any issues with the LLD linker, please <a href="https://github.com/rust-lang/rust/issues/new/choose">let us know</a>. You can read more about the switch to LLD, some benchmark numbers and the opt out mechanism <a href="https://blog.rust-lang.org/2025/09/01/rust-lld-on-1.90.0-stable/">here</a>.</p><h5><a class="anchor" href="https://blog.rust-lang.org/2025/09/18/Rust-1.90.0/#cargo-adds-native-support-for-workspace-publishing"></a>Cargo adds native support for workspace publishing</h5><p><code>cargo publish --workspace</code> is now supported, automatically publishing all ofthe crates in a workspace in the right order (following any dependenciesbetween them).</p><p>This has long been possible with external tooling or manual ordering ofindividual publishes, but this brings the functionality into Cargo itself.</p><p>Native integration allows Cargo's publish verification to run a build acrossthe full set of to-be-published crates <em>as if</em> they were published, includingduring dry-runs. Note that publishes are still not atomic -- network errors orserver-side failures can still lead to a partially published workspace.</p><h5><a class="anchor" href="https://blog.rust-lang.org/2025/09/18/Rust-1.90.0/#demoting-x86-64-apple-darwin-to-tier-2-with-host-tools"></a>Demoting <code>x86_64-apple-darwin</code> to Tier 2 with host tools</h5><p>GitHub will soon <a href="https://github.blog/changelog/2025-07-11-upcoming-changes-to-macos-hosted-runners-macos-latest-migration-and-xcode-support-policy-updates/#macos-13-is-closing-down">discontinue</a> providing free macOS x86_64 runners for public repositories. Apple has also announced their <a href="https://en.wikipedia.org/wiki/Mac_transition_to_Apple_silicon#Timeline">plans</a> for discontinuing support for the x86_64 architecture.</p><p>In accordance with these changes, as of Rust 1.90, we have <a href="https://github.com/rust-lang/rfcs/pull/3841">demoted the <code>x86_64-apple-darwin</code> target</a> from <a href="https://doc.rust-lang.org/stable/rustc/platform-support.html#tier-1-with-host-tools">Tier 1 with host tools</a> to <a href="https://doc.rust-lang.org/stable/rustc/platform-support.html#tier-2-with-host-tools">Tier 2 with host tools</a>. This means that the target, including tools like <code>rustc</code> and <code>cargo</code>, will be guaranteed to build but is not guaranteed to pass our automated test suite.</p><p>For users, this change will not immediately cause impact. Builds of both the standard library and the compiler will still be distributed by the Rust Project for use via <code>rustup</code> or alternative installation methods while the target remains at Tier 2. Over time, it's likely that reduced test coverage for this target will cause things to break or fall out of compatibility with no further announcements.</p><h5><a class="anchor" href="https://blog.rust-lang.org/2025/09/18/Rust-1.90.0/#stabilized-apis"></a>Stabilized APIs</h5><ul><li><a href="https://doc.rust-lang.org/stable/std/primitive.usize.html#method.checked_sub_signed"><code>u{n}::checked_sub_signed</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.usize.html#method.overflowing_sub_signed"><code>u{n}::overflowing_sub_signed</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.usize.html#method.saturating_sub_signed"><code>u{n}::saturating_sub_signed</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.usize.html#method.wrapping_sub_signed"><code>u{n}::wrapping_sub_signed</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/num/enum.IntErrorKind.html#impl-Copy-for-IntErrorKind"><code>impl Copy for IntErrorKind</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/num/enum.IntErrorKind.html#impl-Hash-for-IntErrorKind"><code>impl Hash for IntErrorKind</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#impl-PartialEq%3C%26CStr%3E-for-CStr"><code>impl PartialEq&lt;&amp;CStr&gt; for CStr</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#impl-PartialEq%3CCString%3E-for-CStr"><code>impl PartialEq&lt;CString&gt; for CStr</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#impl-PartialEq%3CCow%3C'_,+CStr%3E%3E-for-CStr"><code>impl PartialEq&lt;Cow&lt;CStr&gt;&gt; for CStr</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/ffi/struct.CString.html#impl-PartialEq%3C%26CStr%3E-for-CString"><code>impl PartialEq&lt;&amp;CStr&gt; for CString</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/ffi/struct.CString.html#impl-PartialEq%3CCStr%3E-for-CString"><code>impl PartialEq&lt;CStr&gt; for CString</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/ffi/struct.CString.html#impl-PartialEq%3CCow%3C'_,+CStr%3E%3E-for-CString"><code>impl PartialEq&lt;Cow&lt;CStr&gt;&gt; for CString</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/borrow/enum.Cow.html#impl-PartialEq%3C%26CStr%3E-for-Cow%3C'_,+CStr%3E"><code>impl PartialEq&lt;&amp;CStr&gt; for Cow&lt;CStr&gt;</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/borrow/enum.Cow.html#impl-PartialEq%3CCStr%3E-for-Cow%3C'_,+CStr%3E"><code>impl PartialEq&lt;CStr&gt; for Cow&lt;CStr&gt;</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/borrow/enum.Cow.html#impl-PartialEq%3CCString%3E-for-Cow%3C'_,+CStr%3E"><code>impl PartialEq&lt;CString&gt; for Cow&lt;CStr&gt;</code></a></li></ul><p>These previously stable APIs are now stable in const contexts:</p><ul><li><a href="https://doc.rust-lang.org/stable/std/primitive.slice.html#method.reverse"><code>&lt;[T]&gt;::reverse</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.f32.html#method.floor"><code>f32::floor</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.f32.html#method.ceil"><code>f32::ceil</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.f32.html#method.trunc"><code>f32::trunc</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.f32.html#method.fract"><code>f32::fract</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.f32.html#method.round"><code>f32::round</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.f32.html#method.round_ties_even"><code>f32::round_ties_even</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.f64.html#method.floor"><code>f64::floor</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.f64.html#method.ceil"><code>f64::ceil</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.f64.html#method.trunc"><code>f64::trunc</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.f64.html#method.fract"><code>f64::fract</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.f64.html#method.round"><code>f64::round</code></a></li><li><a href="https://doc.rust-lang.org/stable/std/primitive.f64.html#method.round_ties_even"><code>f64::round_ties_even</code></a></li></ul><h5><a class="anchor" href="https://blog.rust-lang.org/2025/09/18/Rust-1.90.0/#platform-support"></a>Platform Support</h5><ul><li><code>x86_64-apple-darwin</code> is now a tier 2 target</li></ul><p>Refer to Rust’s <a href="https://doc.rust-lang.org/rustc/platform-support.html">platform support page</a> for more information on Rust’s tiered platform support.</p><h5><a class="anchor" href="https://blog.rust-lang.org/2025/09/18/Rust-1.90.0/#other-changes"></a>Other changes</h5><p>Check out everything that changed in <a href="https://github.com/rust-lang/rust/releases/tag/1.90.0">Rust</a>, <a href="https://doc.rust-lang.org/nightly/cargo/CHANGELOG.html#cargo-190-2025-09-18">Cargo</a>, and <a href="https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-190">Clippy</a>.</p><h4><a class="anchor" href="https://blog.rust-lang.org/2025/09/18/Rust-1.90.0/#contributors-to-1-90-0"></a>Contributors to 1.90.0</h4><p>Many people came together to create Rust 1.90.0. We couldn't have done it without all of you. <a href="https://thanks.rust-lang.org/rust/1.90.0/">Thanks!</a></p></description> <pubDate>Thu, 18 Sep 2025 00:00:00 +0000</pubDate> <dc:creator>The Rust Release Team</dc:creator></item><item> <title>The Servo Blog: Your Donations at Work: Funding Josh Matthews' Contributions to Servo</title> <guid isPermaLink="true">https://servo.org/blog/2025/09/17/your-donations-at-work-funding-jdm/</guid> <link>https://servo.org/blog/2025/09/17/your-donations-at-work-funding-jdm/</link> <description><p>The Servo project is excited to share that long-time maintainer <a href="https://github.com/jdm">Josh Matthews (@jdm)</a> is now working part-time on improving the Servo contributor experience.</p><p>This is a direct result of the monthly donations to the project through <a href="https://opencollective.com/servo">OpenCollective</a> and <a href="https://github.com/sponsors/servo">GitHub</a>. The generosity of our supporters has allowed us to operate dedicated computing resources for CI purposes, as well as participate in the <a href="https://www.outreachy.org/">Outreachy program</a> as a mentoring organization. We’re excited that we can now financially support developers and allow them to dedicate more time to the Servo project over longer periods.</p><p>Josh will use this funded time to make it easier for others to contribute to the project. You will see him improving documentation, reviewing pull requests, breaking down large projects into smaller actionable tasks, and generally helping others get unstuck quicker.</p><p>Here’s Josh in his own words:</p><h3>Tell us about yourself! <a class="header-anchor" href="https://servo.org/blog/2025/09/17/your-donations-at-work-funding-jdm/#tell-us-about-yourself!"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><p>I’ve been working on web browsers since 2009, with a brief diversion into distributed systems and finance for a few years. I’ve been a stay at home dad for several years, though, and Servo is a great way for me to keep that intellectual curiosity. I love helping people accomplish things they haven’t tried before; it’s a very satisfying experience to watch them flourish and grow.</p><h3>Why did you start contributing to Servo? <a class="header-anchor" href="https://servo.org/blog/2025/09/17/your-donations-at-work-funding-jdm/#why-did-you-start-contributing-to-servo%3F"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><p>The team I had lined up at Mozilla in 2012 abruptly was cancelled shortly before I started full time. I knew of the existence of the very beginnings of the Servo project, and I was in the unique position of having several years of experience in both working on Firefox and the early Rust compiler. When I suggested that I should help get Servo off the ground, everyone thought that was a good idea.</p><h3>What was challenging about your first contribution? <a class="header-anchor" href="https://servo.org/blog/2025/09/17/your-donations-at-work-funding-jdm/#what-was-challenging-about-your-first-contribution%3F"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><p>Brian Anderson (@brson) handed me a program that could parse simple HTML and a tiny bit of CSS and draw solid rectangles into a png. He said “Can you make it run JavaScript?” The amount of details I needed to learn about how a web page’s DOM gets hooked up to a JS engine were intimidating, and the relevant web standards were still quite underdeveloped in 2012. There was a lot of guessing and then going and talking to the experts from the Firefox side of the org.</p><h3>What do you like about contributing to the project? What do you get out of it? <a class="header-anchor" href="https://servo.org/blog/2025/09/17/your-donations-at-work-funding-jdm/#what-do-you-like-about-contributing-to-the-project%3F-what-do-you-get-out-of-it%3F"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><p>I love seeing familiar websites becoming more usable. I am fascinated by all the different technologies that make up rendering engines today, and all the ways we discover that websites use them. And I love working in Rust in a large project, especially one that I’m so familiar with. There are a lot of kind, talented, and clever people that contribute to the project that make it a really enjoyable experience for me.</p><h3>What is currently being worked on in Servo that you’re excited about? <a class="header-anchor" href="https://servo.org/blog/2025/09/17/your-donations-at-work-funding-jdm/#what-is-currently-being-worked-on-in-servo-that-you%E2%80%99re-excited-about%3F"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><p>The work to get the JavaScript debugger up and running will be a game changer for investigating site compatibility problems. I’m also really pleased to see work happening in the JS bindings layer—ways to reduce the number of string conversions required when going from JS-&gt;Rust-&gt;JS, or make interactions with typed arrays safer and more ergonomic. I love when we make it easier for non-experts to implement missing web APIs.</p><h3>What would you like to see the Servo community do more of? <a class="header-anchor" href="https://servo.org/blog/2025/09/17/your-donations-at-work-funding-jdm/#what-would-you-like-to-see-the-servo-community-do-more-of%3F"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><p>I would love to see more experiments with embedding Servo in other projects. The ones I know about, like the verso browser and the cuervo text-mode browser, have been enormously helpful in pointing out use cases that we had missed, or areas of the engine that could be made more modular and configurable. I’d love to get to a place where almost any major component of Servo could be replaced without forking the engine.</p><h3>Do you have any advice for new developers who are thinking of contributing to the project? <a class="header-anchor" href="https://servo.org/blog/2025/09/17/your-donations-at-work-funding-jdm/#do-you-have-any-advice-for-new-developers-who-are-thinking-of-contributing-to-the-project%3F"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><p>Choose your favourite web feature and look for it in the engine. Either it’s already implemented and you can use it to understand how some pieces fit together, or you could probably get a skeleton implementation going! Either way, we would love to help you find your way around the codebase. I take pride in the number of PRs we’ve received from people who have never written Rust code before, but their implementation is totally mergeable. I think Servo is the most approachable web rendering engine for new contributors, and I want to keep it that way.</p><h3>What do you hope to see evolve in Servo over the next 1-2 years? <a class="header-anchor" href="https://servo.org/blog/2025/09/17/your-donations-at-work-funding-jdm/#what-do-you-hope-to-see-evolve-in-servo-over-the-next-1-2-years%3F"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><p>I would love to see a larger set of maintainers who review code changes, which will be good for maintainers and contributors alike. Similarly, I’d love to see more experienced contributors writing down the details for solving complex issues that only live in their heads right now. That’s how we grow a long-term project contributor base that skills up over time, by modelling that kind of behaviour.</p><h3>Any final thoughts you’d like to share? <a class="header-anchor" href="https://servo.org/blog/2025/09/17/your-donations-at-work-funding-jdm/#any-final-thoughts-you%E2%80%99d-like-to-share%3F"> <span class="icon hashlink"><i class="fas fa-link"></i></span> </a></h3><p>I’m humbled by how many people contribute to Servo, whether financially, through code, or just Zulip discussions. I think Servo is in a really lucky position, and I hope to continue shepherding it towards a bright future.</p></description> <pubDate>Wed, 17 Sep 2025 00:00:00 +0000</pubDate></item><item> <title>Firefox Developer Experience: Firefox WebDriver Newsletter 143</title> <guid isPermaLink="false">https://fxdx.dev/?p=510</guid> <link>https://fxdx.dev/firefox-webdriver-newsletter-143/</link> <description><p><em>WebDriver is a remote control interface that enables introspection and control of user agents.</em> <em>As such it</em> <em>can</em> <em>help developers to verify that their websites are working and performing well with all major browsers. The protocol is standardized by the</em><a href="https://www.w3.org/"><em> </em><em>W3C</em></a><em> and consists of two separate specifications:</em><a href="https://w3c.github.io/webdriver/"><em> </em><em>WebDriver classic</em></a><em> (HTTP) and the new</em><a href="https://w3c.github.io/webdriver-bidi/"><em> </em><em>WebDriver BiDi</em></a><em> </em><em>(Bi-Directional).</em></p> <p><em>This newsletter gives an overview of the work we’ve done as part of the Firefox 143 release cycle</em>.</p> <h3>Contributions</h3> <p>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.</p> <p>In Firefox 143, two contributors managed to land fixes and improvements in our codebase:</p> <ul><li>Liam (ldebeasi) implemented the logic to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1754273">emit events for existing contexts</a> when subscribing to the <code>browsingContext.contextCreated</code> event.</li> <li>Sabina (sabina.zaripova) <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1972865">added an internal helper</a> to make it easier to check our session data.</li></ul> <p>WebDriver code is written in JavaScript, Python, and Rust so any web developer can contribute! Read<a href="https://firefox-source-docs.mozilla.org/devtools/getting-started/README.html"> how to setup the work environment</a> and check<a href="https://codetribute.mozilla.org/projects/automation"> the list of mentored issues</a> for Marionette, or the<a href="https://codetribute.mozilla.org/languages/javascript?project%3DWebDriver%2520BiDi"> list of mentored JavaScript bugs for WebDriver BiDi</a>. Join<a href="https://chat.mozilla.org/#/room/#webdriver:mozilla.org"> our chatroom</a> if you need any help to get started!<br /></p> <h3>WebDriver BiDi</h3> <h4>Updated: <code>browsingContext.contextCreated</code> for existing contexts</h4> <p>Updated the <code>browsingContext.contextCreated</code> event to be <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1754273">emitted for all open contexts</a> when subscribing to the event.</p> <h4>New: several commands to record network data</h4> <p>We implemented several new commands for the network module to enable recording network data.</p> <p><strong><code>network.addDataCollector</code></strong> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1971778">adds a network data collector</a> to <code>contexts</code>, <code>userContexts</code> or globally. The collector will record network data corresponding to the provided <code>dataTypes</code>. At the moment, only the <code>"response"</code> data type is supported. A <code>maxEncodedDataSize</code> must also be provided, network data exceeding this size will not be recorded.</p> <p><strong><code>network.removeDataCollector</code></strong> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1971781">removes a previously added network data collector</a>.</p> <p><strong><code>network.getData</code></strong> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1971780">retrieves the data collected</a> for a provided <code>request</code> id, <code>dataType</code> and optionally <code>collector</code> id. When providing a <code>collector</code> id, clients may also pass the <code>disown</code> flag to release the network data from the collector. Note that data is deleted when it is no longer owned by any collector.</p> <p><strong><code>network.disownData</code></strong> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1971779">releases the data</a> for a given <code>request</code> id and <code>dataType</code> from the provided <code>collector</code> id.</p> <h4>Bug fixes:</h4> <ul><li>Fixed a bug where <code>emulation.setLocaleOverride</code> <a href="https://bugzil.la/1980137">did not apply the override to newly created cross-origin iframes</a>.</li> <li>Fixed a bug where several commands such as <code>session.subscribe</code> would <a href="https://bugzil.la/1949037">fail if any tab was unloaded</a>.</li> <li>Fixed the <code>browsingContext.navigationCommitted</code> event so that the <code>url</code> property <a href="https://bugzil.la/1980137">now includes basic auth credentials</a>.</li></ul></description> <pubDate>Tue, 16 Sep 2025 19:00:00 +0000</pubDate> <dc:creator>Julian Descottes</dc:creator></item><item> <title>Mozilla Future Releases Blog: Raising the Minimum Android Version for Firefox</title> <guid isPermaLink="false">https://blog.mozilla.org/futurereleases/?p=2729</guid> <link>https://blog.mozilla.org/futurereleases/2025/09/15/raising-the-minimum-android-version-for-firefox/</link> <description><p>Mozilla has always aimed to make Firefox available to as many people as possible, including those on older Android devices. For years, we’ve supported versions of Android going all the way back to 5 (Lollipop), which first launched in 2014. That broad support has helped extend the life of many devices. However, the Android ecosystem is constantly evolving and it has become increasingly difficult for us to find ways to maintain and develop apps on these long-unsupported platforms while also allowing Firefox to take advantage of more modern devices and Android operating systems.</p><p>Beginning with Firefox 144, <strong>the minimum supported Android version will increase to 8.0 (Oreo)</strong>, which was released in 2017. At the same time, we will end support for 32-bit x86 Android devices. Usage of these older platforms has become increasingly rare, and continuing to support them has made it harder for us to deliver the best performance and reliability to the vast majority of our users.</p><p>If your device runs Android 7 or earlier, or if you rely on Firefox for a 32-bit x86 device, Firefox 143 will be the final version available to you. You will still be able to use that version, but it will no longer receive updates once Firefox 144 is released. Please note that 32-bit ARM devices will continue to be supported.</p><p>These changes apply not only to Firefox for Android but also to Firefox Focus &amp; Klar, our privacy-first browsers. By narrowing our supported platforms, we can take better advantage of modern Android APIs, improve stability and security, and focus our engineering resources where they will have the greatest impact.</p><p>We know some users will be affected by this transition, and we don’t take that lightly. Our goal remains to balance broad accessibility with the ability to deliver the best possible Firefox experience on modern hardware and operating systems.</p><p>The post <a href="https://blog.mozilla.org/futurereleases/2025/09/15/raising-the-minimum-android-version-for-firefox/">Raising the Minimum Android Version for Firefox</a> appeared first on <a href="https://blog.mozilla.org/futurereleases">Future Releases</a>.</p></description> <pubDate>Mon, 15 Sep 2025 17:00:36 +0000</pubDate> <dc:creator>Ryan VanderMeulen</dc:creator></item><item> <title>Mozilla Thunderbird: Mobile Progress Report – July/August 2025</title> <guid isPermaLink="false">https://blog.thunderbird.net/?p=3793</guid> <link>https://blog.thunderbird.net/2025/09/mobile-progress-report-july-august-2025/</link> <description><p><img alt="" class="attachment-640x360 size-640x360 wp-post-image" height="360" src="https://blog.thunderbird.net/files/2025/09/blog-banner-mobile-1-768x432.jpg" width="640" /></p><p>Hello wonderful community, it has been a while since the <a href="https://blog.thunderbird.net/2025/07/mobile-progress-report-june-2025/">last Mobile update</a>.</p> <p>A lot has happened in the past 2 months, so let’s jump right into a quick overview of current work in progress and primary efforts.</p> <h4>Account Drawer in progress</h4> <p>If you’re rocking the Beta version of Thunderbird for Android, you might have noticed that all your unified folders have disappeared! Don’t panic, that’s just temporary.</p> <p>We’re still churning through the technical debt and the database inconsistencies in order to create through virtual unified folders for all your accounts.</p> <p>The final goal is the same as the one we shared in a previous update, which you can see the final mock-ups here:</p> <figure class="wp-block-image size-full"><a href="https://blog.thunderbird.net/files/2025/09/Mobile-Update-July_August.png"><img alt="" class="wp-image-3794" height="647" src="https://blog.thunderbird.net/files/2025/09/Mobile-Update-July_August.png" width="1600" /></a></figure> <p>Expect more updates in the coming releases.</p> <h3>iOS account setup</h3> <p>The work on the iOS version is moving at full speed!</p> <p>We found ourselves in a bit of a tight spot due to the recent announcements of Apple with their new iOS 26 version, and a somewhat complete redesign of all the SwiftUI and general Human Interface Guidelines.</p> <p>When will iOS 26 be widely available and adopted?</p> <p>Will we have our iOS version of Thunderbird ready before that?</p> <p>If we build it on current iOS 18 design guidelines, how would that look on the new version?</p> <p>Will we need to update everything right after releasing the first version?</p> <p>Due to these uncertainties, we decided to focus only on the new iOS 26 user interface and be compatible with the new version right off the bat.</p> <p>We will need to test and explore carefully how that behaves on iOS 18 and prior, hoping for some available translation layers in order to guarantee compatibility.</p> <p>For now, here’s a sneak peek of the Account Setup flow for iOS!</p> <figure class="wp-block-image size-full"><a href="https://blog.thunderbird.net/files/2025/09/Mobile-Update-July_August1.png"><img alt="" class="wp-image-3800" height="1600" src="https://blog.thunderbird.net/files/2025/09/Mobile-Update-July_August1.png" width="1312" /></a></figure> <h3>Read/Unread status improvements in Android</h3> <p>As we move through an old codebase and we work hard to modernize components and layouts, it is unfortunately inevitable that we accidentally break old features or setups that are familiar to users.</p> <p>We apologize for the inconvenience, especially in this latest highlighted issue which created some discomfort when it comes to the visual distinction between read and unread messages.</p> <p>The old UI offered an option to customize the background color of those states. Even if this solution sounds like a good approach, it created multiple problems related to following system themes, light/dark mode variations, and the overall outdated implementation that needed to be removed.</p> <p>Some users were dissatisfied, and rightly so, due to the less than optimal visual distinction between those states that solely relied on background colors.</p> <p>We already improved the overall visual consistency and distinction in that area, but we’re working towards implementing a much clearer visual representation for each state that doesn’t just rely on background colors.</p> <p>We’re implementing a combination of background and foreground colors, font weight variation, and a visual indicator that specifically represents unread and new messages.</p> <p>This approach will remove any confusion and hopefully completely fix this problem.</p> <p>Thank you all those involved for your feedback and concerns, and for using the Beta version to provide early feedback and test the new updates.</p> <h3>A new release cadence</h3> <p>Starting from September, we’re switching to a faster and more consistent release cadence.</p> <p>The first week of every month we will release a new beta version, for example v13b1, followed by a new incremental beta version with improvements and fixes directly from the main branch, being released every week during that month (eg: v13b2, v13b3, etc).</p> <p>At the end of that month, the current beta, after being deemed reliable and having passed our QA steps, will be promoted as a stable version and at the same time a new beta branch will be released.</p> <p>In summary, starting from September you can expect a new stable version and a new beta cycle every month.</p> <p>Changing our cadence will allow us to expose new and work in progress features more quickly to our beta audience, and shorten the waiting time for users on the stable branch, with smaller and consistent incremental improvements.</p> <p>Cheers,</p> <p>—</p> <p><strong>Alessandro Castellani</strong>(he, him)<br /><strong>Director, Desktop and Mobile Apps</strong> | Mozilla Thunderbird</p><p>The post <a href="https://blog.thunderbird.net/2025/09/mobile-progress-report-july-august-2025/">Mobile Progress Report – July/August 2025</a> appeared first on <a href="https://blog.thunderbird.net">The Thunderbird Blog</a>.</p></description> <pubDate>Mon, 15 Sep 2025 15:09:31 +0000</pubDate> <dc:creator>Alessandro Castellani</dc:creator></item><item> <title>Firefox Nightly: Webcam previews and more! – These Weeks in Firefox: Issue 187</title> <guid isPermaLink="false">https://blog.nightly.mozilla.org/?p=1893</guid> <link>https://blog.nightly.mozilla.org/2025/09/12/webcam-previews-and-more-these-weeks-in-firefox-issue-187/</link> <description><h3>Highlights</h3><ul><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=557153">Nicolas Chevobbe</a> added presentational hints in the Inspector’s rule-view (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1212289">#1212289</a>)</li></ul><p><img alt="Presentational hints in the Inspector's rule-view" class="alignnone size-large wp-image-1898" height="183" src="https://blog.nightly.mozilla.org/files/2025/09/headlines187_2-600x183.png" width="600" /></p><ul><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=774869">Nate Gross</a> added a new getKeys API method available across all browser.storage APIs (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1910669">Bug 1910669</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=636491">Emma Zühlcke (:emz)</a> added a fix so that the users can preview their webcam(s) before giving sites access to it. (To make sure users look their best, or just to figure out which of their many webcams is the correct one). (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=799415">Bug 799415</a>)</li></ul><p><img alt="Webcam preview" class="alignnone size-full wp-image-1897" height="530" src="https://blog.nightly.mozilla.org/files/2025/09/headlines187_1.png" width="562" /></p><ul><li>The New Tab team is testing out productivity widgets like a focus timer for healthy screen-time breaks and a list widget to manage your tasks.</li></ul><p><img alt="New Tab productivity widgets" class="alignnone size-large wp-image-1899" height="307" src="https://blog.nightly.mozilla.org/files/2025/09/headlines187_3-600x307.png" width="600" /></p><h3>Friends of the Firefox team</h3><h4><a href="https://bugzilla.mozilla.org/buglist.cgi?title=Resolved%20bugs%20(excluding%20employees)&amp;quicksearch=1975093%2C1976968%2C1977124%2C1910669%2C1977066%2C1943057%2C1884618%2C1936018%2C1975872%2C1979623%2C1979294%2C1957214%2C1974983%2C1980170%2C1959618%2C1980854%2C1754273%2C1497064%2C1981039">Resolved bugs (excluding employees)</a></h4><h4>Volunteers that fixed more than one bug</h4><ul><li>Gregory Pappas [:gregp]</li><li>Mauro V [:cheff]</li></ul><h4>New contributors (🌟 = first patch)</h4><ul><li>Jacqueline Amherst <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1959618">helped reorganize some of the code that we use for performing navigations from the front-end code</a></li><li>Mason Abbruzzese <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1957214">cleaned up an old and outdated comment in our code</a></li><li>Nate Gross <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1910669">added a new getKeys API method available across all browser.storage APIs</a></li><li>chase.philpot <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1884618">cleaned up some old extensions utility code written from the era before DOM Promises</a></li><li>Richard LoRicco <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1975872">got rid of some unnecessary awaits in some of our preferences tests</a></li><li>Jim Gong made it so that <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1497064">we fail more gracefully when WebExtensions attempt to set cookies with invalid URLs</a></li></ul><h3>Project Updates</h3><h4>Add-ons / Web Extensions</h4><h5>WebExtension APIs</h5><ul><li>Thanks to Jim Gong contributing changes needed to improve the errors reported by browser.cookies.set API method on invalid domains (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1497064">Bug 1497064</a>)</li></ul><h5>WebExtensions Framework</h5><ul><li>WebExtensions framework and AddonManager internals cleanups:<ul><li>Thanks to Chase Philpot for contributing to WebExtensions internals cleanups by removing the now unnecessary filterStack helper function from the WebExtensions internals (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1884618">Bug 1884618</a>)</li><li>Thanks to Mauro V. [:cheff] for removing old rollout prefs for the userScripts APIs (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1943057">Bug 1943057</a>)</li><li>Migrating tests away from deprecated InstallTrigger API (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979294">Bug 1979294</a> / <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979648">Bug 1979648</a> / <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979657">Bug 1979657</a> / <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979690">Bug 1979690</a> / <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979712">Bug 1979712</a> / <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1980604">Bug 1980604</a>), in preparation for fully removing the InstallTrigger API implementation (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1776426">Bug 1776426</a>)<ul><li>Huge shout out goes to Gregory Pappas 🎉 for his contributions to the work for removing the deprecated InstallTrigger API, as well as for fixing an issue (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979281">Bug 1979281</a>) preventing use of Mochia test helpers in mochitest-browser tests and then refactoring browser_doorhanger_installs.js test cases to use the Mochia describe/it test helpers (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979294">Bug 1979294</a>) 😍</li></ul></li></ul></li><li>Investigated issue introduced in recently released 1password WebExtension versions, which was triggering the extension process to hang, reported to 1password developers which have released a fixed version of their add-on (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1980009">Bug 1980009</a>)<ul><li>We have also investigated why ProcessHangMonitor isn’t currently detecting and showing to the user a notification box on slow scripts that are making the extension process hanging and filed <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1980452">Bug 1980452</a> to capture the findings and tracking fixing that as a followup for the 1password incident.</li></ul></li><li>Investigated and fixed AsyncShutdown failures hit due to a race between application shutdown and active add-ons background pages starting up (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1959339">Bug 1959339</a>)</li><li>As part of introducing support for WPT WebExtensions API tests (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1949012">Bug 1949012</a>), new browser.test.onTestStarted and browser.test.onTestFinished API events are now supported from inside tests running WPT mode (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1971013">Bug 1971013</a>)</li><li>Replaced mouseenter/mouseleave with mouseove/mouseout in browser-addons.js logic handled the extensions button auto-hiding mode (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1976773">Bug 1976773</a>)</li><li>Fixed bug which was generating WebExtensions uuids for extensions not yet installed and increasing the size of extensions.webextensions.uuids pref value unnecessarily (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1974419">Bug 1974419</a>)</li></ul><h5>Addon Manager &amp; about:addons</h5><ul><li>Added new localized string to improve error message shown on add-on install flows failing due to errors hit on accessing the XPI file being installed (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1976490">Bug 1976490</a>)</li></ul><h4>DevTools</h4><ul><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=473060">Kagami Rosylight</a> migrated the DevTools color picker widget to Fluent for devtools color picker widget (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1978294">#1978294</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=283262">Alexandre Poirot</a> improved performance of the Debugger sources tree on pages with a lot of sources (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1976570">#1976570</a>)<ul><li>For example, on a page with 90K sources, on Alex’s machine, we went from 3800ms to 190ms</li></ul></li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=283262">Alexandre Poirot</a> was able to make the Debugger reuse the same tab when pretty printing a source (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1971817">#1971817</a>)<ul><li>It used to create a new Tab with the pretty content, which could be confusing</li></ul></li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=557153">Nicolas Chevobbe</a> removed usage of the <a href="https://www.npmjs.com/package/whatwg-url">whatwg-url</a> package in our source map code, which <a href="https://treeherder.mozilla.org/perfherder/alerts?id=46058">significantly improved performance</a> (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1829610">#1829610</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=559949">Julian Descottes</a> made the “tab toolbox” (e.g. about:debugging) to be focused when the tab was in background and a breakpoint is hit (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1978100">#1978100</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=557153">Nicolas Chevobbe</a> fixed 2 regressions in the markup view:<ul><li>First, the tree would no longer gets focused when opening the inspector via the “Inspect” context menu (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979591">#1979591</a>)</li><li>Second, the search wouldn’t find css selector with tagname + class with hyphens (e.g. div.narrow-item) (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1980892">#1980892</a>)</li></ul></li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=559949">Julian Descottes</a> fixed the splitter in Memory panel for the Retaining Paths view (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1978538">#1978538</a>)</li><li><a href="https://bugzilla.mozilla.org/user_profile?user_id=557153">Nicolas Chevobbe</a> made “Group Similar Messages” setting also impact the “repeat bubble”: when the feature is disabled, successive similar messages will all be displayed in the console (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1615206">#1615206</a>)</li></ul><h4>WebDriver BiDi</h4><ul><li>Sabina added a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1972865">new helper to check if there is existing session data matching specific criteria</a>, and at the same time cleaned up the SessionData class to use proper private fields and methods where possible.</li><li>Mauro <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1938638">removed the deprecated “–enable-crash-reporter” argument from geckodriver</a>.</li><li>Sasha fixed a bug when <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1978533">locale override, set with “emulation.setLocaleOverride” command, was not inherited to newly created cross-origin iframes</a>.</li></ul><h4>New Tab Page</h4><ul><li>We are experimenting adding productivity widgets to new tab in 143<ul><li>To enable:<ul><li>Browser.newtabpage.activity-stream.widgets.system.enabled (allow all widgets)</li><li>Timer<ul><li>browser.newtabpage.activity-stream.widgets.system.focusTimer.enabled</li><li>browser.newtabpage.activity-stream.widgets.focusTimer.enabled</li><li>browser.newtabpage.activity-stream.widgets.focusTimer.showSystemNotifications</li></ul></li><li>Lists<ul><li>browser.newtabpage.activity-stream.widgets.system.lists.enabled</li><li>browser.newtabpage.activity-stream.widgets.lists.enabled</li></ul></li></ul></li></ul></li><li>We’re aiming to do our first train-hop pilot to Beta either later this week or early next!</li></ul><h4>Search and Navigation</h4><ul><li>Drew has added a “Search Image” context menu for visual search – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1977965">1977965</a></li><li>Moritz has enabled urlbar deduplication by default – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979658">1979658</a></li><li>Dao is working on several refactors to enable reuse of the urlbar – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1980372">1980372</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1980913">1980913</a></li><li>Daisuke has started working on stock suggestions – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1969990">1969990</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979232">1979232</a></li><li>Mark fixed several bug with Rakuten – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1979030">1979030</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1924693">1924693</a></li><li>Marco fixed bug with results flashing – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1978283">1978283</a></li><li>Emilio polished the padding of the library toolbar – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1978699">1978699</a></li></ul></description> <pubDate>Fri, 12 Sep 2025 19:59:17 +0000</pubDate> <dc:creator>Anna Kulyk</dc:creator></item><item> <title>The Rust Programming Language Blog: crates.io phishing campaign</title> <guid isPermaLink="true">https://blog.rust-lang.org/2025/09/12/crates-io-phishing-campaign/</guid> <link>https://blog.rust-lang.org/2025/09/12/crates-io-phishing-campaign/</link> <description><p>We received multiple reports of a phishing campaign targeting crates.io users(from the <code>rustfoundation.dev</code> domain name), mentioning a compromise of ourinfrastructure and asking users to authenticate to limit damage to their crates.</p><p>These emails are malicious and come from a domain name not controlled by theRust Foundation (nor the Rust Project), seemingly with the purpose of stealingyour GitHub credentials. We have no evidence of a compromise of the crates.ioinfrastructure.</p><p>We are taking steps to get the domain name taken down and to monitor forsuspicious activity on crates.io. Do not follow any links in these emails if youreceive them, and mark them as phishing with your email provider.</p><p>If you have any further questions please reach out to <a href="mailto:security@rust-lang.org">security@rust-lang.org</a>and <a href="mailto:help@crates.io">help@crates.io</a>.</p></description> <pubDate>Fri, 12 Sep 2025 00:00:00 +0000</pubDate> <dc:creator>Rust Security Response WG, crates.io team</dc:creator></item> </channel></rss> If you would like to create a banner that links to this page (i.e. this validation result), do the following:
Download the "valid RSS" banner.
Upload the image to your own server. (This step is important. Please do not link directly to the image on this server.)
Add this HTML to your page (change the image src attribute if necessary):
If you would like to create a text link instead, here is the URL you can use:
http://www.feedvalidator.org/check.cgi?url=http%3A//planet.mozilla.org/rss20.xml