tsc vs esbuild: Type Checking vs Fast Transpiling
They do different jobs: esbuild transpiles TypeScript extremely fast but skips type checking; tsc type-checks (and can emit) but is slower.
A common confusion: esbuild compiles TS to JS by stripping types without verifying them, so it never reports type errors. tsc actually checks types. Most teams use esbuild (or swc) to build and tsc to type-check.
| tsc | esbuild | |
|---|---|---|
| Type checking | Yes (the point) | No (strips types only) |
| Transpile speed | Slower | Very fast |
| Emit/bundle | Emit, no bundling | Transpile + bundle |
| Reports type errors | Yes | Never |
| Typical role | Type gate | Build/transpile step |
Why you usually need both
esbuild produces runnable JS fast, but because it does not understand the type system, a build can succeed while real type errors slip through. tsc is the tool that fails when types are wrong. Using only esbuild means losing your type safety net.
The common setup
Build/bundle with esbuild (or swc) for speed, and run tsc --noEmit as a separate type-check step. This gives fast builds plus genuine type verification. Watch mode locally uses esbuild for speed; CI runs tsc to enforce correctness.
In CI
Run tsc --noEmit as its own job/gate so a fast esbuild build never hides type regressions. esbuild keeps the build step quick; tsc keeps types honest. They are complementary, not competing.
The verdict
Do not pick one: use esbuild (or swc) for fast transpiling/bundling and tsc --noEmit for type checking. esbuild alone will not catch type errors; tsc alone is slower to build.