Skip to main content

Build Tools

Configure and optimize your TypeScript build process with modern compilers and bundlers for fast, efficient development and production builds.

What's Covered

This section covers the TypeScript compiler, build tools, bundlers, and configuration strategies for building TypeScript applications efficiently.

The TypeScript Compiler (tsc)

What is tsc?

The official TypeScript compiler that:

  • Transpiles TypeScript to JavaScript
  • Performs type checking
  • Generates declaration files (.d.ts)
  • Supports incremental compilation
  • Enables project references

Basic Usage

# Install TypeScript
npm install --save-dev typescript

# Initialize tsconfig.json
npx tsc --init

# Compile TypeScript files
npx tsc

# Watch mode
npx tsc --watch

# Type check only (no emit)
npx tsc --noEmit

tsconfig.json Configuration

Essential Settings

{
"compilerOptions": {
// Language & Environment
"target": "ES2020", // ECMAScript target version
"lib": ["ES2020", "DOM"], // Include library definitions
"jsx": "react-jsx", // JSX support

// Modules
"module": "ESNext", // Module system
"moduleResolution": "bundler", // Module resolution strategy
"resolveJsonModules": true, // Import JSON files
"esModuleInterop": true, // CommonJS/ESM interop

// Emit
"outDir": "./dist", // Output directory
"declaration": true, // Generate .d.ts files
"declarationMap": true, // Source maps for .d.ts
"sourceMap": true, // Generate source maps
"removeComments": true, // Strip comments

// Type Checking
"strict": true, // Enable all strict checks
"noImplicitAny": true, // Error on implicit any
"strictNullChecks": true, // Strict null checking
"strictFunctionTypes": true, // Strict function types
"noUnusedLocals": true, // Error on unused locals
"noUnusedParameters": true, // Error on unused parameters
"noImplicitReturns": true, // Error on missing returns

// Interop & Compatibility
"skipLibCheck": true, // Skip type checking of .d.ts files
"forceConsistentCasingInFileNames": true // Consistent file naming
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}

Configuration Presets

For Node.js:

{
"extends": "@tsconfig/node20/tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
}
}

For React:

{
"extends": "@tsconfig/react/tsconfig.json",
"compilerOptions": {
"outDir": "./dist"
}
}

Modern Build Tools

Vite

Lightning-fast build tool with native TypeScript support.

Key Features:

  • Instant server start
  • Lightning-fast HMR (Hot Module Replacement)
  • Native ESM support
  • Optimized production builds
  • TypeScript out of the box

Setup:

# Create Vite project with TypeScript
npm create vite@latest my-app -- --template react-ts

# Or add to existing project
npm install --save-dev vite

Configuration (vite.config.ts):

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': '/src'
}
},
build: {
outDir: 'dist',
sourcemap: true,
target: 'es2020'
}
});

esbuild

Extremely fast JavaScript/TypeScript bundler written in Go.

Key Features:

  • 10-100x faster than other bundlers
  • Built-in TypeScript support
  • Tree shaking
  • Minification
  • Source maps

Setup:

npm install --save-dev esbuild

Build Script:

// build.js
const esbuild = require('esbuild');

esbuild.build({
entryPoints: ['src/index.ts'],
bundle: true,
outfile: 'dist/index.js',
platform: 'node',
target: 'node20',
format: 'esm',
sourcemap: true,
minify: true
}).catch(() => process.exit(1));

SWC

Rust-based TypeScript/JavaScript compiler (20x faster than Babel).

Key Features:

  • Extremely fast compilation
  • TypeScript support
  • JSX/TSX transformation
  • Plugin system
  • Drop-in Babel replacement

Setup:

npm install --save-dev @swc/core @swc/cli

Configuration (.swcrc):

{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true,
"decorators": true
},
"target": "es2020"
},
"module": {
"type": "es6"
}
}

Webpack with ts-loader

Traditional bundler with TypeScript support.

Setup:

npm install --save-dev webpack webpack-cli ts-loader

Configuration (webpack.config.js):

const path = require('path');

module.exports = {
entry: './src/index.ts',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
resolve: {
extensions: ['.tsx', '.ts', '.js']
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
};

Build Optimization Strategies

Incremental Compilation

Enable faster rebuilds:

{
"compilerOptions": {
"incremental": true,
"tsBuildInfoFile": "./dist/.tsbuildinfo"
}
}

Project References

For monorepos and large projects:

// packages/core/tsconfig.json
{
"compilerOptions": {
"composite": true,
"declaration": true,
"outDir": "./dist"
},
"include": ["src/**/*"]
}

// packages/app/tsconfig.json
{
"compilerOptions": {
"outDir": "./dist"
},
"references": [
{ "path": "../core" }
]
}

Skip Type Checking in Production

Use esbuild/swc for fast builds, tsc for type checking:

{
"scripts": {
"build": "npm run type-check && npm run bundle",
"type-check": "tsc --noEmit",
"bundle": "esbuild src/index.ts --bundle --outfile=dist/index.js"
}
}

Tree Shaking

Remove unused code:

{
"compilerOptions": {
"module": "ES2020",
"moduleResolution": "bundler"
}
}

Development Workflow

Watch Mode for Development

# TypeScript watch mode
tsc --watch

# Vite dev server
vite

# esbuild watch
esbuild src/index.ts --bundle --outfile=dist/index.js --watch

# ts-node for running TypeScript directly
npm install --save-dev ts-node
npx ts-node src/index.ts

Hot Module Replacement (HMR)

Enable instant updates during development:

Vite (automatic):

// vite.config.ts
export default defineConfig({
server: {
hmr: true
}
});

Build Performance Tips

1. Use Modern Tools

  • esbuild - 10-100x faster
  • swc - 20x faster than Babel
  • Vite - Instant server start

2. Enable Incremental Builds

{
"compilerOptions": {
"incremental": true
}
}

3. Skip Type Checking in Bundlers

Let bundlers focus on bundling, use tsc separately for type checking:

# Parallel: type check + bundle
npm-run-all --parallel type-check bundle

4. Optimize TypeScript Config

{
"compilerOptions": {
"skipLibCheck": true, // Skip checking node_modules
"isolatedModules": true, // Each file can be transpiled independently
"noEmit": true // Don't emit when using bundler
}
}

5. Use Project References

Split large projects into smaller ones for better caching.

Build Tool Comparison

ToolSpeedTypeScript SupportUse Case
tscSlowNativeType checking, declarations
esbuildFastestBuilt-inProduction builds, bundling
swcVery FastBuilt-inDrop-in Babel replacement
ViteFastNativeModern web apps, HMR
WebpackModerateVia loaderComplex apps, legacy support
RollupModerateVia pluginLibraries, tree shaking

Common Patterns

Dual Package (ESM + CommonJS)

// package.json
{
"type": "module",
"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"
}
}
}

Build with tsup:

npm install --save-dev tsup

# package.json
{
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts"
}
}

Library Publishing

{
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["**/*.test.ts", "**/*.spec.ts"]
}

Monorepo Setup

// tsconfig.base.json
{
"compilerOptions": {
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}

// packages/*/tsconfig.json
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
}
}

Getting Started

Quick Setup

1. Initialize TypeScript:

npm install --save-dev typescript
npx tsc --init

2. Configure tsconfig.json:

{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"outDir": "./dist",
"strict": true
},
"include": ["src/**/*"]
}

3. Add Build Scripts:

{
"scripts": {
"build": "tsc",
"dev": "tsc --watch",
"type-check": "tsc --noEmit"
}
}

4. Optional: Add Fast Bundler:

npm install --save-dev esbuild

# Add to scripts
{
"scripts": {
"bundle": "esbuild src/index.ts --bundle --outfile=dist/index.js --platform=node"
}
}

Best Practices

1. Separate Type Checking from Bundling

Use tsc for types, fast bundler for output.

2. Enable Strict Mode

{
"compilerOptions": {
"strict": true
}
}

3. Use Path Aliases

{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@components/*": ["src/components/*"]
}
}
}

4. Generate Source Maps

{
"compilerOptions": {
"sourceMap": true,
"declarationMap": true
}
}

5. Exclude Test Files from Build

{
"exclude": [
"node_modules",
"**/*.test.ts",
"**/*.spec.ts"
]
}

Next Steps

After mastering TypeScript build tools, explore:

  • Monorepo Tools - Turborepo, Nx for multi-package projects
  • Bundle Analysis - Optimize bundle size
  • Docker - Containerize TypeScript apps
  • CI/CD - Automate builds and deployments
  • Publishing - Publish TypeScript libraries to npm