Introduction
Rollup remains the go-to tool in 2026 for bundling modern libraries and applications thanks to its ES modules-based approach. Unlike Webpack, it produces lighter, tree-shakeable bundles by default. This expert tutorial guides you through a production-ready configuration including TypeScript, dynamic code splitting, and custom plugins. You'll learn how to optimize performance and avoid common pitfalls in complex builds.
Prerequisites
- Node.js 20+ and npm 10+
- Solid knowledge of modern JavaScript and TypeScript
- Familiarity with bundling and tree-shaking concepts
- An existing or new project to initialize
Project Initialization
npm init -y
npm install --save-dev rollup @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-typescript rollup-plugin-terser tslib typescriptThis command installs Rollup and the essential plugins for module resolution, CommonJS, TypeScript, and minification. Don't forget tslib for TypeScript runtime helpers.
TypeScript Configuration
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"esModuleInterop": true,
"strict": true,
"outDir": "dist",
"declaration": true
},
"include": ["src"]
}The tsconfig.json is configured to generate declarations and use ESNext so Rollup can perform optimal tree-shaking. Bundler mode improves compatibility with imports.
Basic Rollup Configuration
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from '@rollup/plugin-typescript';
import { terser } from 'rollup-plugin-terser';
export default {
input: 'src/index.ts',
output: {
file: 'dist/bundle.js',
format: 'es',
sourcemap: true
},
plugins: [
resolve(),
commonjs(),
typescript({ tsconfig: './tsconfig.json' }),
terser()
]
};This basic configuration transforms TypeScript code into an optimized ES bundle with minification. The resolve plugin automatically handles node_modules dependencies.
Adding Code Splitting
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from '@rollup/plugin-typescript';
export default {
input: {
main: 'src/index.ts',
utils: 'src/utils.ts'
},
output: {
dir: 'dist',
format: 'es',
chunkFileNames: 'chunks/[name]-[hash].js',
entryFileNames: '[name].js'
},
plugins: [resolve(), commonjs(), typescript()]
};Multi-entry with output.dir enables native code splitting. Rollup automatically generates shared chunks to reduce total bundle size.
Expert Custom Plugin
function customLogger() {
return {
name: 'custom-logger',
generateBundle(options, bundle) {
console.log('Generated files:', Object.keys(bundle));
Object.keys(bundle).forEach(key => {
if (bundle[key].type === 'chunk') {
bundle[key].code = '/* Optimized by Learni */\n' + bundle[key].code;
}
});
}
};
}
export default { /* ... previous config with customLogger() in plugins */ };This custom plugin intercepts bundle generation to add headers and log files. Ideal for advanced production transformations.
Best Practices
- Always enable sourcemaps in development and disable them in production
- Use multiple output formats (es + cjs) for maximum compatibility
- Manually configure external for peer dependencies
- Test builds with --watch for fast feedback
- Measure bundle sizes with rollup-plugin-visualizer
Common Errors to Avoid
- Forgetting to mark peerDependencies as external, which duplicates code
- Using CommonJS imports without the commonjs plugin
- Ignoring circular dependency warnings that break tree-shaking
- Not correctly configuring TypeScript paths in Rollup
Going Further
Deepen your skills with our advanced build tools courses.