# Tree Shaking Remove unused code from bundles. ## Overview Tree shaking eliminates dead code (unused exports) from your final bundle, reducing size and improving performance. **Default:** Enabled ## Basic Usage ### CLI ```bash # Tree shaking enabled (default) tsdown # Disable tree shaking tsdown --no-treeshake ``` ### Config File ```ts export default defineConfig({ entry: ['src/index.ts'], treeshake: true, // Default }) ``` ## How It Works ### With Tree Shaking **Source:** ```ts // src/util.ts export function unused() { console.log("I'm unused") } export function hello(x: number) { console.log('Hello World', x) } // src/index.ts import { hello } from './util' hello(1) ``` **Output:** ```js // dist/index.mjs function hello(x) { console.log('Hello World', x) } hello(1) ``` `unused()` function is removed because it's never imported. ### Without Tree Shaking **Output:** ```js // dist/index.mjs function unused() { console.log("I'm unused") } function hello(x) { console.log('Hello World', x) } hello(1) ``` All code is included, even if unused. ## Advanced Configuration ### Enable (Default) ```ts export default defineConfig({ treeshake: true, }) ``` Uses Rolldown's default tree shaking. ### Custom Options ```ts export default defineConfig({ treeshake: { moduleSideEffects: false, propertyReadSideEffects: false, unknownGlobalSideEffects: false, }, }) ``` See [Rolldown docs](https://rolldown.rs/reference/config-options#treeshake) for all options. ### Disable ```ts export default defineConfig({ treeshake: false, }) ``` ## Side Effects ### Package.json sideEffects Declare side effects in your package: ```json { "sideEffects": false } ``` Or specify files with side effects: ```json { "sideEffects": ["*.css", "src/polyfills.ts"] } ``` ### Module Side Effects ```ts export default defineConfig({ treeshake: { moduleSideEffects: (id) => { // Preserve side effects for polyfills return id.includes('polyfill') }, }, }) ``` ## Common Patterns ### Production Build ```ts export default defineConfig({ entry: ['src/index.ts'], format: ['esm', 'cjs'], treeshake: true, minify: true, }) ``` ### Development Build ```ts export default defineConfig((options) => ({ entry: ['src/index.ts'], treeshake: !options.watch, // Disable in dev })) ``` ### Library with Side Effects ```ts export default defineConfig({ entry: ['src/index.ts'], treeshake: { moduleSideEffects: (id) => { return ( id.includes('.css') || id.includes('polyfill') || id.includes('side-effect') ) }, }, }) ``` ### Utilities Library ```ts export default defineConfig({ entry: ['src/index.ts'], format: ['esm'], treeshake: true, dts: true, }) ``` Users can import only what they need: ```ts import { onlyWhatINeed } from 'my-utils' ``` ## Benefits ### Smaller Bundles - Only includes imported code - Removes unused functions, classes, variables - Reduces download size ### Better Performance - Less code to parse - Faster execution - Improved loading times ### Cleaner Output - No dead code in production - Easier to debug - Better maintainability ## When to Disable ### Debugging During development to see all code: ```ts export default defineConfig((options) => ({ treeshake: !options.watch, })) ``` ### Side Effect Code Code with global side effects: ```ts // This has side effects window.myGlobal = {} export function setup() { // ... } ``` Disable tree shaking or mark side effects: ```json { "sideEffects": true } ``` ### Testing Include all code for coverage: ```ts export default defineConfig({ treeshake: false, }) ``` ## Tips 1. **Leave enabled** for production builds 2. **Mark side effects** in package.json 3. **Use with minification** for best results 4. **Test tree shaking** - verify unused code is removed 5. **Disable for debugging** if needed 6. **Pure functions** are easier to tree shake ## Troubleshooting ### Code Still Included - Check for side effects - Verify imports are ES modules - Ensure code is actually unused - Check `sideEffects` in package.json ### Missing Code at Runtime - Code has side effects but marked as none - Set `sideEffects: true` or list specific files ### Unexpected Behavior - Module has side effects not declared - Try disabling tree shaking to isolate issue ## Examples ### Pure Utility Functions ```ts // utils.ts - perfect for tree shaking export function add(a, b) { return a + b } export function multiply(a, b) { return a * b } // Only 'add' imported = only 'add' bundled import { add } from './utils' ``` ### With Side Effects ```ts // polyfill.ts - has side effects if (!Array.prototype.at) { Array.prototype.at = function(index) { // polyfill implementation } } export {} // Need to export something ``` ```json { "sideEffects": ["src/polyfill.ts"] } ``` ## Related Options - [Minification](option-minification.md) - Code compression - [Target](option-target.md) - Syntax transformations - [Dependencies](option-dependencies.md) - External packages - [Output Format](option-output-format.md) - Module formats