| name | esbuild |
| description | [Applies to: **/*.{js,jsx}] Definitive guidelines for configuring and using esbuild to achieve ultra-fast, optimized, and production-ready JavaScript/TypeScript builds. |
| source | cursor_mdc |
esbuild Best Practices
esbuild is the definitive choice for speed-first JavaScript/TypeScript bundling. Follow these rules to maximize its performance, maintainability, and production readiness.
1. Centralize Configuration
Always manage esbuild options in a dedicated .mjs file for clarity, reproducibility, and IDE linting. Avoid scattering CLI flags across package.json scripts.
❌ BAD
"scripts": {
"build": "esbuild src/index.js --bundle --minify --outfile=dist/bundle.js"
}
✅ GOOD
import * as esbuild from 'esbuild';
const isProduction = process.env.NODE_ENV === 'production';
esbuild.build({
entryPoints: ['src/index.js'],
bundle: true,
outfile: 'dist/bundle.js',
minify: isProduction,
sourcemap: !isProduction ? 'inline' : 'external',
define: {
'process.env.NODE_ENV': JSON.stringify(isProduction ? 'production' : 'development'),
},
}).catch(() => process.exit(1));
2. Optimize for Target Environments
Specify the target to ensure esbuild only transpiles what's necessary, reducing bundle size and build time.
❌ BAD
esbuild.build({
});
✅ GOOD
esbuild.build({
target: ['es2022', 'chrome90', 'firefox90'],
});
3. Leverage Incremental Builds for Development
For rapid development feedback, enable incremental builds or use watch mode.
❌ BAD
esbuild.build({
entryPoints: ['src/index.js'],
bundle: true,
outfile: 'dist/bundle.js',
}).catch(() => process.exit(1));
✅ GOOD
import * as esbuild from 'esbuild';
async function devBuild() {
const ctx = await esbuild.context({
entryPoints: ['src/index.js'],
bundle: true,
outdir: 'dist',
sourcemap: true,
});
await ctx.watch();
console.log('Watching for changes...');
}
devBuild();
4. Implement Code Splitting & Hashing
For larger applications, use code splitting with ESM format and cache-friendly chunk naming.
❌ BAD
esbuild.build({
entryPoints: ['src/app.js', 'src/admin.js'],
bundle: true,
outfile: 'dist/bundle.js',
});
✅ GOOD
esbuild.build({
entryPoints: ['src/app.js', 'src/admin.js'],
bundle: true,
splitting: true,
format: 'esm',
outdir: 'dist',
chunkNames: 'chunks/[name]-[hash]',
assetNames: 'assets/[name]-[hash]',
});
5. Manage External Dependencies
When building libraries, declare common dependencies as external to prevent duplication and allow consumers to dedupe.
❌ BAD
esbuild.build({
entryPoints: ['src/library.js'],
bundle: true,
outfile: 'dist/library.js',
});
✅ GOOD
esbuild.build({
entryPoints: ['src/library.js'],
bundle: true,
outfile: 'dist/library.js',
external: ['react', 'react-dom'],
});
6. Use Path Aliases
Improve module resolution readability and prevent deep relative imports. Configure tsconfig.json and pass it to esbuild.
❌ BAD
import { helperFunction } from '../../../../utils/helpers';
✅ GOOD
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"~/*": ["src/*"]
}
}
}
esbuild.build({
tsconfig: 'tsconfig.json',
});
import { helperFunction } from '~/utils/helpers';
7. Enable Strict TypeScript Integration
Always integrate your tsconfig.json to leverage strict type checking and ensure esbuild correctly processes TypeScript.
❌ BAD
esbuild.build({
entryPoints: ['src/index.ts'],
bundle: true,
loader: { '.ts': 'tsx' },
});
✅ GOOD
esbuild.build({
entryPoints: ['src/index.ts'],
bundle: true,
tsconfig: 'tsconfig.json',
});
8. Optimize Production Builds
Ensure minify: true, sourcemap: 'external', and define for dead code elimination.
❌ BAD
esbuild.build({
minify: false,
sourcemap: true,
});
✅ GOOD
esbuild.build({
minify: true,
sourcemap: 'external',
define: {
'process.env.NODE_ENV': JSON.stringify('production'),
},
});
9. Testing Integration
esbuild focuses on bundling, not testing. Ensure your build configuration doesn't interfere with test environments (e.g., by conditionally defining process.env.NODE_ENV). For testing, use dedicated test runners (e.g., Vitest, Jest) that can either process raw source files or use a separate, test-specific esbuild configuration.
import * as esbuild from 'esbuild';
esbuild.build({
entryPoints: ['src/**/*.test.ts'],
bundle: true,
outdir: 'test-dist',
platform: 'node',
define: {
'process.env.NODE_ENV': JSON.stringify('test'),
},
}).catch(() => process.exit(1));