Skip to content

Browser extensions update whenever they feel like it

Tom Riley Aug 13, 2025

Recently our cofounder Will reported a bug he was seeing with the Firefox version of our WonderSwitcher browser extension. Our extension userbase is weighted heavily towards Chrome and Edge users, but it was good to get some feedback from a real-life Firefox user. The problem he was seeing was this - he would activate a proxy for a specific location, browse to a website he was expecting to see geo-specific content for, but then notice that requests were not being proxied and the extension UI had changed to show that the proxy had deactivated. After reactivating the proxy, everything worked as expected.

This is a task that Will performs infrequently but by using the same process every time, and reported that he’d seen this happen multiple times in the past. I had a suspicion that maybe the extension’s background page was being reloaded unexpectedly, so the first thing I tried to reproduce the issue was follow his steps, but manually call browser.runtime.reload() in the extension’s console before navigating to the test website. Sure enough, I saw the same result. The extension’s background page was probably reloading unexpectedly, and the thing most likely to cause that was an extension version automatic update.

Years ago, when both the Chrome and Firefox versions of WonderSwitcher were built from mostly the same source code, this was actually the default behaviour - the background page reloading for any reason would deactivate any active proxy. Since the major rework of the Chrome extension to support MV3, we’d changed the behaviour in that browser to maintain any active proxy across extension/browser reloads, since Chrome’s mandatory MV3 support requires us to support the background Service Worker suspending and unsuspending at unpredictable times. It looks like we’d overlooked this in the Firefox extension (which still uses a persistent background script) and never brought that functionality in line.

How browser extension updates work

It wasn’t until this happened to Will that we realised how “forced” browser extension updates in every browser are. Google doesn’t provide much official documentation about the extension update process beyond saying “Chrome periodically checks extension hosts for new versions of installed extensions and automatically updates them without user intervention”. Looking at the Chromium source code though, we can see the check interval is currently (Chrome 139) every 5 hours:

Mozilla do specify “Firefox checks for updates every 86400 seconds (24 hours)”. However, in both cases the user doesn’t have control over this (unless you’re a Firefox user who likes tinkering in about:config, or a Chrome user who wants to run it with command line flags). Once the browser knows there’s an update for an extension, the default behaviour is to immediately apply it and reload the extension.

A “reload” after update means that the central background script of the extension will be stopped and then started again using the updated code. Any extension windows (like the popup and options) will be closed. Connections to content scripts running in webpages may break. Any extension application state in memory that has not been saved to storage will be lost. This means that in the same way any important user state data needs to be stored to persist browser restarts, developers must also consider the same thing happening when the extension (seemingly randomly) updates and restarts - but without the flexibility of knowing that the browser has only just started. The user could be in the middle of a task at the moment this happens, making UX considerations particularly fiddly. It’s likely that any initialisation code that runs on a normal extension start will need to be significantly different to handle starting after an extension update.

Extension developers may make use of the browser.runtime.onUpdateAvailable event to give their users a warning that an update is going to happen. But at the point that event fires, the update is already going to be applied on the next background reload (for Chrome MV3 extensions this may be after the service worker next suspends and then starts up again). So, the most helpful message that can be shown to a user would be to warn them it is going to happen soon, with maybe a “Just do it right now” option.

Developers also have access to other useful web extension API features related to extension updates, but unfortunately they’re read only, and don’t provide control over the process.

The browser.runtime.onInstalled event is fired “when the extension is first installed, when the extension is updated to a new version, and when the browser is updated to a new version.” The callback for this will receive a nice details object which always includes a reason (being one of “install”, “update” or “browser_update”). And if the reason is “update”, details will also have a previousVersion property, so you can see which version the user has updated from.

This is useful if you want to build UI features around relaying to the user exactly what is happening to them (like displaying a changelog), since there’s nothing they can do about it. However, unless you’re distributing your extension in an Enterprise setup, or you’re willing to bypass the browser extension stores completely, the version check URL, lack of a rollback mechanism, and update process are completely out of the control of the user and mostly out of the control of the developer.

What could go wrong?

In the past we actually had a WonderSwitcher bug reported which we narrowed down to being caused by another very popular extension which those users had installed. And after conversing with that extension’s company, we discovered that it was because their release contained a bug (improper handling of a blocking callback) which left everyone wishing more advanced extension version management was available. But that’s probably a whole other blog post…

The experience with tracing Will's issue back to a quiet automatic update hammered something home for us: browser extension updates aren't necessarily just routine maintenance. They can disrupt functionality, reset state, confuse users, and introduce fiddly bugs if you don't preempt them. And since these updates are automatic and invisible, users probably won't know what happened or why something unexpectedly changed.

I’m sure there are constraints beyond my comprehension as to why browser vendors are so single-minded about these policies. However, in today’s semantically versioned world of complex dependency graphs, maybe relinquishing some control would ultimately be better and improve the platform for everyone? Especially since the whole reason many extensions exist is that they enable beneficial functionality by allowing users to agree to certain privileges not normally allowed by the browser.

Tom Riley

Tom is a developer in Bristol, UK working mainly with JavaScript. If not coding, you’ll find him playing with his kid, consuming scifi/films, running/swimming or listening to industrial music.