Skip to content

Set target es2024 in TS and Vite, drop browserslist - #3356

Merged
david-crespo merged 2 commits into
mainfrom
es2024
Aug 27, 2026
Merged

Set target es2024 in TS and Vite, drop browserslist#3356
david-crespo merged 2 commits into
mainfrom
es2024

Conversation

@david-crespo

@david-crespo david-crespo commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

Spun off from #3354, where I wanted Promise.withResolvers in a test but tsc wouldn't let me. Then I found out our browserslist list setting is not being used by anything — autoprefixer went away with Tailwind v4.

Changes

  • target in tsconfig: es2023 → es2024, so tsc accepts ES2024 builtins like Promise.withResolvers
  • Set build.target: 'es2024' in the Vite config to match. Vite's default target is 'baseline-widely-available', a browser list regenerated for each Vite major (currently Chrome 111 / Firefox 114 / Safari 16.4)
  • Add a safety test asserting the two targets stay equal
  • Remove the browserslist key and the autoprefixer dep

Argument

target in tsconfig can control two things: what syntax tsc emits and the default lib declarations for typechecking. We use noEmit because we compile with Vite, so we only care about lib: it determines which builtin APIs the typechecker allows (Promise.withResolvers, Object.groupBy, etc.).

Vite has its own target concept, and it only affects syntax: it rewrites newer syntax for older browsers, but if you call a too-new API, it doesn't polyfill or warn about it. 🤖 confirmed this by building Promise.withResolvers() with target safari16.4: clean build, the call ships as-is, TypeError at runtime. That means tsc's lib is the only thing keeping unsupported APIs out of the code, so the tsconfig target has to line up with the browsers we actually support. This PR sets build.target: 'es2024', which Vite maps to the oldest browsers with full ES2024 support (Chrome 119, Safari 17.4, Firefox 145, per https://caniuse.com/sr-es15), and adds a safety test asserting the two targets are the same.

The potential downside is that we are moving our target to browsers that might be too new. The worst one is Firefox, where full ES2024 support means 145 (Nov 2025). But that version requirement comes from a single feature that we're never going to call: per MDN, Atomics.waitAsync appeared in Firefox 145, while every other ES2024 feature was in by Firefox 128 (July 2024), and the ones we'd actually use (groupBy, withResolvers, isWellFormed) by 121 (Dec 2023).

Alternatives

  • Do nothing (but still remove useless browserslist), i.e., leave es2023 for TS and baseline-widely-available for Vite. Fine, but es2024 has fun APIs we could use.
  • es2024 for TS but leave Vite on the default. Also most likely fine in practice, but feels bad.

- tsconfig target es2024: with noEmit, this only changes the default lib,
  allowing ES2024 APIs (Promise.withResolvers, Object.groupBy, etc.)
- vite build.target es2024: Vite maps this to the oldest browsers with
  full ES2024 support. Pinned because the default
  (baseline-widely-available) is lower (safari16.4) and drifts across
  Vite versions. tsc only checks against lib types and nothing polyfills
  APIs, so this must stay in sync with the tsconfig target.
- autoprefixer was an unused leftover from Tailwind v3 (no postcss config,
  nothing imports it), and the browserslist key was consumed only by it.
@vercel

vercel Bot commented Aug 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
console Ready Ready Preview Aug 27, 2026 3:59pm

Request Review

@david-crespo
david-crespo merged commit 9e4d320 into main Aug 27, 2026
7 checks passed
@david-crespo
david-crespo deleted the es2024 branch August 27, 2026 18:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant