esbuild: Speed and Limitations
Use esbuild as a standalone bundler and understand why it is orders of magnitude faster than webpack, plus its current limitations around plugins and types.
esbuild: Speed and Limitations is a free Frontend Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Frontend Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Is esbuild?
esbuild is a bundler and minifier written in Go. It's 10-100x faster than JavaScript-based bundlers because of native multi-threading and zero startup overhead. Created by Evan Wallace (Figma).
Speed Benchmarks
Bundling React's source (around 6 MB): esbuild ~0.4s, Webpack ~9s, Rollup ~6s, Parcel ~10s. The speed comes from: Go (compiled), parallelism, no AST conversion between passes, simple architecture.
Using esbuild Directly
Install and run from CLI.
npm install -D esbuild
npx esbuild src/app.ts \
--bundle \
--outfile=dist/app.js \
--minify \
--sourcemap \
--target=es2020 \
--platform=browserProgrammatic API
Use from a build script for more control.
// build.js
import { build } from 'esbuild';
await build({
entryPoints: ['src/app.ts'],
bundle: true,
outfile: 'dist/app.js',
minify: true,
sourcemap: true,
target: ['es2020'],
platform: 'browser',
define: { 'process.env.NODE_ENV': '"production"' }
});TypeScript Without tsc
esbuild strips TypeScript syntax (turning .ts into .js) much faster than tsc. It does NOT type-check — run tsc --noEmit separately for that.
# Strip types and bundle in one go:
npx esbuild src/index.ts --bundle --outfile=dist/index.js
# Type-check separately (slower, can run in parallel):
npx tsc --noEmitDev Server with Hot Reload
esbuild has a built-in dev server with watch mode and HMR via the context API.
import { context } from 'esbuild';
const ctx = await context({
entryPoints: ['src/app.ts'],
bundle: true,
outdir: 'dist'
});
await ctx.watch();
await ctx.serve({ servedir: 'public', port: 8000 });Plugin Architecture
esbuild supports plugins with two main hooks: onResolve (intercept module resolution) and onLoad (provide content for resolved modules).
const myPlugin = {
name: 'env',
setup(build) {
build.onResolve({ filter: /^env$/ }, () => ({ path: 'env', namespace: 'env-ns' }));
build.onLoad({ filter: /.*/, namespace: 'env-ns' }, () => ({
contents: JSON.stringify(process.env),
loader: 'json'
}));
}
};Loaders
esbuild has built-in loaders for: js, ts, jsx, tsx, json, css, text, base64, dataurl, file, binary. CSS support is bundling-only (no modules, no PostCSS) — use a plugin or another tool.
Limitations vs Rollup/Vite
1) Plugin ecosystem is smaller. 2) CSS pipeline is minimal — no CSS Modules, no PostCSS, no preprocessors out of box. 3) No HMR for frameworks (frameworks like React/Vue need framework-specific HMR). 4) No tree-shaking warnings or analysis. 5) Less mature for complex SSR setups.
When esbuild Shines
1) Library bundling (single entrypoint, no framework). 2) Lambda/Worker packaging (minimal cold start). 3) Sub-tool inside Vite/tsup (used for TS transformation under the hood). 4) Migrating from tsc to a faster TS pipeline.
esbuild Inside Other Tools
Vite uses esbuild for dev TS/JSX transformation and pre-bundling node_modules. tsup uses esbuild for library bundling. Rollup has an esbuild plugin. Many tools combine the speed of esbuild with their own UX.
tsup — Library-Friendly esbuild Wrapper
For publishing npm libraries, tsup wraps esbuild with sensible defaults: emits CJS + ESM + .d.ts, watches in dev, accepts simple config.
# package.json
"scripts": { "build": "tsup src/index.ts --format esm,cjs --dts" }Bundle Size Trade-offs
esbuild minifies fast but its minification is slightly less aggressive than Terser. Run Terser as a post-step for absolute smallest output, if size matters more than build speed.
Quick Check
esbuild can replace tsc for compiling TypeScript — but what does esbuild NOT do that tsc does?
Recap: esbuild
Go-based bundler, 10-100x faster than JS bundlers. CLI + programmatic API. Strips TS (no type-check — run tsc --noEmit). Plugin hooks: onResolve + onLoad. Limitations: thin plugin ecosystem, minimal CSS pipeline, no framework HMR. Best for: libraries, Lambda/Workers, inside Vite/tsup. Use tsup wrapper for npm libs.
Frequently asked questions
Is the “esbuild: Speed and Limitations” lesson free?
Yes — the full text of “esbuild: Speed and Limitations” is free to read here on the web, and the Frontend Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Frontend Academy course, upgrade to CoddyKit PRO.
What will I learn in “esbuild: Speed and Limitations”?
Use esbuild as a standalone bundler and understand why it is orders of magnitude faster than webpack, plus its current limitations around plugins and types. You practise Frontend Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Frontend Academy?
No prior experience is required. Frontend Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “esbuild: Speed and Limitations” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Frontend Academy lesson?
Yes. Every Frontend Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Vite: Plugin System and SSR Mode
- esbuild: Speed and Limitations
- pnpm Workspaces for Monorepos
- Turbo: Caching and Task Pipelines