How Baseline helps you ship less JavaScript

Jad Joubran gives a practical method for auditing package.json: which libraries can be dropped today because the browser does the same job natively. The piece explains Baseline's three states — limited availability, newly available, and widely available — and shows how to use them as a measure instead of a feeling. The gap between the claim that something needs a library and the fact that the browser already does it closes faster than most projects track.

Jad Joubran took a typical package.json and walked through it with Baseline in hand. The outcome is between 60 and 90 kilobytes, measured after compression, that can come out of an average mid-sized application without losing functionality. The piece is not a wish list but a check with numbers. Internationalization, the easiest 14 kilobytes The gain is largest here and the risk smallest, because nearly everything in this group is already widely available. timeago.js , 1 kilobyte, replaced by Intl.RelativeTimeFormat pluralize , 2.3 kilobytes, replaced by Intl.PluralRules numeral , 3.9 kilobytes, replaced by Intl.NumberFormat humanize-duration , 6.6 kilobytes, replaced by Intl.DurationFormat , which is only newly available rather than widely helper functions for lists, replaced by Intl.ListFormat HTTP clients, 17 kilobytes axios goes out, and the built-in fetch and AbortController come in, both widely available. Account for the differences, though. fetch does not reject on HTTP errors, and it has no interceptors, retries, or upload progress. If you need any of that, you write a thin wrapper — still far lighter than the whole library. Interface elements, 24 kilobytes This group pays off best, because the dialog element and the Popover API together delete three to four packages at once. Modal libraries, replaced by the dialog element tippy.js , 14 kilobytes, replaced by the Popover API with CSS anchoring focus-trap , 6.6 kilobytes, unnecessary because focus containment is built into dialog body-scroll-lock , 1.3 kilobytes, replaced by one CSS rule that hides overflow while the modal is open Lodash, 8 kilobytes and up lodash.clonedeep , replaced by structuredClone lodash.groupby , replaced by Object.groupBy set operations, replaced by built-in methods such as union and intersection When not to drop: the Temporal case Temporal reached the final stage and is part of the ES2026 standard, so the temptation is to switch immediately. Its polyfill weighs 44 kilobytes after compression, though — more than the libraries it would replace. Wait for stable support in Safari and entry into Baseline. This is a useful reminder that standardized and production-ready are not the same thing. Three questions before you delete Is the replacement safe by Baseline for your audience — not in general, but for the actual visitors in your analytics? What does the replacement really cost, counting polyfills, support checks, and testing time? Does the built-in feature cover your real use case, or only the one from the documentation example? Tools for checking npm ls --omit =dev --depth =0 lists production dependencies Bundlephobia shows the size of an individual package source-map-explorer or vite-bundle-visualizer show the real share of the shipped bundle webstatus.dev and MDN are where you check Baseline status the web-features package makes programmatic checks possible, which is useful in continuous integration