0
# Plugin System
1
2
Built-in plugins for common bundling tasks and integration with external plugin ecosystems. tsdown supports Rollup, Rolldown, unplugin, and select Vite plugins, providing a comprehensive plugin architecture for extending build functionality.
3
4
## Capabilities
5
6
### External Plugin
7
8
Handles external dependency resolution and bundling decisions based on package.json dependencies and configuration.
9
10
```typescript { .api }
11
/**
12
* Plugin for handling external dependencies
13
* @param options - Resolved tsdown options containing dependency information
14
* @returns Rolldown plugin for external dependency handling
15
*/
16
function ExternalPlugin(options: ResolvedOptions): Plugin;
17
```
18
19
**Features:**
20
- Automatically externalizes production dependencies and peer dependencies
21
- Respects `external` and `noExternal` configuration options
22
- Supports `skipNodeModulesBundle` for excluding all node_modules
23
- Handles Node.js built-in modules with proper side effects configuration
24
- Supports regex patterns and function-based external resolution
25
26
**Usage Example:**
27
28
```typescript
29
import { ExternalPlugin } from "tsdown/plugins";
30
31
// Used internally by tsdown, but can be configured via options
32
export default defineConfig({
33
external: ["lodash", /^@types\/.*$/],
34
noExternal: ["small-utility"],
35
skipNodeModulesBundle: true
36
});
37
```
38
39
### Shebang Plugin
40
41
Manages shebang execution permissions for CLI tools and executable bundles.
42
43
```typescript { .api }
44
/**
45
* Plugin for handling shebang execution permissions
46
* @param logger - Logger instance for output
47
* @param cwd - Current working directory
48
* @param name - Optional project name for logging
49
* @param isMultiFormat - Whether building multiple formats
50
* @returns Rolldown plugin for shebang handling
51
*/
52
function ShebangPlugin(
53
logger: Logger,
54
cwd: string,
55
name?: string,
56
isMultiFormat?: boolean
57
): Plugin;
58
```
59
60
**Features:**
61
- Automatically detects shebang lines in entry chunks
62
- Grants execute permissions (0o755) to files with shebangs
63
- Provides detailed logging of permission changes
64
- Supports multi-format builds with appropriate logging
65
66
**Usage Example:**
67
68
```typescript
69
// In your source file (src/cli.ts)
70
#!/usr/bin/env node
71
import { runCLI } from "./cli-impl";
72
runCLI();
73
74
// Configuration
75
export default defineConfig({
76
entry: "src/cli.ts",
77
format: "esm"
78
// ShebangPlugin is automatically applied
79
});
80
```
81
82
### Report Plugin
83
84
Provides comprehensive size reporting and build analysis with compression metrics.
85
86
```typescript { .api }
87
/**
88
* Plugin for size reporting and build analysis
89
* @param options - Reporting configuration options
90
* @param logger - Logger instance for output
91
* @param cwd - Current working directory
92
* @param cjsDts - Whether building CommonJS declaration files
93
* @param name - Optional project name for logging
94
* @param isMultiFormat - Whether building multiple formats
95
* @returns Rolldown plugin for size reporting
96
*/
97
function ReportPlugin(
98
options: ReportOptions,
99
logger: Logger,
100
cwd: string,
101
cjsDts?: boolean,
102
name?: string,
103
isMultiFormat?: boolean
104
): Plugin;
105
106
interface ReportOptions {
107
/**
108
* Enable/disable brotli-compressed size reporting.
109
* Compressing large output files can be slow.
110
* @default false
111
*/
112
brotli?: boolean;
113
114
/**
115
* Skip reporting compressed size for files larger than this size.
116
* @default 1_000_000 // 1MB
117
*/
118
maxCompressSize?: number;
119
}
120
```
121
122
**Features:**
123
- File size reporting with raw, gzip, and optional brotli compression
124
- Sorting by entry files first, then by size
125
- TypeScript declaration file highlighting
126
- Total size summary across all files
127
- Performance optimization for large files
128
129
**Usage Example:**
130
131
```typescript
132
export default defineConfig({
133
entry: "src/index.ts",
134
format: ["esm", "cjs"],
135
report: {
136
brotli: true,
137
maxCompressSize: 500_000
138
}
139
});
140
141
// Output example:
142
// dist/index.mjs 2.1 kB │ gzip: 1.1 kB │ brotli: 1.0 kB
143
// dist/index.d.mts 856 B │ gzip: 445 B │ brotli: 398 B
144
// 2 files, total: 2.9 kB
145
```
146
147
### Node Protocol Plugin
148
149
Handles Node.js protocol prefixes (`node:`) for built-in modules with options to add or strip the protocol.
150
151
```typescript { .api }
152
/**
153
* Plugin for handling node: protocol
154
* @param nodeProtocolOption - Either 'strip' to remove node: prefix or true to add it
155
* @returns Rolldown plugin for node protocol handling
156
*/
157
function NodeProtocolPlugin(nodeProtocolOption: 'strip' | true): Plugin;
158
```
159
160
**Features:**
161
- **Strip Mode**: Removes `node:` prefix from imports (e.g., `node:fs` → `fs`)
162
- **Add Mode**: Adds `node:` prefix to built-in module imports (e.g., `fs` → `node:fs`)
163
- Proper external marking and side effects handling
164
- Pre-order resolution for optimal performance
165
166
**Usage Examples:**
167
168
```typescript
169
// Strip node: protocol
170
export default defineConfig({
171
entry: "src/index.ts",
172
nodeProtocol: 'strip'
173
// node:fs becomes fs in output
174
});
175
176
// Add node: protocol
177
export default defineConfig({
178
entry: "src/index.ts",
179
nodeProtocol: true
180
// fs becomes node:fs in output
181
});
182
```
183
184
### Plugin Ecosystem Integration
185
186
tsdown supports multiple plugin ecosystems for maximum flexibility.
187
188
```typescript { .api }
189
interface Options {
190
/**
191
* Rolldown plugins array
192
*/
193
plugins?: InputOptions['plugins'];
194
}
195
```
196
197
**Supported Plugin Types:**
198
199
1. **Rolldown Plugins**: Native plugins for maximum performance
200
2. **Rollup Plugins**: Broad compatibility with existing ecosystem
201
3. **unplugin**: Universal plugins that work across bundlers
202
4. **Vite Plugins**: Select Vite plugins (via `fromVite` option)
203
204
**Usage Examples:**
205
206
```typescript
207
import { defineConfig } from "tsdown";
208
import { nodeResolve } from "@rollup/plugin-node-resolve";
209
import { json } from "@rollup/plugin-json";
210
211
export default defineConfig({
212
entry: "src/index.ts",
213
plugins: [
214
nodeResolve(),
215
json()
216
]
217
});
218
219
// Using unplugin
220
import { unpluginExample } from "unplugin-example/rolldown";
221
222
export default defineConfig({
223
entry: "src/index.ts",
224
plugins: [
225
unpluginExample()
226
]
227
});
228
229
// Reusing Vite plugins
230
export default defineConfig({
231
entry: "src/index.ts",
232
fromVite: true, // Automatically imports plugins from vite.config.ts
233
plugins: [
234
// Additional plugins specific to tsdown
235
]
236
});
237
```
238
239
### Custom Plugin Development
240
241
Plugins follow the Rolldown plugin interface for optimal performance.
242
243
```typescript { .api }
244
// Example custom plugin
245
interface Plugin {
246
name: string;
247
buildStart?(options: InputOptions): void | Promise<void>;
248
resolveId?(id: string, importer?: string, options?: ResolveIdOptions): string | null | void | Promise<string | null | void>;
249
load?(id: string): string | null | void | Promise<string | null | void>;
250
transform?(code: string, id: string): string | null | void | Promise<string | null | void>;
251
writeBundle?(options: OutputOptions, bundle: OutputBundle): void | Promise<void>;
252
}
253
```
254
255
**Custom Plugin Example:**
256
257
```typescript
258
import { defineConfig } from "tsdown";
259
260
function customPlugin(): Plugin {
261
return {
262
name: "custom-plugin",
263
transform(code, id) {
264
if (id.endsWith('.custom')) {
265
return `export default ${JSON.stringify(code)};`;
266
}
267
}
268
};
269
}
270
271
export default defineConfig({
272
entry: "src/index.ts",
273
plugins: [
274
customPlugin()
275
]
276
});
277
```
278
279
### Production Dependency Detection
280
281
Utility function for determining which dependencies should be externalized.
282
283
```typescript { .api }
284
/**
285
* Get production dependencies that should be excluded from the bundle
286
* @param pkg - Package.json object
287
* @returns Set of dependency names to externalize
288
*/
289
function getProductionDeps(pkg: PackageJson): Set<string>;
290
```
291
292
This function extracts dependencies and peerDependencies from package.json, which are typically externalized in library builds to avoid bundling runtime dependencies.