plugin-web-update-notification: telling a browser its bundle is stale
Tiny lib, Detect webpage updates and notify user to reload. support Vite、Umijs、Rspack、Webpack、Nuxt.
At a glance
- What is it?
- plugin-web-update-notification is a small TypeScript build plugin that writes a version file at build time and polls it from the browser, so a page left open tells the user to reload instead of silently running old code. It works with Vite, UmiJS, Webpack, Rspack and Nuxt, and it does nothing at all in development mode.
- Who is it for?
- plugin-web-update-notification fits a team that deploys a single page app to a static host, where users keep tabs open across deploys and would otherwise be looking at a stale bundle, and that is willing to configure a version strategy per project. It does not fit an application that must never interrupt the user mid-task, and it does not fit a developer who expects a dev-server update, because the plugin explicitly does not take effect in development mode.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 15 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem is a tab that was open before the deploy
A single page application serves static assets, so a user who opened a page before your deploy keeps running the JavaScript that was in their browser cache while your server is already serving the new build. The mismatch causes the classic symptoms: a chunk that 404s, a component that expects a field the old bundle does not have, or a feature that quietly does nothing. The plugin's whole job is to detect that situation and tell the person to reload. The mechanism the README describes is a version number on each side and a comparison between them. The version comes from the build, is written into a file, and the client polls the server's copy of that file. When the two differ, the user is notified to refresh the page, and the README notes that you can customise that behaviour. The audience is a frontend team shipping SPAs where this failure mode is common enough to be worth a build step.
Four triggers for the version check, and one of them is the important one
The client fetches version.json at four moments, as the README lists. The first is the first load of the page. The second is polling, with a default interval of ten minutes, that is 10*60*1000 milliseconds. The third is a detected script resource loading failure, described as a 404. The fourth is when the tab page is refocused or becomes visible again. That last one is the mechanism that actually solves the problem in practice. A user who has the tab in the background, who switches away to do something else and comes back, gets a fresh version check the moment the tab becomes visible, and a user who never returns to the tab is the user who does not need to be interrupted. The description in the README mentions the visibilitychange or focus event as the assistant for this. The polling interval is a fallback for the case where the tab stays in the foreground, and the 404 detection catches the case where the new build has already invalidated a chunk the old page is trying to load.
Version strategies: git hash, svn revision, package version, timestamp
The build time phase resolves a version number and writes it into artifacts. The README's flowchart for that phase shows the plugin starting by auto detecting the repository type, looking for a .git or a .svn directory, and then branching on the versionType setting. The git_commit_hash strategy runs git rev-parse --short HEAD, the svn_revision_number strategy runs svnversion, and the pkg_version strategy reads process.env.npm_package_version. Two more options exist: build_timestamp, which uses Date.now(), and custom, which uses a customVersion option you provide. Each of these is checked for success, and a failure falls back to build_timestamp so the build never breaks over a missing command. The last step in the flow emits the version artifacts, version.json, .js and .css, each carrying an MD5 first-8 content hash, and then injects into the HTML through transformIndexHtml. That content hash is what makes the emitted files themselves cache-bust, so the browser picks up the new version file rather than a cached one.
One package, five build tool adapters
The plugin is distributed as a monorepo with per-tool packages, and the top level package.json shows how the workspace is wired. The scripts section names the build pipeline and one development command per integration.
"build": "turbo run build --filter='./packages/*'",
"dev:vite": "pnpm --filter=@plugin-web-update-notification/vite dev",
"dev:umi": "pnpm --filter=@plugin-web-update-notification/core dev",
"dev:webpack": "pnpm --filter=@plugin-web-update-notification/webpack dev",
"dev:nuxt": "pnpm --filter=@plugin-web-update-notification/nuxt dev",So the supported tools are Vite, UmiJS, Webpack, Rspack and Nuxt, with the plugin itself distributed on npm under the @plugin-web-update-notification scope. The root package is marked private with type module, and it ships only its dist directory. The examples directory in the repository makes the coverage concrete: there is an example for Nuxt, react-vite, svelte-vite, vue-cli, vue-rspack, and three generations of vue-vite at versions 3, 5 and 7, which tells you the plugin tracks the Vite major versions rather than only the newest one. Each example has its own preview script in the root package.json.
"example:vue-vite": "pnpm --filter=vue-vite-example preview",
"example:react-vite": "pnpm --filter=react-vite-example preview",
"example:svelte-vite": "pnpm --filter svelte-vite-example preview",Seeing the notification for yourself takes a redeploy
The README describes a manual verification loop, and it is worth following exactly because the plugin is invisible otherwise. Install the plugin with the default configuration, package and deploy the application, then open a browser to visit the page. That tab is Tab A. Then modify the code, repackage and redeploy, and the default versionType requires a git commit for the version number to change, so commit your change as part of the redeploy. Finally re-enter the previously opened Tab A, and the update notification appears in the lower right corner. The window between opening the tab and coming back to it is the whole point: the plugin is comparing a version the page was built with against a version the server now reports. The one caveat in the README is that the current plugin will not take effect in development mode, which is sensible, since a dev server serves fresh modules on every request and the problem does not exist there.
A tiny package with a small surface area
The design goal in the repository description is a tiny lib, and the package metadata backs that up. The published root package is the aggregator, with the actual npm packages under the @plugin-web-update-notification scope, and the client entry point is a single injected script that the badge links to as webUpdateNoticeInjectScript.js in the core package's dist directory. The root package.json is marked with sideEffects false, so bundlers can tree-shake it, and it exports both a require build at ./dist/index.js and an ES module build at ./dist/index.mjs, with types at ./dist/index.d.ts and a typesVersions map for older resolvers. The package is MIT licensed, authored as Utopia, and the default branch is main. The repository itself is a pnpm workspace with a pnpm-lock.yaml, a pnpm-workspace.yaml, a turbo.json for the build orchestration, and vitest.config.ts for the tests.
Where a version poll is the wrong answer
There are deployments where telling the user to reload is not acceptable. If the application holds unsaved work, if it is a trading or medical interface, if a reload loses a session mid-task, then a notification is a decision the product has to make rather than something the build can decide for you. The README says the behaviour can be customised, which is the right place to solve that, but the default is a prompt and the responsibility sits with the integrator.
A second limit is the dependency on the version number changing. With the default git commit hash strategy, a redeploy of identical code produces a different version, so users are told to reload for no reason. That is a false positive rate you control by choosing a different versionType, but every choice has a cost: the package version changes only on a release, the build timestamp changes on every build, and the custom option pushes the decision into your release script. The third limit is the check itself. The plugin detects that the version file changed, and it does not detect what changed, so a reload during a deploy can land a page whose chunks are only partly uploaded, which is the usual reason behind the 404 trigger in the list of checks.
Editorial conclusion
plugin-web-update-notification fits a team that deploys a single page app to a static host, where users keep tabs open across deploys and would otherwise be looking at a stale bundle, and that is willing to configure a version strategy per project. It does not fit an application that must never interrupt the user mid-task, and it does not fit a developer who expects a dev-server update, because the plugin explicitly does not take effect in development mode. Before you adopt it, choose the versionType that matches your release process, since the default needs a git commit to change the version number, and confirm the notification behaviour suits your users, since the README says you can customise it.
Frequently asked questions
What does plugin-web-update-notification do?
It detects that a deployed web page is out of date and notifies the user to reload. The version number is taken from the build, written into a file, and the client polls the server's copy and compares it with the local one, and you can customise what happens when they differ.
Which build tools does plugin-web-update-notification support?
The README lists Vite, UmiJS, Webpack, Rspack and Nuxt. The repository keeps one package per integration under the @plugin-web-update-notification scope, with separate dev scripts for the vite, core (umi), webpack and nuxt packages, and examples for Nuxt, react-vite, svelte-vite, vue-cli, vue-rspack and vue-vite 3, 5 and 7.
How does the plugin decide which version number to use?
The build phase auto detects the repository type by looking for .git or .svn, then follows the configured versionType: git_commit_hash runs git rev-parse --short HEAD, svn_revision_number runs svnversion, pkg_version reads process.env.npm_package_version, build_timestamp uses Date.now(), and custom uses your customVersion option. If the chosen command fails, it falls back to the build timestamp.
When does the client check for a new version?
On the first page load, on a poll whose default interval is 10*60*1000 milliseconds, when a script resource load failure such as a 404 is detected, and when the tab is refocused or becomes visible again.
Does the plugin work in development mode?
No. The README states that the current plugin will not take effect in development mode. It is meant for the built and deployed application, and the manual check the README describes requires a build, a deploy, and then a redeploy after a change.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/greatauk-plugin-web-update-notification)Was this useful?