Files
agent-skills/skills/tsdown/references/option-tree-shaking.md
Jason Woltje f5792c40be feat: Complete fleet — 94 skills across 10+ domains
Pulled ALL skills from 15 source repositories:
- anthropics/skills: 16 (docs, design, MCP, testing)
- obra/superpowers: 14 (TDD, debugging, agents, planning)
- coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth)
- better-auth/skills: 5 (auth patterns)
- vercel-labs/agent-skills: 5 (React, design, Vercel)
- antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo)
- Plus 13 individual skills from various repos

Mosaic Stack is not limited to coding — the Orchestrator and
subagents serve coding, business, design, marketing, writing,
logistics, analysis, and more.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:27:42 -06:00

336 lines
5.1 KiB
Markdown

# 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