Bun check vs tsc: we test Bun's new type checker on zod, Playwright, and Hono

bun check, the TypeScript type checker that came with Bun 1.4.3, was between 2.7 and 4.5 times faster than tsc 7.0.2 in our tests with zod and Playwright, and reported exactly the same errors. In a small project, however, tsc won.

:white_check_mark: yoDEV Tested · October 14, 2026
We compared Bun 1.4.3’s bun check with tsc 7.0.2 on zod, Playwright, and Hono in a Linux x86_64 container with 2 vCPU and 7 GB of RAM (median of five runs). The results we report as ours come from that test.

Bun 1.4.3 was released on October 10, 2026 and includes bun check without needing to install the typescript package. We put it to the test against tsc on three real open source projects on a modest machine to see what remains of the official numbers outside of Bun’s benchmark.

What is bun check and what does it have to do with TypeScript 7?

bun check is a port of typescript-go, the Go rewrite of TypeScript that Microsoft released as TypeScript 7, compiled into the Bun binary. It reads your tsconfig.json, reports the same errors as TypeScript 7’s tsc, and uses all CPU cores. TypeScript’s lib.*.d.ts declarations (Array, Promise, the DOM) are included, so your project doesn’t need typescript in node_modules for checking to work.

If Bun is new to you: it’s a JavaScript and TypeScript runtime that also brings a package manager, bundler, and test runner in a single executable. bun check is the newest piece of that kit.

It only verifies types. It doesn’t generate JavaScript, .d.ts files or source maps, and doesn’t include a language server. It exits with code 1 if it finds an error and 0 if it doesn’t.

To confirm which TypeScript version your Bun matches:

bun -p process.versions.typescript

On Bun 1.4.3 it returns 7.0.2. If you want the context of that version, we covered it in TypeScript 7.0 is now GA.

Is bun check faster than tsc?

According to Bun’s numbers, it’s between 3 and 6.4 times faster than tsc 7.0.2 and uses between 2.2 and 4.9 times less memory. These are Bun’s own benchmarks, measured on a 16-core Mac with Apple silicon across eight projects, from VS Code’s src (9,795 files) to lit’s packages/react (6 files), and no one has reproduced them independently.

So we reproduced part of it on a deliberately modest machine: a Linux x86_64 container with 2 vCPU and 7 GB of RAM. We used bun@1.4.3 and typescript@7.0.2 from npm, cloned three repos from Bun’s own test list, discarded one warm-up run, and took the median of five runs (ten on Hono).

Project tsc 7.0.2 bun check Result
zod, 604 errors, no dependencies installed 5.93 s · 1,124 MB 1.31 s · 191 MB 4.5x faster, 5.9x less memory
Playwright, 5,692 errors, no dependencies installed 3.11 s · 572 MB 1.13 s · 198 MB 2.7x faster, 2.9x less memory
Hono, tsconfig.build.json, 188 files, dependencies installed, no errors 0.32 s · 98 MB 0.47 s · 152 MB tsc 1.4x faster

Three things stand out.

The advantage holds up with two cores. Bun’s numbers come from a 16-core machine, so you’d expect the difference to disappear on a small CI runner. It didn’t. We also forced both tools to a single thread on zod (bun check --threads 1 vs tsc --checkers 1): 2.33 s vs 5.50 s, still 2.4 times faster. The gain doesn’t come just from parallelism.

Small projects don’t benefit. With Hono’s build configuration of 188 files, bun check was slower and used more memory. Running it with --timing explains why: it spent about 100 ms loading 364 files before checking 188 in 328 ms. On a project that tsc checks in a third of a second, that fixed cost decides the result. Bun’s published table has no case where it loses, but none of its projects are both small, with dependencies installed, and on a machine with few cores.

On large repos, memory is the biggest win. On zod, peak memory dropped from 1.1 GB to under 200 MB. On a shared CI runner that matters as much as seconds.

Does bun check report the same errors as tsc?

In our tests, yes. Bun’s post proposes a three-line test, and we ran it on each project:

bunx -p typescript@7.0.2 tsc --noEmit --pretty false > tsc.txt
bun check --no-pretty > bun.txt
diff tsc.txt bun.txt

On zod and Playwright, all 6,296 errors matched in file, line, column, code, and message. The only difference was cosmetic: when @types/node is missing, tsc suggests npm i --save-dev @types/node and bun check suggests bun add -d @types/node. Hono’s misconfigured root (7 errors) and its clean build configuration also matched.

Bun claims it passes 51,210 tests from TypeScript 7.0.2’s conformance test suite and compared its output to tsc on 72 open source repositories deliberately misconfigured, with just one discrepancy across 1,103 configurations in vuejs/core. Those are Bun’s own tests; ours cover much less ground, but found nothing to contradict them. Bun considers any difference with tsc 7 a bug and asks you to report it as an issue on GitHub.

How do you replace tsc --noEmit with bun check?

In most projects only the command changes. Bun’s documentation maps them like this:

Instead of Run
tsc --noEmit bun check
tsc --noEmit -p packages/server bun check -p packages/server
tsc -b bun check -b
tsc --noEmit && bun test bun test --check
tsc --noEmit && bun build ./app.ts bun build --check ./app.ts

If you’re not already using Bun’s types, add them first:

bun add -d @types/bun

and declare them in tsconfig.json:

{
  "compilerOptions": {
    "types": ["bun"]
  }
}

Since TypeScript 6, packages in node_modules/@types only count if types includes them. We saw this in our own test: in an empty folder without node_modules, bun check detected the type error, also marked console as unknown, and showed the suggestion bun add -d @types/bun.

In GitHub Actions

This is Bun’s documentation workflow:

name: Type check
on: [push, pull_request]

jobs:
  typecheck:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: oven-sh/setup-bun@v2
      - run: bun install --frozen-lockfile
      - run: bun check

In GitHub Actions, bun check also prints a workflow command for each error, so errors appear as annotations on the pull request diff without needing a problem matcher. When the output isn’t a terminal, it uses the single-line format of tsc --pretty false, so scripts written for tsc keep working. On shared runners, --threads 4 limits the number of threads.

Two CI details worth knowing: bun check doesn’t write .tsbuildinfo, so there’s no cache to save and each run checks the entire project; and a run that finds nothing to check exits with code 1, so a job pointed at the wrong directory fails instead of passing.

Before each commit

A simple Git hook:

#!/bin/sh
bun check

saved as .git/hooks/pre-commit and made executable with chmod +x .git/hooks/pre-commit. With lint-staged, "*.{ts,tsx}": "bun check" checks only staged files and what they import, yet still loads your tsconfig.json, something tsc doesn’t do when you pass filenames. Bun’s documentation recommends keeping the full check in CI anyway, because a change in one file can break another that imports it.

Bun vs Node: do you need to use Bun as a runtime to use bun check?

No. bun check just reads your tsconfig.json and looks for packages in node_modules, just like tsc; it doesn’t run your code. zod and Playwright, two of the projects we tested, don’t use Bun as a runtime, and bun check reviewed them with their tsconfig.json as-is, with the same results as tsc. You can keep running your application with Node and use Bun only as a type checker in CI.

The exception is Yarn Plug’n’Play, which bun check doesn’t support: the documentation says to configure nodeLinker: node-modules in .yarnrc.yml.

Does bun check replace TypeScript in VS Code?

No. Your editor runs its own copy of TypeScript, and bun check doesn’t have a language server. For editor and CI to match, Bun’s documentation suggests installing exactly the version bun check matches:

bun add -d typescript@$(bun -p process.versions.typescript)

and then in VS Code, run TypeScript: Select TypeScript Version and choose Use Workspace Version. Repeat when you update Bun, because a new version might match a newer TypeScript. And keep tsc if you publish .d.ts files: bun check never generates them.

What changes in your tsconfig with TypeScript 7?

bun check behaves like TypeScript 7 no matter what version you have installed, so if you’re coming from TypeScript 5 you’ll notice the default changes: strict is on, types is empty, and side-effect imports (like import "./index.css") are also checked. Also, options like baseUrl, "moduleResolution": "node", and "target": "es5" no longer exist. If your tsconfig.json uses a removed option, bun check reports it and stops before checking any files, just like tsc 7.

Bun’s documentation shows what to use instead: "moduleResolution": "bundler" (or "nodenext" for code that Node runs without a bundler), remove baseUrl and start each paths entry with ./, and "target": "es2015" or later.

What can go wrong when switching to bun check?

Your project already has a check script. This is what surprised us. Hono’s package.json defines "check": "vp check", and bun check ran that script instead of checking types. Bun documents this: your script takes priority. Use bun --check to reach the type checker, or name your own script something else.

bun --check doesn’t accept -p as a project. At Bun’s top level, -p means “print”. When we ran bun --check -p tsconfig.build.json to work around Hono’s script, Bun evaluated the filename as code and reported Cannot find name 'tsconfig'. If you need a specific tsconfig, rename your conflicting script and use bun check -p.

Output changes inside AI agents. When AGENT=1, CLAUDECODE=1, or REPL_ID=1 is set, bun check prints each error as a labeled block meant for a model to read. Our container had CLAUDECODE=1, and that’s what we saw until we removed it. Useful inside an agent, surprising in a CI log.

Is it worth switching from tsc to bun check?

If your CI checks types on a project with a few thousand files, yes: bun check is the cheapest speed improvement available today. Change one command, the errors stay identical, and on our two-core machine it cut the step by between 2.7 and 4.5 times and its memory by two-thirds or more. If your project checks in under half a second, it’s not worth it: there tsc 7 was faster. Either way, run Bun’s three-line diff test on your own repo before switching. It takes a minute and turns Bun’s numbers into yours.

At publication time, the speed figures and conformance claim correspond to TypeScript 7.0.2 and will change with the next TypeScript version.


What about you? How long does the type check step take in your CI pipeline today?

How do you check TypeScript types in CI?
  • tsc from TypeScript 5 or 6
  • tsc from TypeScript 7
  • bun check
  • I prefer another option (tell us which)
0 votantes

Comment below or, if this article reached you by email, reply directly to the email: your reply gets published here.

Related: TypeScript 7.0 is now GA