5 min read

Two-Week Browser Releases Quietly Broke "last 2 versions" — Move Your Browserslist to Baseline

If your package.json still says "browserslist": ["last 2 versions"], your support window got cut in half in September and nobody opened a PR about it. Chrome, Edge and Firefox now ship a new major version every two weeks, and every version-counting Browserslist query you own silently changed meaning. The fix is a Browserslist Baseline query — a target defined by time and feature interoperability instead of release numbers.

What actually changed in September 2026

Three of the four engines your users run moved to a two-week stable cadence within the same month:

  • Chrome: four weeks → two weeks, starting with Chrome 153 stable on September 8, on desktop, Android and iOS. Extended Stable stays on its eight-week cycle.
  • Edge: two-week cadence starting with Edge 152 on August 27.
  • Firefox: Firefox 154 (August 18) was the last four-week release; Firefox 155 shipped September 1 and the cadence is now two weeks. Mozilla calls it an experiment. ESR keeps its slow lane.
  • Safari: not part of this. It still ships on Apple's cadence — Safari 27 in September, point releases after.

By mid-October Chrome stable was already on 155 and Firefox on 158. That's the version churn your build config is now reacting to.

And before you say "we don't use last 2 versions": if your config is defaults, or you have no config at all, you do. Browserslist's defaults resolves to > 0.5%, last 2 versions, Firefox ESR, not dead.

Why version-count queries were always a proxy

last 2 versions doesn't mean "browsers from the last few months". It means "the two newest releases of each browser". That was a tolerable approximation of time when cadences were stable. Now it's three different windows in one query:

  • Chrome / Edge / Firefox: the oldest version you cover is now ~2 weeks behind current, down from ~4.
  • Safari: two versions still covers a year-plus of releases.
  • Real users: don't care about either. Enterprises sit on Extended Stable's eight-week milestones and Firefox ESR, laptops don't restart, Android WebViews lag.

Usage-based queries have a subtler problem. > 0.5% is evaluated per browser version. Halve the release interval and the same Chrome audience is spread across twice as many version buckets — each bucket's share shrinks, more of them fall under your threshold, and you drop browsers that collectively still matter. Nothing about your users changed; the slicing did.

Run your current query against fresh data before and after updating caniuse-lite and diff the output:

powershell
npx update-browserslist-db@latest npx browserslist "last 2 versions, > 0.5%, not dead"

Baseline queries: target time, not version numbers

Browserslist has Baseline queries built in (since late 2025 — the separate browserslist-config-baseline package is no longer needed):

  • baseline widely available — features interoperable across the core browser set for 30+ months
  • baseline newly available — everything interoperable today
  • baseline 2024 — the feature set of a given Baseline year
  • baseline widely available on 2026-01-01 — the Widely available set as of a fixed date
  • ... with downstream — also include Chromium-based downstream browsers (Samsung Internet and friends)
javascript
// package.json { "browserslist": ["baseline widely available on 2026-01-01 with downstream"] }

Baseline is defined by when features became interoperable across Chrome, Edge, Firefox and Safari (desktop and mobile). Release cadence is invisible to it. Chrome could ship daily and the resolved browser set wouldn't care — it moves only when interoperability does.

Pin a date — don't track a moving target

The contrarian bit: plain baseline widely available is itself a moving target. It advances every day as features cross the 30-month line, so a routine lockfile bump can drop browsers from your output with zero diff in your config. That's the same "silent change" problem you're trying to escape, just slower.

Vite already solved this. Its default build.target is the special value 'baseline-widely-available', but pinned to a date per major release — 2026-01-01 for the current major — which resolves to roughly chrome111, edge111, firefox114, safari16.4. The target moves only when Vite ships a major, i.e. when someone made a decision.

Copy that policy:

javascript
// package.json — bump the date on purpose, in a reviewed PR { "browserslist": { "production": ["baseline widely available on 2026-01-01 with downstream"], "development": ["last 1 chrome version", "last 1 firefox version", "last 1 safari version"] } }

(Note: if you're on Vite, align build.target with the same date so JS lowering and your CSS tooling agree on what "supported" means.)

Make the rest of the toolchain obey it

The query only matters if tools read it. Autoprefixer, Babel's preset-env, Lightning CSS and most CSS tooling consume Browserslist directly. The win most teams miss is linting: Stylelint can flag CSS outside your target via stylelint-browser-compat, so you catch a not-yet-Baseline property in review instead of in a bug report. eslint-plugin-compat does the same for JS/Web APIs and reads the production Browserslist environment by default.

javascript
// stylelint.config.js export default { plugins: ["stylelint-browser-compat"], rules: { "plugin/browser-compat": [ true, { browserslist: ["baseline widely available on 2026-01-01"] } ] } };

Two operational habits that matter more now:

  • Keep browser data fresh. With twice as many releases, a stale caniuse-lite is wrong twice as fast. Run npx update-browserslist-db@latest in CI or let Renovate do it.
  • Print the resolved list in CI. npx browserslist output in the build log turns invisible target changes into visible ones.

The real lesson: write your support policy as a date

Release cadence is a vendor implementation detail. It went from six weeks to four to two, and it'll change again. Any support policy expressed as "N versions" inherits every one of those changes without your consent.

A policy like "We support Baseline Widely available as of 2026-01-01, reviewed every six months" survives cadence changes, maps to features your team can actually reason about, and moves only when you move it. Put that sentence in your README, put the matching query in package.json, and stop letting browser release managers edit your config.