Best TypeScript-First Build Tools 2026
esbuild is 45x faster than tsc for transpilation. SWC is 20x faster. Yet tsc remains the gold standard for type checking — because esbuild and SWC deliberately skip type checking entirely. The TypeScript build tooling landscape in 2026 is about combining these tools correctly, not picking one.
TL;DR
For libraries: Use tsup (esbuild-based, zero-config) or unbuild (Rollup-based, better tree-shaking). For applications: Your framework's build tool (Next.js, Vite, etc.) already handles this. For type checking: Always run tsc --noEmit separately — no other tool can replace it. For running TypeScript directly: Use tsx (fast, esbuild-based).
Key Takeaways
tsc: Only tool that performs type checking; transpilation is 45x slower than esbuildesbuild: 45x faster than tsc for transpilation; does NOT type checkswc: 20x faster than tsc; does NOT type check; used by Rspack/Next.js internalstsup(~1.2M weekly downloads): Most popular library bundler, uses esbuild, zero-configunbuild: Rollup-based, better for libraries needing optimal tree-shakingpkgroll: Rollup-based, explicit about entry points, growing adoption- The correct pattern:
tsc --noEmit(type check) + esbuild/SWC (transpile)
The TypeScript Tooling Landscape
The tools serve different purposes:
Source (TypeScript)
│
├─→ Type Checking: tsc --noEmit (required for correctness)
│
├─→ Transpilation (TS → JS):
│ tsc (slow, correct)
│ esbuild (45x faster, no type check)
│ SWC (20x faster, no type check)
│ Babel (configurable, slow)
│
└─→ Bundling (JS → optimized JS):
tsup (esbuild, library-focused)
unbuild (Rollup, library-focused)
pkgroll (Rollup, library-focused)
Vite (Rollup + esbuild)
Rollup (manual configuration)
tsc: The Type Checking Foundation
Package: typescript (includes tsc)
Weekly downloads: 60M+
Purpose: Type checking + transpilation (slow path)
Never use tsc for production builds in 2026. Use it only for type checking:
# Type check only (no output files)
npx tsc --noEmit
# Or in watch mode during development
npx tsc --noEmit --watch
// package.json
{
"scripts": {
"type-check": "tsc --noEmit",
"build": "tsup src/index.ts --format esm,cjs --dts"
}
}
tsconfig.json for Library Publishing
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"strict": true,
"skipLibCheck": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
tsup: The Library Bundler Standard
Package: tsup
Weekly downloads: 1.2M
GitHub stars: 10K
Creator: EGOIST
Underlying: esbuild
tsup is the most popular TypeScript library bundler. Zero-config defaults make it productive immediately:
npm install -D tsup
Basic Library Setup
// tsup.config.ts
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['cjs', 'esm'], // CommonJS + ES Modules
dts: true, // Generate .d.ts files
splitting: false, // Keep output in single files
sourcemap: true,
clean: true, // Clean dist/ before build
});
// package.json
{
"name": "my-library",
"version": "1.0.0",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.cjs",
"types": "./dist/index.d.ts"
}
},
"scripts": {
"build": "tsup",
"dev": "tsup --watch",
"type-check": "tsc --noEmit"
},
"devDependencies": {
"tsup": "^8.0.0",
"typescript": "^5.4.0"
}
}
Multiple Entry Points
export default defineConfig({
entry: {
index: 'src/index.ts',
cli: 'src/cli.ts',
utils: 'src/utils/index.ts',
},
format: ['cjs', 'esm'],
dts: true,
external: ['react'], // Don't bundle peer dependencies
});
tsup Features
export default defineConfig({
entry: ['src/index.ts'],
format: ['cjs', 'esm'],
dts: true,
minify: true, // Minify output
treeshake: true, // Remove dead code
shims: true, // Add CJS/ESM shims for interop
onSuccess: 'node dist/index.cjs', // Run after build
banner: {
js: '// My Library v1.0.0',
},
define: {
'process.env.NODE_ENV': '"production"',
},
});
unbuild: Rollup-Based Library Bundling
Package: unbuild
Weekly downloads: 800K
GitHub stars: 2.5K
Creator: UnJS (Nuxt team)
Underlying: Rollup + mkdist
unbuild is the choice when output optimization matters more than build speed. Rollup's tree-shaking and code splitting are superior to esbuild's for complex libraries.
npm install -D unbuild
// build.config.ts
import { defineBuildConfig } from 'unbuild';
export default defineBuildConfig({
entries: ['./src/index'],
declaration: true,
rollup: {
emitCJS: true,
cjsBridge: true,
esbuild: { minify: true },
},
externals: ['react', 'react-dom'],
});
unbuild automatically infers your build configuration from package.json exports:
// package.json — unbuild reads this automatically
{
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
}
}
Why Choose unbuild Over tsup?
- Rollup tree-shaking is more aggressive (better output for complex libraries)
mkdistfor distributing TypeScript source files (.d.ts+.ts)- Better handling of CSS-in-JS and asset imports in library code
- Part of the UnJS ecosystem (works with Nuxt, Nitro, H3)
pkgroll: Explicit Entry Points
Package: pkgroll
Weekly downloads: 100K
GitHub stars: 1.5K
Underlying: Rollup
pkgroll reads your package.json exports field to determine what to build — no separate config file needed:
npm install -D pkgroll typescript
// package.json — pkgroll uses this as its configuration
{
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"./utils": {
"types": "./dist/utils.d.ts",
"import": "./dist/utils.js"
}
},
"scripts": {
"build": "pkgroll"
}
}
# Just run:
npx pkgroll
# With watch mode:
npx pkgroll --watch
pkgroll's philosophy: your package.json is the source of truth for what gets built. No separate build config file.
esbuild: The Raw Transpiler
Package: esbuild
Weekly downloads: 32M
GitHub stars: 38K
For scripts and non-library code, raw esbuild is fast and simple:
// build.ts — manual esbuild
import * as esbuild from 'esbuild';
await esbuild.build({
entryPoints: ['src/index.ts'],
bundle: true,
outfile: 'dist/index.js',
platform: 'node',
target: 'node20',
format: 'esm',
minify: true,
sourcemap: true,
external: ['express', 'zod'], // Don't bundle dependencies
});
esbuild Watch Mode
const ctx = await esbuild.context({
entryPoints: ['src/index.ts'],
bundle: true,
outdir: 'dist',
platform: 'node',
});
await ctx.watch();
console.log('Watching...');
SWC: Rust-Powered Transpilation
Package: @swc/core
Weekly downloads: 15M
GitHub stars: 32K
SWC is used internally by Next.js, Rspack, and Vite (via plugins). For direct use:
npm install -D @swc/core @swc/cli
// .swcrc
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true,
"decorators": true
},
"transform": {
"react": { "runtime": "automatic" }
},
"target": "es2022"
},
"module": {
"type": "es6"
},
"sourceMaps": true
}
# Transpile a file
npx swc src/index.ts -o dist/index.js
# Transpile directory
npx swc src -d dist
Performance Comparison
| Tool | Transpilation (100 files) | Type Checking | Tree Shaking |
|---|---|---|---|
| tsc | ~10s | Yes | No |
| esbuild | ~0.2s (50x) | No | Basic |
| SWC | ~0.5s (20x) | No | Basic |
| tsup (esbuild) | ~0.3s | Via tsc | Basic |
| unbuild (Rollup) | ~2s | Via tsc | Excellent |
The Recommended Stack
For Library Development
# Build tool: tsup or unbuild
npm install -D tsup typescript
# Type check separately:
# tsc --noEmit (in CI, pre-commit, IDE)
# tsup builds with dts: true (generates .d.ts only, no type errors)
For Application Development
Use your framework's built-in tools:
- Next.js: SWC (built-in) + turbopack
- Vite: esbuild (dev) + Rollup (prod)
- Remix: esbuild
For CLI Tools
# tsup with Node.js target:
tsup src/cli.ts --format cjs --dts --no-splitting
For Monorepos (TypeScript Project References)
# tsc project references for type checking:
tsc --build --verbose
# tsup for each package's output:
workspace: each package has its own tsup.config.ts
Choosing the Right Tool
| Use Case | Recommended Tool |
|---|---|
| NPM library (fast build) | tsup |
| NPM library (optimal bundle) | unbuild |
| NPM library (package.json-driven) | pkgroll |
| Type checking (always) | tsc --noEmit |
| Node.js script | esbuild direct or tsup |
| Next.js app | Built-in SWC + Turbopack |
| Vite app | Built-in esbuild + Rollup |
| Running TS directly | tsx |
Compare download trends for these tools on PkgPulse.
See the live comparison
View best typescript build tools on PkgPulse →