How long does a full TypeScript type check take?

5 type checkers on 3 real projects, each a fresh process with no incremental cache, on one Apple M5 in one session. Every figure links to the raw output behind it.

Full checks only: not watch mode, editors or --build. One machine. Independent: not affiliated with or funded by Microsoft, Vercel, Oven (bun) or the authors of any checker here.

Default threading differs: tsgo and tsc-rs default to 4 checkers; tsc-ts, tsrs and bun use one per core, up to 10 on this 10-core machine (sources). The other settings give every checker the same thread count, set with its documented flag. ¹ marks a checker that reported errors where tsgo reported none.

VS Code

The VS Code editor's main sources. 10,645 project files. tsgo creates 3.3 M types and 4.2 M instantiations.

wall timevs tsgoCPU timepeak memory
tsgo
7.11 s1.0×36.9 s8.2 GiB
36.9 s CPU, 8.2 GiB peak, range 7.01–8.34 s
tsc-ts
3.27 s2.2×30.3 s6.9 GiB
30.3 s CPU, 6.9 GiB peak, range 3.25–3.29 s
tsc-rs¹
2.94 s2.4×12.2 s6.1 GiB
12.2 s CPU, 6.1 GiB peak, range 2.90–2.98 s
bun
2.13 s3.3×19.2 s2.2 GiB
19.2 s CPU, 2.2 GiB peak, range 2.12–2.17 s
tsrs¹
1.22 s5.8×11.2 s2.3 GiB
11.2 s CPU, 2.3 GiB peak, range 1.20–1.23 s

tsc-rs and tsrs report 10 errors that tsgo 7.0.2 does not; their upstream TypeScript builds print exactly the same (details).

Checked with -p ./src/tsconfig.json --noEmit --skipLibCheck at 4a82da11e45f, from package.json typecheck-client. Raw: timings, diagnostics, file lists, work counts.

Outline

A knowledge-base web app. 2,315 project files. tsgo creates 0.6 M types and 5.8 M instantiations.

wall timevs tsgoCPU timepeak memory
tsgo
3.88 s1.0×16.9 s3.1 GiB
16.9 s CPU, 3.1 GiB peak, range 3.78–3.90 s
tsc-rs¹
1.57 s2.5×4.8 s1.8 GiB
4.8 s CPU, 1.8 GiB peak, range 1.55–1.58 s
tsc-ts
1.04 s3.7×9.4 s2.3 GiB
9.4 s CPU, 2.3 GiB peak, range 1.02–1.06 s
bun
1.04 s3.7×8.1 s1.0 GiB
8.1 s CPU, 1.0 GiB peak, range 1.04–1.06 s
tsrs¹
0.69 s5.6×5.7 s1.0 GiB
5.7 s CPU, 1.0 GiB peak, range 0.69–0.71 s

tsc-rs and tsrs report 1 error that tsgo 7.0.2 does not; their upstream TypeScript builds print exactly the same (details).

Checked with -p . --incremental false at ef7753dc57a6, from .github/workflows/ci.yml, job types: yarn tsc --incremental false. Raw: timings, diagnostics, file lists, work counts.

type-fest

A type-level library; its check cost is almost all its own test-d suite. 502 project files. tsgo creates 5.9 M types and 17.8 M instantiations.

wall timevs tsgoCPU timepeak memory
tsgo
6.99 s1.0×26.2 s7.5 GiB
26.2 s CPU, 7.5 GiB peak, range 6.75–7.16 s
tsc-rs
2.09 s3.3×4.2 s4.0 GiB
4.2 s CPU, 4.0 GiB peak, range 2.06–2.12 s
tsrs
1.63 s4.3×6.8 s1.8 GiB
6.8 s CPU, 1.8 GiB peak, range 1.61–1.67 s
tsc-ts
1.54 s4.5×10.3 s6.0 GiB
10.3 s CPU, 6.0 GiB peak, range 1.50–1.57 s
bun
1.22 s5.7×5.2 s1.4 GiB
5.2 s CPU, 1.4 GiB peak, range 1.21–1.28 s

tsc-rs and tsrs print one type differently in a message with the planted errors; their upstream TypeScript builds print exactly the same (details).

Checked with -p . --noEmit at b550b410e13f, from package.json test:tsc (tsc on the repo tsconfig, which sets noEmit). Raw: timings, diagnostics, file lists, work counts.

All 3 projects against tsgo

tsgo's median wall time divided by each checker's, so 2.0× means the checker took half as long.

VS CodeOutlinetype-fest
tsc-ts2.2×3.7×4.5×
tsc-rs2.4×2.5×3.3×
tsrs5.8×5.6×4.3×
bun3.3×3.7×5.7×

Do they report the same errors?

Each checker ran every project clean and with a few planted type errors, and its output was compared with tsgo's.

Per project and state
VS CodeOutlinetype-fest
clean0 errorsplanted3 errorsclean0 errorsplanted3 errorsclean0 errorsplanted6 errors
tsc-ts✓✓✓✓✓✓
tsc-rs+10+10+1+1✓+1 −1
its upstream buildupstream✓✓✓✓✓✓
tsrs+10+10+1+1✓+1 −1
its upstream buildupstream✓✓✓✓✓✓
bun≈≈≈≈≈≈

✓ byte-identical to tsgo≈ same errors, places and top-level messages after normalising each output to one path:line:col code message line per error+n −m lines only in the checker, only in tsgoThe counts under each column are tsgo's errors. Ports get a second row against their upstream build.

Every difference, verbatim, and the full tables, in the run's report.

Checkers

Diagnostics only, never timed: upstream tsgo typescript@7.1.0-dev.20260930.4, the build tsrs ports; typescript@7.1.0-dev.20261008.1, the build tsc-rs ports.

Thread defaults and flags as each checker documents them (sources). Each binary's version output and sha256 are in run.json.

How it was measured

Machine
Apple M5, 10 cores, 24 GiBmacOS 26.5.1 (25F80)
Each check
A fresh process, no incremental cacheNo build info or cache carries over between runs. The OS file cache is warm for every checker alike: each set of runs starts with a warm-up round.
Sample
Median of 7 timed roundsAfter one warm-up round. Checker order rotated each round, so every checker ran in every position.
Settings
Shipped defaults, no tuning flagsEach checker as it ships, with only the project's own typecheck arguments.
Projects
Pinned commits, their own lockfilesBenchmarked only if tsgo reports 0 errors; rejected in this run: excalidraw.
Conditions
All 570 runs on AC powerKept awake by caffeinate, no sleep, wake or thermal events, no preflight warnings.
Harness
bde799c06fc9Recorded after the run: the last harness commit before it started (details in run.json).

Caveats, and what the numbers do not show, in docs/METHOD.md. Every file behind this page is in results/2026-10-19-apple-m5-darwin/, with its full report.

Run it yourself

On macOS, Linux or Windows, with Node 22.18 or later and git. Use a quiet machine on AC power. AGENTS.md lists every prerequisite and what to check at each step.

  1. Get the codeClone the repository.
    git clone https://github.com/danfry1/ts-checker-bench && cd ts-checker-bench
  2. Check the harnessIts typecheck and tests, and that the committed reports regenerate exactly.
    (cd bench && npm ci && npm run check)
  3. Install everythingEvery checker from its lockfile, and every project at its pinned commit with its own install command. About 10 GB, most of it VS Code's own dependencies.
    node bench setup
  4. Check the machineRefuses to start on battery or with a checkout that is not ready; warns about busy processes.
    node bench preflight
  5. Try it end to endtype-fest only, one round, about 6 minutes. Not published.
    node bench run --smoke
  6. Run the benchmarkAbout 40 minutes on a 10-core Mac, longer on slower ones. Writes results/<date>-<cpu>-<os>/ with its report.
    node bench run
  7. Send itCheck the run as CI will, then open a pull request with its results/ folder. Runs from other machines are welcome.
    node bench verify <date>-<cpu>-<os>