Minify vs Bundle vs Tree-shake: What Each Does
Three orthogonal optimizations that combine to shrink JavaScript payloads.
Build pipelines often blur these terms. Each does something different, and you usually want all three.
Minify
Removes everything that does not change behavior: whitespace, comments, long names. Renames variables to single letters when scope allows.
// Before
function calculateTotalPrice(items, taxRate) {
return items.reduce((sum, item) => sum + item.price, 0) * (1 + taxRate);
}
// After
function c(a,b){return a.reduce((c,a)=>c+a.price,0)*(1+b)}
Modern minifiers (Terser, swc, esbuild) cut payload by 30-50% on top of gzip.
Bundle
Concatenates many files into fewer HTTP requests. With HTTP/2 multiplexing, this matters less than it once did, but bundlers still:
- Resolve module imports into a flat output
- Convert ESM to formats older runtimes understand
- Apply code splitting (multiple bundles per app)
// 50 source files → 3 bundles: app.js, vendor.js, route-checkout.js
Tree-shake
Eliminates code that is imported but never executed. Requires ESM (import/export) so the bundler can statically analyze what is reachable.
// utils.js
export function used() {}
export function unused() {}
// app.js
import { used } from './utils';
used();
// Output: only "used" appears in the bundle
Pre-conditions:
- ESM modules (CommonJS defeats it)
- No top-level side effects
- Mark package as
"sideEffects": falsein package.json
How They Combine
A typical production build runs in this order:
1. Bundle — collect all source modules
2. Tree-shake — drop unused exports
3. Minify — compress what remains
4. Compress — gzip/brotli at the server
For a SaaS app, each stage cuts roughly 2-5x. Skipping tree-shake is the most common mistake — it requires nothing special, just ESM imports.
Modern Defaults
- Vite: bundle (Rollup/Rolldown) + tree-shake + minify by default
- esbuild: bundle + tree-shake + minify in one pass
- webpack: bundle + tree-shake + minify when mode=production
- Bun: same defaults, faster
Measuring
Bundle size budgets in CI fail builds when payloads creep up. Lighthouse, bundlejs.com, and vite-bundle-visualizer all help.
For full build optimization see [vite build optimization](https://sdk.is/blog/vite-build-optimization) (cross-site reference).