2.8 KiB
Imported from docs/adr/0004-typescript-version.md in the go-bananas repository.
ADR 0004: TypeScript 6.0.3 rather than 7.x
- Status: accepted
- Date: 2026-10-04
- Revisit when: typescript-eslint ships TypeScript 7 support
Context
The brief was to take the latest version of everything. For TypeScript, the latest
release is 7.0.2, which is the native Go port of the compiler (tsgo).
Decision
Pin TypeScript to 6.0.3 in both web/ and sdk/.
Rationale
TypeScript 7.0.2 ships tsc.js and a version module. It does not ship a
JavaScript compiler API:
$ npm install typescript@7.0.2
$ node -e "const ts=require('typescript'); console.log(typeof ts.createProgram)"
undefined
That API is what every type-aware linting tool consumes. typescript-eslint@8.71.0,
the current release, declares:
peerDependencies: { typescript: ">=4.8.4 <6.1.0" }
So TypeScript 7 fails to install at all alongside the standard linting stack, and would fail at run time if forced past the peer check.
The choice is therefore between:
- TypeScript 7.x — a much faster compiler, and no type-aware ESLint rules at all,
because the tooling that provides them cannot run.
npm installfails outright without--legacy-peer-deps, which is a smell in a project rather than a solution. - TypeScript 6.0.3 — the newest release that ships both the CLI and the JavaScript API, satisfying every tool in the toolchain.
Why not upgrade anyway and lose the linting
The project's standards require type-aware linting: @typescript-eslint rules that
need the compiler's type information, which is what catches the mistakes that matter
in a codebase using unknown at API boundaries. Dropping it to gain compiler speed
is a bad trade: the speed is a developer-experience improvement, and the linting is
a correctness control.
What this costs
TypeScript 6.0.3 is slower than 7.0.2. On this codebase the typecheck completes in well under a second, so the difference is not observable, and the compilation cost that matters is Vite's, which uses its own transform.
When to revisit
When typescript-eslint declares support for TypeScript 7, which requires the
JavaScript API or a native alternative to it. That is a one-line version bump plus
a make check run. This ADR exists so that the pin is a decision with a reason
rather than an accident that outlives its justification.
A related note: baseUrl is deprecated
TypeScript 6 deprecates compilerOptions.baseUrl. The project resolves paths
relative to the tsconfig instead, which is the documented replacement and removes a
compiler option that only ever existed to make paths work.