Skip to content
Putting technology to work.
Insights to guide decisions and action.

Search articles

Can bun check in Bun 1.4.3 replace tsc? We tried them side by side

Table of contents · 6 items

If you run tsc --noEmit in CI, the wait for type checking adds up with every pull request. Switching to bun check, the type checker built into Bun, might make it faster, but what CI owners want to confirm first is "Does it report the same errors?" and "Does the job reliably fail when there are errors?"

Bun is a JavaScript runtime that Anthropic acquired in December 2025. Version 1.4.3, released on October 10, 2026 (UTC), added bun check for type checking and the --check flag, which type-checks before running, building, or testing (according to the release notes on the Bun blog; the repository documentation was also added in the 1.4.3 tag and is not present in the 1.4.2 tag). In this article, we ran Bun 1.4.3 and tsc from TypeScript 7.0.2 against the same project in the editorial team's test environment and lay out the information needed to decide on a replacement.

The overall changes in Bun 1.4 (the rewrite in Rust) and whether to adopt it for business systems are covered in our article on Bun 1.4.

What the bun check command does

The Bun documentation (docs/runtime/check.mdx) describes bun check as follows.

  • It reads tsconfig.json and "reports the same errors as tsc from TypeScript 7" (the same errors as tsc in TypeScript 7). It uses all CPU cores
  • The exit code is 1 if there are errors and 0 if there are none. "It never writes files"
  • The typescript package is not needed. lib.*.d.ts is built into Bun. You can see which version it matches with bun -p process.versions.typescript
  • The replacement mapping includes tsc --noEmit to bun check, tsc --noEmit && bun test to bun test --check, and so on. You still use tsc to generate .d.ts

Running bun -p process.versions.typescript with the 1.4.3 executable returned 7.0.2. The latest version of typescript on npm is also 7.0.2. The defaults that changed in TypeScript 6 and 7 (such as strict being enabled by default and types being empty) apply to bun check as well, so for projects still using TypeScript 5 settings, the first step is to work through the migration to TypeScript 7.

The release notes on the Bun blog say that bun check passes the entire TypeScript 7.0.2 conformance test suite. They also include the results of comparing output with tsc on 72 open-source repositories with deliberately broken configurations: out of 1,103 configurations (286,267 errors in total), only one (vuejs/core) produced mismatched output. On speed, they say it is "3x to 6.4x faster than tsc 7.0.2" on real projects such as VS Code and Next.js on a 16-core Apple silicon Mac. The "more than 3x faster" in news coverage comes from these figures. In this article, we also present the editorial team's measurements, taken under different conditions.

Results of running it side by side with tsc 7.0.2

The test environment was Linux (x86_64, 4 cores) with Node.js v22.22.0. Bun was @oven/bun-linux-x64@1.4.3 from npm (1.4.3+c6da4a4d3), compared against tsc from typescript@7.0.2. We tested on a small three-file project with strict enabled.

Conditionbun check(1.4.3)tsc —noEmit(7.0.2)
No errorsExit code 0Exit code 0
Two type errors (TS2322 and TS7006)Same two lines, exit code 1Same two lines, exit code 1
Removed options (baseUrl and moduleResolution: node)TS5102 and TS5108, exit code 1TS5102 and TS5108, exit code 1
No files match includeTS18003, exit code 1TS18003, exit code 2
File names specified (src/index.ts)Checks using tsconfig.json, exit code 1TS5112 (does not read the config file), exit code 1
outDir specified without rootDirNo errors, exit code 0TS5011, exit code 2

In the piped standard output, the two type error lines showed no difference between tsc and diff. The summary line goes to standard error. The output also matched when we introduced one type error into the 2,000-file synthetic project described below.

The exit codes for TS18003 differ (1 and 2), but both are nonzero, so the CI job fails either way. The differences in content appear in the last two rows of the table. Using tsconfig.json when file names are passed is behavior the documentation describes as "intentional." On the other hand, with a configuration that specifies outDir but does not set rootDir, tsc reported TS5011 (an error asking you to specify the common source directory explicitly with rootDir), while bun check reported nothing. It appears that bun check, which does not write output, does not perform this check on output layout (the editorial team's assessment). In projects that also build with tsc, the tsc build may fail even when bun check passes.

About 2.6x faster on the editorial team's synthetic project

We measured speed on a 2,000-file synthetic project generated by the editorial team (each file imports the two preceding files and includes generic classes and mapped types, with no type errors). After one warm-up run each, we ran bun check and tsc --noEmit alternately 10 times each and measured the time from start to finish.

  • bun check: median 573 ms (min 506, max 739)
  • tsc --noEmit: median 1,502 ms (min 1,319, max 1,834)

Under these conditions, it was about 2.6x faster at the median. With the thread count set to 1, bun check --threads 1 took about 1.5 to 1.6 seconds and tsc --noEmit --singleThreaded about 2.4 to 2.6 seconds (5 runs each). These values come from measuring one project in a 4-core test environment, and results vary with the amount of code, the complexity of the types, and the number of cores on the CI runner. The conditions differ from the 3x to 6.4x on the Bun blog (16-core Mac, real projects), and our results do not verify those figures. The difference may be smaller on CI runners with fewer cores, so measure your own repositories the same way before deciding.

Also, as the documentation states, bun check does not write .tsbuildinfo and checks the whole project every time ("No cache to save or restore"). Make sure your comparison is fair against CI setups that rely on incremental in tsc.

Pitfalls to check before adding it to CI

The results of the --check flag varied by version and usage as follows.

Diagram comparing results of Bun's --check flag by version and usage. In 1.4.3, bun --check src/index.ts shows the type errors, does not run, and exits with code 1. In 1.4.2, bun --check ignores the flag, runs, and exits with code 0. In 1.4.2, bun build --check writes output without checking types and exits with code 0. In 1.4.3, bun test --check does not look at type errors in files the tests do not import

Older Bun versions silently ignore --check

When we ran bun --check src/index.ts with Bun 1.4.2, the file with type errors ran as is, and the exit code was 0. bun test --check also passed the tests without type checking, and bun build --check wrote the output files as is. bun check itself fails in 1.4.2 with "Script not found "check"", so you will notice, but you will not notice with the --check flag. Pin the Bun version to 1.4.3 or later, both in CI and locally, before using it.

bun test --check only covers what the tests import

As the documentation states, bun test --check checks "The test files and everything they import." Even if src/index.ts had type errors, the tests passed with exit code 0 in 1.4.3 as long as the tests did not import that file. When we introduced a type error into src/user.ts, which the tests import, the tests did not run and the exit code was 1. It does not replace type checking of the whole project, so keep bun check as a separate step in CI.

If package.json has a check script, something else runs

If package.json has a script named check (such as a linter), bun check runs that script. The documentation on the main branch and the official site's documentation as of October 20 (bun.com/docs/runtime/check) list --no-script, which forces the type checker, but it is not in the 1.4.3 tag's documentation or executable. When we ran bun check --no-script in 1.4.3, --no-script was passed as an argument to the script, the script succeeded, and the exit code was 0. In 1.4.3, using bun --check (the form without specifying files) as the documentation describes type-checked the whole project.

Environment variables change the output format

If any of AGENT=1, CLAUDECODE=1, or REPL_ID=1 is set, bun check outputs errors in <error file=...> tag format. Our test environment had CLAUDECODE=1, so the first run was not in tsc format. We confirmed that adding --no-pretty fixes the output to the single-line format. Also, when we set GITHUB_ACTIONS=true and ran it locally, in addition to the single-line output, it printed ::error file=... lines, which the documentation says are used for pull request annotations (we have not confirmed how they appear on GitHub).

How to proceed with the replacement (suggestions from the editorial team)

  1. Pin the Bun version: Specify 1.4.3 or later in bun-version of oven-sh/setup-bun@v2. If you leave it at latest, there may be periods when the documentation and the executable's features (such as --no-script) are out of sync
  2. Run both side by side for a while: Add bun check --no-pretty while keeping the existing tsc --noEmit, and compare for several weeks whether the error lines and exit codes match. The documentation asks you to report it as a Bun bug if you get errors that differ from TypeScript 7's tsc
  3. Split out tsc's roles and keep it: Keep tsc for generating .d.ts and for builds that use outDir. Even if bun check passes, mistakes in build settings (TS5011 in this case) are only caught on the tsc side
# .github/workflows/typecheck.yml(並行運用の例。GitHub Actions上では未実行)
jobs:
  typecheck:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: oven-sh/setup-bun@v2
        with:
          bun-version: 1.4.3
      - run: bun install --frozen-lockfile
      - run: bun check --no-pretty
      - run: bun x tsc --noEmit  # devDependencies の typescript。一致を確かめる期間だけ残す

Conclusion

Start by running bun -p process.versions.typescript locally to check which TypeScript version Bun matches, then compare the output and exit codes of bun check --no-pretty and tsc --noEmit on your own repositories using diff. Once you have confirmed they match, pin the version and add it to CI alongside the existing check. Avoiding a setup that leaves type checking solely to the --check flag or bun test --check helps prevent things from slipping through.

On October 20, 2026, we checked the 1.4.3 release notes on the Bun blog and the GitHub release, the bun check documentation on the official site, docs/runtime/check.mdx (the bun-v1.4.3 tag and main) and docs/docs.json in oven-sh/bun, the publication dates and versions of bun, @oven/bun-linux-x64, typescript, and @types/bun on npm, action.yml in oven-sh/setup-bun, and Anthropic's announcement of its acquisition of Bun (document research). In the editorial team's test environment (Linux x86_64, 4 cores, Node.js v22.22.0), we ran Bun 1.4.3 and 1.4.2 and tsc from TypeScript 7.0.2 against a three-file test project and a 2,000-file synthetic project (hands-on testing). We have not confirmed behavior on actual GitHub Actions or GitLab CI runners, with bun check -b and project references, on Windows or macOS, or speed on large real-world codebases.

GleamHub's development, AI, and automation consultations cover reviewing CI for TypeScript projects and automating development and testing of business systems. The approach depends on how your project is structured, so please reach out through our contact form.

References

Share this articleXFacebook
Kakeru Suzuki

Fascinated by the possibilities of technology, has had a deep interest in programming and digital art since student days

Turn this article's theme into your company's next step

Concrete steps forward for your organization.

We organize your desired architecture, legacy systems, and operational requirements to formulate your next steps toward execution.

  • Desired architecture
  • Integration with existing environments
  • Operational requirements
Consult on development & operations initiatives

You can consult with us from the initial conceptual stage. Details from this article will be carried over to the inquiry form.

Receive the latest articles by email