TypeScript Bundling — Complete Guide
In this tutorial, you will learn about TypeScript Bundling. We cover key concepts, practical examples, and best practices to help you master this topic.
Bundling TypeScript for production involves compiling TS to JS, resolving modules, treeshaking dead code, and optimizing output for browsers or Node.js — with modern tools like Vite, esbuild, and tsup making this faster than ever.
What You'll Learn
- Vite with TypeScript configuration
- Webpack with ts-loader
- esbuild for ultra-fast compilation
- tsup for TypeScript libraries
- Tree-shaking and code splitting
Why It Matters
TypeScript's compiler (tsc) does not bundle modules. A bundler is required to produce a single output file (or set of files) that runs in browsers. Choosing the right bundler affects build speed, output size, and developer experience.
Real-World Use
DodaTech's Durga Antivirus Pro dashboard uses Vite for development (instant HMR) and esbuild for production (sub-second builds). The shared utility library uses tsup to generate both ESM and CJS outputs.
Learning Path
flowchart LR A[Linting] --> B[Bundling] B --> C[React Components] B --> D[You Are Here] C --> E[React Hooks] E --> F[React Events]
Vite
The fastest build tool for web projects:
npm create vite@latest my-app -- --template react-ts
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
build: {
target: 'es2020',
sourcemap: true,
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom'],
},
},
},
},
});
Vite uses esbuild for transpilation (dev) and Rollup for production bundling. TypeScript is handled natively — no extra config needed.
Webpack
npm install --save-dev webpack webpack-cli ts-loader typescript
// 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'],
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
devtool: 'source-map',
};
esbuild
npm install --save-dev esbuild
// build.js
const esbuild = require('esbuild');
esbuild.build({
entryPoints: ['src/index.ts'],
bundle: true,
outfile: 'dist/bundle.js',
platform: 'browser',
target: 'es2020',
sourcemap: true,
minify: true,
treeShaking: true,
}).catch(() => process.exit(1));
esbuild is 10-100x faster than traditional bundlers. It handles TypeScript natively.
tsup (for Libraries)
npm install --save-dev tsup
// package.json
{
"scripts": {
"build": "tsup src/index.ts --dts --sourcemap --format esm,cjs"
}
}
// tsup.config.ts
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
dts: true,
sourcemap: true,
clean: true,
splitting: true,
});
tsup is built on esbuild with TypeScript declaration generation built in. Perfect for libraries.
Tree-Shaking
Tree-shaking eliminates unused exports from the final bundle:
// utils.ts
export function used() { return 1; }
export function unused() { return 2; } // Removed by tree-shaking
// app.ts
import { used } from './utils';
For tree-shaking to work:
- Use ES module syntax (
import/export) - Enable
sideEffects: falsein package.json - Use a bundler that supports tree-shaking (Rollup, esbuild, Webpack in production mode)
Code Splitting
// Dynamic import — creates a separate chunk
const AdminModule = await import('./admin/AdminPanel');
Vite/Rollup automatically splits dynamic imports into separate chunks. Webpack needs splitChunks configuration.
Common Mistakes
1. Not Setting the Correct target
Bundlers default to modern targets, but if you need IE11 support, configure target explicitly.
2. Forgetting sourceMap in Production
Source maps in production expose your source code. Disable them:
// Vite
build: { sourcemap: false }
3. Not Configuring TypeScript for the Bundler
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "bundler",
"isolatedModules": true
}
}
4. Using ts-loader When esbuild Is Available
ts-loader is 10x slower than esbuild-based alternatives. Use esbuild-loader or Vite.
5. Not Using .d.ts for Library Exports
If building a library, always generate type declarations:
tsup --dts
Practice Questions
Why does TypeScript need a bundler? tsc compiles TS to JS but does not bundle multiple files. Bundlers combine modules, tree-shake, and optimize for production.
What is tree-shaking? Eliminating unused exports from the final bundle, reducing file size.
What is the advantage of esbuild over Webpack? Speed — esbuild is 10-100x faster, written in Go, and handles TypeScript natively.
What does tsup add on top of esbuild? Automatic declaration generation (--dts), multiple output formats (ESM/CJS), and simpler configuration.
Challenge: Create a small TypeScript library with tsup that exports both ESM and CJS formats with type declarations. Publish the output and verify both import and require work.
FAQ
Mini Project: Build Configurations
// src/index.ts
export function add(a: number, b: number): number { return a + b; }
export function multiply(a: number, b: number): number { return a * b; }
// For library — tsup config
// tsup.config.ts
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
dts: true,
clean: true,
splitting: false,
});
# Build library
npx tsup
# Output:
# dist/index.js (CJS)
# dist/index.mjs (ESM)
# dist/index.d.ts (Types)
# dist/index.d.mts (Types for ESM)
What's Next
You've completed Module 5: Tooling & Config. Now explore React with TypeScript:
| Lesson | Description |
|---|---|
| {{< ref "/programming-languages/typescript/35-linting-prettier" >}} | Review linting |
| {{< ref "/programming-languages/typescript/37-react-components" >}} | React components with TypeScript |
| {{< ref "/programming-languages/typescript/38-react-hooks" >}} | Typed React hooks |
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro