Running TypeScript and checking TypeScript are different jobs. A development server can start, a bundle can build, and tests can pass while a separate type-check job still rejects the code. That separation is useful when fast iteration matters, but it also creates another command to remember and another CI step to maintain.
Bun 1.4.3, released on October 10, brings that check into the runtime’s toolchain. Its new bun check command is a native TypeScript checker, with optional gates before running code, executing tests, or writing a bundle. The interesting question is not just whether it beats tsc on a benchmark. It is whether it can shorten your feedback loop without changing which mistakes your pipeline catches.
This is a different development from Bun’s earlier Rust rewrite. That story concerned the runtime’s implementation; this one changes the commands developers use to decide whether code is ready to run.
What Bun Check Actually Replaces#
According to the Bun 1.4.3 release notes, the checker is a port of Microsoft’s typescript-go and targets TypeScript 7.0.2 behavior. It reads tsconfig.json and does not require a separately installed typescript package to perform the check.
The simplest candidate for replacement is a no-output type-check step:
# Existing type-check step, using your installed TypeScript compiler:
tsc --noEmit
# Candidate replacement with Bun 1.4.3:
bun checkThat does not mean you can delete TypeScript from every project. Bun explicitly says the checker emits neither JavaScript nor .d.ts files and provides no language server. Your editor continues to use its TypeScript service, and a library that publishes declarations still needs a declaration-generation step.
The distinction belongs in the migration ticket: replace checking, not every job currently performed by the compiler. Similarly, the tooling consolidation discussed in my Biome analysis does not make formatting, lint policy, and type checking interchangeable. Keep each check that enforces a requirement your project actually has.
Put a Type Gate Before Execution#
The release’s run, test, and build integrations are arguably more useful than the standalone command:
bun run --check src/index.ts
bun test --check
bun build --check ./src/index.ts --outdir ./distA type error prevents the requested operation. For the build command, Bun says no output is written when checking fails. For tests, the checked scope is the test files and what they import—not automatically every application file in the repository.
That last boundary matters. Consider an administrative worker that has no tests importing it. A green bun test --check run does not establish that the worker is type-correct. Bun’s documentation on check coverage also identifies computed imports, workers, and other separately loaded code as reasons an entry-point check may miss files. Keep a whole-project check with an appropriate tsconfig.json in CI.
You can demonstrate the gate with a tiny file:
// example.ts
const port: number = "3000";
console.log("This should not run with --check", port);Then run:
bun run --check example.tsThe expected result is a type error and a nonzero exit, without the message being printed by the program. This is a smoke test of the gate, not proof that the checker agrees with TypeScript across your codebase.
Nor does a successful check validate external input. An HTTP request can still contain an unexpected value; your runtime validation and application tests remain necessary. Type checking verifies the program’s static assumptions, not whether the outside world honors them.
Read the Speed Claims Carefully#
Bun reports 3× to 6.4× faster checking than the native TypeScript 7.0.2 compiler across its listed projects on a 16-core Apple silicon Mac. These are Bun’s measurements, not independently reproduced results for your CI runners.
A few examples from the published benchmark table:
| Project | Files | Bun Check | TypeScript 7.0.2 | Reported Speedup |
|---|---|---|---|---|
VS Code src | 9,795 | 1.24 s | 5.98 s | 4.8× |
Next.js packages/next | 2,881 | 0.28 s | 1.82 s | 6.4× |
| Playwright | 706 | 0.15 s | 0.64 s | 4.2× |
Notice the baseline: the native TypeScript 7 compiler, not the older JavaScript implementation. Bun also reports lower memory consumption, ranging from 2.2× to 4.9× less across those projects. That makes the release worth evaluating even for teams already using the native compiler, but neither range is a promise about a particular repository or shared runner.
Compatibility deserves at least as much attention as speed. Bun reports passing all 51,210 cases in its TypeScript 7.0.2 conformance run. The same testing section also discloses mismatches in additional repository/configuration tests and 191 mismatches across roughly 3 million offline fuzzing programs. Those results concern different test populations; a perfect conformance-suite score does not mean every possible program has identical diagnostics.
I have not independently benchmarked Bun against TypeScript for this article. The table is a reason to run a paired experiment, not a reason to replace a production gate without one.
A Faster Checker Can Still Be a TypeScript Migration#
Installing Bun does not make its checker inherit the semantics of whichever typescript dependency your project happens to use. Bun’s migration documentation says it follows TypeScript 7 behavior regardless of that installed version.
For projects coming from TypeScript 5, that includes changed defaults and removed configuration options. The docs call out stricter defaults, explicit selection of ambient type packages, side-effect import checking, and obsolete settings such as baseUrl or an ES5 target.
Before attributing new errors to a broken Bun port:
- Identify both compiler versions. Compare Bun against the TypeScript version it targets when investigating diagnostic parity.
- Review
typesand asset declarations. Missing test globals or CSS-module declarations may be configuration issues. - Preserve intentional strictness. Do not switch off checks just to make the first migration run green.
- Treat unsupported targets as requirements. A project that must emit legacy JavaScript needs an appropriate build path, not a casual configuration deletion.
Bun also documents how to inspect its embedded compiler version with process.versions.typescript and align the editor’s workspace TypeScript version in its editor troubleshooting guide. Otherwise, a developer can see one set of diagnostics locally and a different set in CI even when both tools are behaving as designed.
Migrate One CI Job, Not the Entire Toolchain#
My starting point would be a temporary, non-authoritative CI job beside the existing check. Pin Bun 1.4.3, use the same commit and dependency installation, and compare both the successful run and deliberately broken cases. If your current compiler is older, separate the TypeScript-version migration from the question of whether Bun reproduces TypeScript 7 diagnostics.
A minimal script change looks like this:
{
"scripts": {
"typecheck": "bun --check --no-pretty"
}
}Use typecheck deliberately, and bun --check to invoke the checker directly. Bun’s script-name documentation warns that a package script named check takes precedence over bun check. Older Bun versions can recursively invoke a script containing "check": "bun check"; mixed-version teams should avoid that trap and upgrade together before adopting the new command.
There are three other operational details in the CI documentation:
- There is no
.tsbuildinfocache to restore. Bun checks the whole project on each run. Compare against your real warm and cold TypeScript jobs, not only a convenient full-check baseline. - Project references need explicit attention.
bun check -bfollows references, but it still does not generate declaration artifacts. Do not replace atsc -bbuild if downstream steps consume its output. - CPU concurrency is configurable. Bun uses one thread per CPU core by default; the documented
--threadsoption lets you limit that on shared infrastructure.
Measure wall time and peak memory, but also record missing diagnostics, extra diagnostics, and any configuration changes needed to achieve agreement. The broader JavaScript runtime landscape is competitive enough that adopting one useful tool need not imply moving every production service to the same runtime. A Bun type-check pilot can remain just that.
My Take#
Bun 1.4.3’s strongest idea is making type checking an easy part of an operation developers already run. A gate attached to a test or build command is harder to forget than a separate convention buried in onboarding documentation. I expect that kind of integration to matter more for adoption than the largest number on a benchmark chart.
I would trial the standalone checker first, keep the existing gate authoritative until diagnostics agree, and retain TypeScript wherever it supplies declarations or editor services. If the paired runs show a meaningful improvement on the team’s actual machines, promote the new check. If they expose migration work, do that work explicitly rather than hiding it under a runtime upgrade.
The opportunity is a shorter feedback loop with the same engineering obligations. Fewer tools are useful only when the responsibilities they carried are still covered; a faster green check that examines less code is not progress.




