CLI tool
browserslist/update-db avatar
browserslist/update-db

update-browserslist-db: keeping caniuse-lite in step with your browser targets

CLI tool to update caniuse-lite to refresh target browsers from Browserslist config

858 stars229 forksJavaScriptMIT

At a glance

What is it?
update-browserslist-db is a small command line tool that refreshes the caniuse-lite data in your lock file so that queries like last 2 versions or greater than one percent resolve against current browser statistics rather than the snapshot your project was created with. It runs through npx, pnpm dlx, bunx or yarn dlx, and it is built by Evil Martians.
Who is it for?
Adopt update-browserslist-db in any project whose Browserslist queries are relative, such as last 2 versions or greater than one percent, and schedule it alongside your dependency updates so the browser data does not silently age. Do not run it in a project that pins explicit browser versions, because there is nothing for it to resolve.
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 17 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the tool does and why the data goes stale

update-browserslist-db is a CLI tool to update caniuse-lite with the browsers database from the Browserslist config. The description frames it precisely: it refreshes the target browsers derived from your Browserslist configuration.

The problem it solves is not obvious until you have hit it. Browserslist queries like last 2 versions or greater than one percent depend on actual data from caniuse-lite, and caniuse-lite is a pinned dependency in your lock file. That means the answer to those queries is frozen at the moment the dependency was installed. A project created two years ago that did not update its dependencies will have last 1 version resolve to browsers that were current two years ago, which is what the README describes.

The fix is a data refresh rather than a code change, which is why this exists as a separate tool rather than as part of Browserslist itself. The command updates the caniuse-lite version in your npm, yarn or pnpm lock file, which brings data about new browsers to polyfill tools like Autoprefixer or Babel and reduces already unnecessary polyfills.

There are three reasons the README gives for doing this regularly. First, to use the latest browser versions and statistics in queries like last 2 versions or greater than one percent. Second, actual browser data leads to using fewer polyfills, which reduces the size of JS and CSS files and improves website performance. Third, caniuse-lite deduplication, to synchronise versions in different tools, which is a housekeeping point: when several tools in the same project depend on different caniuse-lite versions, the lock file ends up with more than one copy and the update synchronises them.

The project is built by Evil Martians, described as an American design and engineering consultancy for developer tools, AI and cybersecurity startups, and the author of the package is Andrey Sitnik, who is also the author of Browserslist itself.

Running it through whichever package manager you already use

There is one command per package manager, and the README gives all four so that you do not have to work out the equivalent yourself.

With npm:

sh
npx update-browserslist-db@latest

With pnpm:

sh
pnpm dlx update-browserslist-db latest

With bun:

sh
bunx update-browserslist-db@latest

And with yarn 2 and above:

sh
yarn dlx update-browserslist-db@latest

The differences are only in the argument syntax. The npm, bun and yarn forms all use the @latest suffix as part of the package name, while the pnpm form passes latest as a separate argument, which is how pnpm dlx expresses the same intent.

That every major runner is covered matters more than it looks. This is a tool you are expected to run periodically, and a tool you can only run through one package manager is a tool you do not run at all.

The repository layout is consistent with a small, focused utility: a cli.js as the binary entry point, an index.js and utils.js for the logic, a check-npm-version.js script, an index.d.ts for types, a test/ directory, and configuration for oxlint and oxfmt. The CHANGELOG.md and a pnpm-lock.yaml with a pnpm-workspace.yaml complete it, along with a .devcontainer.json for development.

The dependency contract and the size budget

The package metadata is short and it constrains the tool in ways that are worth reading before you depend on it.

There are two runtime dependencies: escalade at 3.2.0 or newer, which is the module for walking up a directory tree, and picocolors at 1.1.1 or newer for terminal colour output. Two dependencies for a tool that updates one lock file entry is a small surface, and escalade is doing the work of finding the lock file from wherever the command was run.

There is a peer dependency on browserslist at 4.21.0 or newer, which is a strong statement about what the tool expects to find in your project. The tool reads your Browserslist configuration to work out what browsers your queries resolve to, and it needs a recent enough Browserslist to parse whatever configuration syntax you have written.

The size-limit configuration puts a 16 KB limit on index.js, which is an unusual and useful piece of discipline for a CLI. It means the library entry point is expected to stay small, and it is checked as part of the test run rather than left to review.

The coverage configuration is just as strict. The c8 settings enable check-coverage, exclude the test files, require 100 percent line coverage, and report in lcov format. The test scripts run uvu against the test directory, with oxlint for linting and c8 for the coverage wrapper, and the test script runs them all through a regex over the script names.

That combination, a size budget and full line coverage enforced in CI, is a reasonable signal about the project's seriousness for something whose entire job is a handful of lines of logic. The risk in this kind of tool is not a subtle bug in the algorithm but a silent mismatch with a lock file format that has changed, and that is what the tests are there to catch.

Where it fits in a dependency update routine

The natural home for this tool is alongside whatever already refreshes your dependencies, and that is how most people will encounter it.

The reason a relative query goes stale is that the answer depends on two things that change independently. The Browserslist query stays the same, but the data behind it moves. A lock file pins the data, and most lock files are only updated when a human runs a dependency bump or when an automated update opens a pull request.

So the tool belongs in that pull request cycle. When the automated dependency update refreshes the lock file, running update-browserslist-db makes sure the caniuse-lite entry in the same diff is current too, and the resulting change to your browser targets is visible in the same review as the rest of the dependency change.

That is a better model than running it ad hoc on developer machines, because the consequence of a refresh is visible. A query like last 2 versions that suddenly stops including a browser is a change to what your build targets, and it should be reviewed like any other change rather than appearing as a silent side effect of one developer's local run.

The README's second reason points at the payoff. Actual browser data leads to using less polyfill, which reduces the size of JS and CSS files and improves website performance. So a project that was polyfilling for browsers that have not been relevant for two years is shipping bytes for nothing, and the tool is what removes them.

The third reason, deduplication, is the least interesting and the one most likely to be noticed by a reviewer looking at the lock file diff, because the update may collapse two copies of caniuse-lite into one.

Limits: one package manager family, relative queries only, and a scoped blast radius

The limits are modest but they define the tool's applicability.

The first is that it only helps with relative queries. If your Browserslist configuration names explicit versions, like chrome 120 or safari 17, there is nothing for the tool to resolve and running it changes nothing that matters. The whole value proposition is in queries whose answer depends on data, which the README names as last 2 versions and greater than one percent.

The second is the package manager coverage. The README documents npm, pnpm, bun and yarn 2 and above. That covers the current runners, and the yarn 2 and above qualifier is the notable limit, since yarn 1 has no dlx command and would need npx instead.

The third is the blast radius. caniuse-lite is a shared dependency. Autoprefixer, Babel and your own build tooling all read it, and the version in the lock file determines what every one of them decides to polyfill. Updating it changes the behaviour of several tools at once, which is the reason to review the diff and the reason to keep the update in a pull request rather than committing it silently.

The fourth is that the tool resolves queries but does not tell you what they resolved to. The output of the command is the lock file change, not a report of your current target list. If you want to know which browsers you are targeting, that is a separate question, answered by Browserslist itself rather than by this tool.

The fifth is the peer dependency floor. Browserslist 4.21.0 or newer is required, so a project on an older Browserslist needs that updated first. Since Browserslist and caniuse-lite are released together and are usually bumped together, that is rarely a separate step, but it is a real ordering constraint if your lock file is old.

Finally, the tool is scoped to one data source. It refreshes caniuse-lite. It does not touch your Browserslist config, and it does not update any other browser database your pipeline might consult.

update-browserslist-db against a caniuse-lite bump and against pinning browsers explicitly

Two comparisons make the choice clearer.

The first is against bumping caniuse-lite yourself. You can add a caniuse-lite dependency at a newer version, or run your package manager's update command for it, and the lock file entry moves. The difference in approach is that the tool computes which version to move to based on your Browserslist configuration, rather than taking the newest published one. That matters because the newest caniuse-lite is not necessarily the one your queries resolve to, and because a tool that knows the resolution can move to a version that actually changes something rather than churn the lock file.

The second comparison is against the other strategy entirely, which is pinning your browsers explicitly. If your Browserslist config names specific versions rather than relative queries, you have removed the dependency on data freshness, and the decision about which browsers you support becomes an explicit one you revisit deliberately rather than one that drifts with the calendar.

That is a legitimate and increasingly common choice, and it is worth being honest that for many projects it is the better one. Pinning removes a category of surprise from your build: the same commit produces the same output on every machine, forever, rather than producing different output as the data changes underneath it.

What pinning costs is the maintenance of knowing which browser versions are still worth supporting. Relative queries like last 2 versions are a way of outsourcing that decision to the caniuse usage statistics, and they are how a project gets the modern targets without a human tracking release dates. A team that has someone doing that tracking anyway may prefer to pin, and a team that does not should use a relative query plus this tool.

The middle position is also common, and it is what update-browserslist-db is designed for. Some queries are relative because you want the current mainstream browsers, and the refresh keeps them honest. Others are pinned because a specific browser version matters for a workaround. The tool and the pinning coexist, and the tool only touches the relative ones.

Editorial conclusion

Adopt update-browserslist-db in any project whose Browserslist queries are relative, such as last 2 versions or greater than one percent, and schedule it alongside your dependency updates so the browser data does not silently age. Do not run it in a project that pins explicit browser versions, because there is nothing for it to resolve. Verify first that your lock file is under version control and that the resulting diff is reviewable, since the update touches a shared dependency that several tools in the same project read.

Frequently asked questions

What does update-browserslist-db do?

It updates the caniuse-lite version in your npm, yarn or pnpm lock file so that Browserslist queries like last 2 versions or greater than one percent resolve against current browser statistics. The update brings data about new browsers to polyfill tools like Autoprefixer or Babel and reduces already unnecessary polyfills.

How do I run update-browserslist-db?

With npm it is npx update-browserslist-db@latest, with pnpm it is pnpm dlx update-browserslist-db latest, with bun it is bunx update-browserslist-db@latest, and with yarn 2 or above it is yarn dlx update-browserslist-db@latest. The package has a peer dependency on browserslist 4.21.0 or newer.

Why do I need to run update-browserslist-db regularly?

The README gives three reasons: to use the latest browser versions and statistics in queries like last 2 versions or greater than one percent, since a project that did not update its dependencies for two years will resolve last 1 version to old browsers; because actual browser data means fewer polyfills, reducing JS and CSS size; and for caniuse-lite deduplication, to synchronise versions in different tools.

Official sources

  1. browserslist/update-db on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/browserslist-update-db.svg)](https://hysenlabs.com/projects/browserslist-update-db)

Was this useful?