tsdown
npx skills add https://github.com/grahamcrackers/skills --skill tsdown
Agent 安装分布
Skill 文档
tsdown â Library Bundler
Blazing-fast bundler for TypeScript/JavaScript libraries powered by Rolldown and Oxc. A modern replacement for tsup.
Setup
npm install -D tsdown
# Or scaffold a new project
npm create tsdown@latest
Requires Node.js 20.19+.
Basic Configuration
// tsdown.config.ts
import { defineConfig } from "tsdown";
export default defineConfig({
entry: ["src/index.ts"],
format: ["esm", "cjs"],
dts: true,
});
Defaults (Different from tsup)
| Option | tsdown default | tsup default |
|---|---|---|
format |
esm |
cjs |
clean |
true |
false |
dts |
Auto-enabled if types field exists in package.json |
false |
Entry Points
// Single entry
entry: ["src/index.ts"],
// Named entries
entry: {
index: "src/index.ts",
utils: "src/utils.ts",
cli: "src/cli.ts",
},
// Glob with exclusions
entry: ["src/**/*.ts", "!**/*.test.ts"],
Output Formats
// Dual ESM + CJS (most common for libraries)
format: ["esm", "cjs"],
// Browser global
format: ["iife"],
globalName: "MyLib",
// UMD for CDN/script tag compatibility
format: ["umd"],
globalName: "MyLib",
Package.json Exports
Auto-generate the exports field:
export default defineConfig({
entry: ["src/index.ts"],
format: ["esm", "cjs"],
dts: true,
exports: true, // auto-generates package.json exports field
});
Type Declarations
// Basic â generates .d.ts alongside output
dts: true,
// With options
dts: {
sourcemap: true,
compilerOptions: {
composite: false,
},
},
Always enable dts for published TypeScript libraries.
Dependency Handling
tsdown automatically externalizes dependencies and peerDependencies from package.json.
// Manually external
external: ["react", "react-dom", /^@myorg\//],
// Force-bundle a dependency (inline it)
noExternal: ["tiny-utility-to-inline"],
- External by default:
dependencies,peerDependencies. - Bundled by default:
devDependencies.
Platform and Target
// Node.js library (default)
platform: "node",
target: "es2022",
// Browser library
platform: "browser",
target: "es2020",
// Isomorphic
platform: "neutral",
Minification
// Full minification
minify: true,
// Dead code elimination only (smaller output, readable)
minify: "dce-only",
Shims
Add ESM/CJS interop shims (__dirname, __filename, import.meta.url):
shims: true,
Enable when publishing dual ESM/CJS packages that reference Node.js globals.
Source Maps
sourcemap: true, // external .map files
sourcemap: "inline", // embedded in output
sourcemap: "hidden", // generated but not referenced
Unbundle Mode
Preserve the source directory structure instead of bundling into a single file:
export default defineConfig({
entry: ["src/**/*.ts", "!**/*.test.ts"],
unbundle: true,
format: ["esm"],
dts: true,
});
Useful for utility libraries where consumers may want to import individual modules.
Plugins
tsdown supports Rolldown, Rollup, and unplugin plugins:
import { wasm } from "rolldown-plugin-wasm";
export default defineConfig({
entry: ["src/index.ts"],
plugins: [wasm()],
});
Multiple Configurations
Export an array for different build targets:
export default defineConfig([
{
entry: ["src/index.ts"],
format: ["esm", "cjs"],
dts: true,
},
{
entry: ["src/cli.ts"],
format: ["esm"],
platform: "node",
banner: { js: "#!/usr/bin/env node" },
},
]);
Conditional Configuration
export default defineConfig((options) => {
const isDev = options.watch;
return {
entry: ["src/index.ts"],
format: ["esm", "cjs"],
minify: !isDev,
sourcemap: isDev,
};
});
Monorepo / Workspace Builds
Build all packages in a monorepo from a single config:
export default defineConfig({
workspace: "packages/*",
entry: ["src/index.ts"],
format: ["esm", "cjs"],
dts: true,
});
Lifecycle Hooks
export default defineConfig({
entry: ["src/index.ts"],
hooks: {
"build:before": async (context) => {
// Pre-build tasks (codegen, validation)
},
"build:done": async (context) => {
// Post-build tasks (copy files, notifications)
},
},
});
CI Configuration
Use 'ci-only' and 'local-only' to vary behavior by environment:
export default defineConfig({
entry: ["src/index.ts"],
format: ["esm", "cjs"],
dts: true,
failOnWarn: "ci-only", // fail on warnings in CI only
publint: "ci-only", // validate package structure in CI
attw: "ci-only", // check "are the types wrong" in CI
});
Common Recipes
React Component Library
export default defineConfig({
entry: ["src/index.tsx"],
format: ["esm", "cjs"],
dts: true,
external: ["react", "react-dom"],
});
Node.js CLI Tool
export default defineConfig({
entry: ["src/cli.ts"],
format: ["esm"],
platform: "node",
target: "es2022",
banner: { js: "#!/usr/bin/env node" },
minify: true,
});
Dual Package with Shims
export default defineConfig({
entry: ["src/index.ts"],
format: ["esm", "cjs"],
dts: true,
shims: true,
exports: true,
clean: true,
});
Migration from tsup
npx tsdown migrate
This handles ~90% of config conversion automatically. Key differences to review:
formatdefaults toesm(tsup defaults tocjs).cleanis enabled by default.dtsauto-enables iftypesfield exists inpackage.json.onSuccessâ usehooks['build:done']instead.splittingâ enabled by default, usesplitting: falseto disable.
CLI Reference
tsdown # Build with defaults
tsdown --watch # Watch mode
tsdown --format esm,cjs # Specify formats
tsdown --dts # Generate declarations
tsdown --minify # Minify output
tsdown --outDir lib # Custom output directory
tsdown --sourcemap # Generate source maps
tsdown --config custom.ts # Custom config file
tsdown src/a.ts src/b.ts # Multiple entries