
Tsdown
Configure and run tsdown/Rolldown library builds with plugins, lifecycle hooks, and programmatic `build()` for shippable ESM/CJS packages.
Overview
Tsdown is an agent skill for the Build phase that configures tsdown library bundling with Rolldown plugins, hooks, and programmatic build APIs.
Install
npx skills add https://github.com/onmax/nuxt-skills --skill tsdownWhat is this skill?
- Plugin stack: native Rolldown, Unplugin, and most Rollup plugins (with type cast); notes on Vite plugins
- Custom Rolldown transform plugins via inline `transform(code, id)` handlers
- Build hooks: `build:prepare`, `build:before`, and async `build:done` with object or function hook registration
- Programmatic API via `import { build } from 'tsdown'` with entry, dual formats, `dts`, and `exports` options
- Supports multiple sequential builds from the programmatic API
- Documents 3 plugin compatibility classes (Rolldown, Unplugin, Rollup) and 3 named build lifecycle hooks
Adoption & trust: 861 installs on skills.sh; 674 GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your TypeScript package needs dual-format dist output, dts, and custom plugins but you are unsure how to wire tsdown beyond a minimal config.
Who is it for?
Nuxt/TypeScript authors publishing libraries who want agent-guided tsdown, Rolldown plugins, and hook-driven build automation.
Skip if: Apps that only need Vite dev-server bundling with no standalone package publish step, or teams standardized on Webpack-only tooling.
When should I use this skill?
You are configuring or automating tsdown library builds, Rolldown/Unplugin plugins, build hooks, or programmatic `build()` from TypeScript.
What do I get? / Deliverables
You produce configured tsdown builds—via config hooks or `build()`—with the formats, types, and plugin pipeline your library consumers expect.
- tsdown `defineConfig` with plugins and hooks
- Built `dist` output (formats, dts, exports as configured)
Recommended Skills
Journey fit
Bundling and publishing TypeScript libraries is core product construction, which belongs on the Build shelf even when the package backs an API or Nuxt app. tsdown targets package output (formats, dts, exports)—closest to frontend/library toolchain work in the Nuxt ecosystem.
How it compares
Library-focused tsdown/Rolldown skill—not a Nuxt app deployment or Nitro server configuration guide.
Common Questions / FAQ
Who is tsdown for?
Solo builders and maintainers in the Nuxt ecosystem packaging TS libraries with tsdown who need plugin, hook, and programmatic build guidance.
When should I use tsdown?
Use it in Build → frontend when setting up dist formats and dts, or Build → integrations when CI must call `build()` programmatically before publish.
Is tsdown safe to install?
Review the Security Audits panel on this Prism page; the skill is build-configuration knowledge and does not inherently require elevated runtime permissions beyond your normal dev environment.
SKILL.md
READMESKILL.md - Tsdown
# Advanced ## Plugins ### Supported Types - **Rolldown** - Native support - **Unplugin** - Most `unplugin-*` work - **Rollup** - Most work (may need type cast) - **Vite** - May work if not using Vite internals ```ts import UnpluginVue from 'unplugin-vue/rolldown' import SomeRollupPlugin from 'some-rollup-plugin' defineConfig({ plugins: [ UnpluginVue({ isProduction: true }), SomeRollupPlugin() as any, // Type cast for Rollup plugins ], }) ``` ### Custom Plugin ```ts defineConfig({ plugins: [ { name: 'my-plugin', transform(code, id) { if (id.endsWith('.txt')) { return `export default ${JSON.stringify(code)}` } }, }, ], }) ``` See [Rolldown Plugin API](https://rolldown.rs/guide/plugin-development). ## Hooks Build lifecycle: ```ts // Object syntax defineConfig({ hooks: { 'build:prepare': (context) => { console.log('Preparing build...') }, 'build:before': (context, format) => { console.log(`Building ${format}...`) }, 'build:done': async (context) => { await generateDocs() console.log('Build complete!') }, }, }) // Function syntax defineConfig({ hooks(hooks) { hooks.hook('build:prepare', () => { console.log('Starting...') }) }, }) ``` ## Programmatic API ```ts import { build } from 'tsdown' await build({ entry: ['src/index.ts'], format: ['esm', 'cjs'], outDir: 'dist', dts: true, exports: true, }) ``` Multiple builds: ```ts await build([ { entry: ['src/node.ts'], platform: 'node', outDir: 'dist/node' }, { entry: ['src/browser.ts'], platform: 'browser', outDir: 'dist/browser' }, ]) ``` ## Rolldown Options ### inputOptions ```ts defineConfig({ inputOptions: { cwd: './custom-directory', resolve: { mainFields: ['module', 'main'], alias: { '@': './src' }, }, transform: { jsx: 'react', }, }, }) ``` Function syntax for format-specific: ```ts defineConfig({ inputOptions(options, format) { if (format === 'cjs') { options.cwd = './cjs-specific' } return options }, }) ``` ### outputOptions ```ts defineConfig({ outputOptions: { legalComments: 'inline', // Preserve license headers }, }) ``` Format-specific: ```ts defineConfig({ outputOptions(options, format) { if (format === 'esm') { options.legalComments = 'inline' } return options }, }) ``` ## Migration from tsup ### Automatic ```bash npx tsdown-migrate npx tsdown-migrate packages/* # Monorepo npx tsdown-migrate --dry-run # Preview ``` ### Changed Defaults | Option | tsup | tsdown | | -------- | ------- | ----------------------------- | | `format` | - | `esm` | | `clean` | `false` | `true` | | `dts` | `false` | Auto-enabled if `types` field | | `target` | - | Reads `engines.node` | ### Breaking Changes (v0.19+) - **Removed**: `dts.resolve` option (v0.20+) - **Removed**: `silent` option - use log levels instead - **Renamed**: `debugLogs` → `debug` - **Renamed**: `debug.devtools` → `devtools.ui` - **Exports**: `exports.legacy` controls `main`/`module` field generation - **Exports**: `exports.exclude` now excludes extension names ### No Stub Mode tsdown doesn't support stub mode. Alternatives: 1. **Watch mode**: `tsdown --watch` 2. **Dev exports**: `exports: { devExports: true }` 3. **TypeScript runners**: vite-node, tsx, jiti, Node.js v22.18+ ## Performance Tips 1. Enable `isolatedDeclarations` in tsconfig for fast `.d.ts` 2. Use `skipNodeModulesBundle: true` if not bundling deps 3. Disable sourcemaps in production if not needed ## Package Validation ### publint Validates `package.json` exports configuration: ```ts defineConfig({ publint: true, // Enable publint: 'warning', // Set severity: 'warning' | 'error' | 'suggestion' publint: 'ci-only', // Run only in CI }) ``` ```bash tsdown --publint ``` ##