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