Build1 distinct publisher2 min readPublished
A three-project diff published on dev.to shows Next.js 16's SWC sorting browserslist into two buckets, so chrome 116 and chrome 139 compile identically, while the ie 11 build downlevels syntax and still calls Object.hasOwn.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
Reading that field is closer to flipping a switch than turning a dial. The writeup's explanation is that SWC sorts every browserslist target into one of two buckets: legacy, meaning no support for native ES modules, where IE11 lands, and modern, which starts around Chrome 61, Safari 11 and Firefox 60, so anything from 2017 onward [7]. Chrome 139 sits 78 major versions above that floor [12]. The two Chrome targets tested are 23 versions apart [13]. Both live deep inside the same bucket, so the compiler had nothing to distinguish. It read two different fields and, judging by the output, took the same single fact from each [4].
Rewriting syntax and supplying missing builtins are two separate jobs in a build. Here the first followed the target and the second did not [5][6], which makes the browserslist array an instruction to the syntax pass and to nothing else in the JS pipeline. That is why the line in package.json reads as reassurance. It records a belief about which browsers you support, and the emitted JS is not where that belief gets tested.
For the two-bucket result to transfer to your repo, several things have to hold. The compared code is a single exported function exercising features dated ES2021 through ES2026 [10], built by Next.js 16, and in the modern builds the diffed snippet sits inside an onClick handler [15]. If your oldest supported browser is anywhere past native module support, that is the tested case, and the writeup's claim is that you should expect no difference in emitted JS syntax at all [8]. If it is below that line, you are in the legacy bucket, and the only sample here is IE11.
The reported results cover the emitted JS chunks. The same three projects also ship eslint-plugin-compat and a postcss.config.js with postcss-preset-env, installed specifically to check whether the tooling that consumes browserslist acts on it [9], and no verdict on those appears in the diff as published [14]. So treat this as a finding about JS syntax, not about CSS prefixing or lint coverage. All three projects are on GitHub [11], which is the part that makes it checkable rather than quotable.
The practical read is narrow and useful. If your floor is inside the modern bucket, tightening that array by Chrome version will not move a byte of your JS syntax, and the only lever that moves it is crossing the module-support line [8]. Cross it and you get syntax downleveling; the runtime builtins the ES5 output still calls are yours to supply [6].
Ranked by verification strength, evidence, and original report placement.
Next.js's SWC compiler does not map browserslist to a continuum of ECMAScript versions the way Babel plus preset-env would; it collapses every target into two buckets, legacy (browsers without native ES module support, where IE11 falls) and modern (roughly Chrome 61, Safari 11 or Firefox 60 onward, 2017 and later).
Three near-identical Next.js 16 projects were built whose only difference was the browserslist field in package.json: ["ie 11"], ["chrome 116"] and ["chrome 139"].
The three targets tested were ie 11, chrome 116 (about 3 years old) and chrome 139 (about 1 year old); next build was run on each project and the emitted chunks were compared byte by byte.
The author expected three different outputs scaled to how old each target is, and got two identical outputs and one different one.
The chrome 116 and chrome 139 builds were byte-for-byte the same syntax: arrow functions, let, ??=, ?. and for...of were untouched in both, so setting chrome 116 versus chrome 139 had zero effect on the emitted JS syntax.
The ie 11 build was genuinely transpiled to ES5: no arrow functions, no let/const, for...of rewritten as a manual Symbol.iterator loop, and optional chaining and ??= rewritten as ternaries and ||.
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 31, 2026
Follow any of these and your For You feed starts watching them — no settings page required.
build
Next.js 'use cache' claims 700ms TTFB down to 60ms. Every deploy hands the bill back1 distinct publisher
build
Next.js 16 scatters its breaking changes across every dynamic route in the app1 distinct publisher
build
A build-tool swap that took 70 days and 166 files, and the build was the easy part1 distinct publisher
build
In Manifest V3 every message handler is a cold start, and the fix for lost state hides new failures1 distinct publisher
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Artifacts on the page, no second pair of hands
You can audit almost all of this without leaving the post: the three package.json fields are quoted, the minified chunks are printed before and after, and the harness is public as ale-grosselle/nextjs-browserlist-test. What is missing is everything outside the author's own terminal — no pinned Next.js or SWC version, no reference to SWC's docs for the two-bucket model, and no one else running the same build.
Compiler behaviour observed, exposure unknown
Nothing in this reporting speaks to who is affected: no figure for how many Next.js projects set browserslist at all, no acknowledgement from the framework's maintainers, and no sense of how much shipped code targets anything below the module line. A self-run diff tells you what the compiler does, not how widely it bites.
Bytes are honest, the 'only' is not
For the three targets he ran, the author claims no more than his diffs show — that restraint is unusual and it counts. The stretch is in the generalisation: 'browserslist only matters if your oldest target predates ES modules' is extrapolated from one pre-module browser and two Chrome versions nowhere near the claimed floor, and the same post's CSS section shows chrome 116 and chrome 139 output diverging a few paragraphs later. The finding is solid; the word 'only' is doing work the experiment did not.
Nothing for sale but the finding
An individual posting under his own name on dev.to, with the test repo open and the result mildly unflattering to a framework he is evidently still shipping. No sponsor, product or migration is attached. The one pressure worth naming is reputational: a counterintuitive headline travels further than a hedged one, which is roughly where the overreach in the framing comes from.
Reproducible once, replicated never
Confidence here splits cleanly. That these three builds produced these bytes: high, because the code and the output are both on the table. That the Chrome 61 line is where SWC's buckets actually meet: much lower, since it is described from the outside, on an unstated Next.js 16 patch level, by one person, and the post trails off mid-sentence before finishing its own CSS argument.