rolldown-plugin-dts
A Rolldown plugin that generates TypeScript declaration files and bundles their imports into publishable .d.ts outputs. It can use the regular TypeScript compiler for maximum compatibility, Rolldown's Oxc transformer for fast isolated declarations, or the experimental TypeScript Go compiler. It belongs in a library build, not an application runtime: JavaScript is still built by Rolldown while this plugin produces the type surface consumers receive from the package.
A strong fit for TypeScript libraries already committed to Rolldown, especially when Oxc can handle isolated declarations. Do not adopt it merely for type generation if your runtime floor, module format, or bundler does not match its narrow current contract.
Use it if
- You already build a TypeScript library with Rolldown 1.2 or later and want declaration generation in the same configuration
- You want bundled .d.ts entry points instead of shipping a tree of declarations that exposes internal source layout
- Your code supports isolatedDeclarations and you want the fast Oxc generator supplied through Rolldown
- You need TypeScript project references, Vue files, or Volar custom languages and can use the full tsc generator
- Your build must run on Node 20 or early Node 22 releases: version 0.28 requires Node ^22.18.0, ^24.11.0, or 26 and later
- You use Rollup rather than Rolldown: this package has a Rolldown ^1.2.0 peer dependency, while rollup-plugin-dts is designed for Rollup
- You need one CommonJS build pass: declaration bundling requires ESM output, and the README says CommonJS packages need a separate emitDtsOnly declaration build
- Your declarations contain export = or import-equals syntax: the plugin expects ESM-style declaration input and warns that those CommonJS forms may not bundle correctly
- You want a settled 1.x API: the current release is 0.28.0, custom-language support and tsgo are explicitly experimental, and the package published many 0.x releases during its first year
Setup reality
Install rolldown-plugin-dts as a development dependency, but that is only the first piece. Rolldown ^1.2.0 is a required peer, and version 0.28 will not run below Node 22.18. For the usual tsc path you must also install a supported TypeScript version; TypeScript, vue-tsc, and the Volar packages are optional peers because not every generator uses them. The default generator is inferred from your compiler setup, which is convenient until a tsconfig change turns on isolatedDeclarations and silently selects Oxc. Pin generator when reproducibility matters. Oxc is fast and comes from Rolldown, but your source must satisfy isolated-declaration rules such as explicit public return types. Vue and other Volar languages force the tsc generator, with vue-tsc installed for the built-in Vue shortcut. TypeScript Go remains experimental, requires a tsconfig.json, and ignores tsconfigRaw and compilerOptions overrides. Declaration bundling itself needs an ESM Rolldown output. If the published JavaScript is CommonJS, run one normal JavaScript build and a second ESM declaration-only build with emitDtsOnly. Vite users must exclude .d.ts, .d.mts, and .d.cts files from Oxc transformation while retaining Vite's JavaScript exclusions. Code-splitting group names for declaration chunks must end in .d. No credentials or native compilation are involved, but compiler version, tsconfig discovery, output format, and externalized dependency types all affect the first successful build.
Patterns
Generate bundled declarations with the default compilerbasic-declarations
import { defineConfig } from 'rolldown'
import { dts } from 'rolldown-plugin-dts'
export default defineConfig({
input: 'src/index.ts',
plugins: [dts()],
output: { dir: 'dist', format: 'es' },
})The plugin infers tsc, Oxc, or tsgo from tsconfig and the installed TypeScript version. Pin generator if an automatic switch would surprise CI.
Use the full TypeScript compilerforce-tsc
dts({
generator: 'tsc',
tsconfig: './tsconfig.build.json',
compilerOptions: { stripInternal: true },
})Install a supported TypeScript 5.x or 6.x version. The tsc generator is the compatibility path for project references and custom languages.
Generate isolated declarations with Oxcfast-oxc
dts({
generator: 'oxc',
oxc: { stripInternal: true },
sourcemap: true,
})Oxc is supplied by Rolldown, but source code must be compatible with isolatedDeclarations. Use the top-level sourcemap option for .d.ts.map files.
Try the TypeScript Go generatorexperimental-tsgo
dts({
generator: 'tsgo',
tsconfig: './tsconfig.json',
tsgo: { path: '/opt/tsgo/tsgo' },
})tsgo is experimental, requires a tsconfig.json, and ignores tsconfigRaw and compilerOptions. Install TypeScript 7 or @typescript/native-preview.
Emit declarations for a source globselect-entries
dts({
entry: ['src/**/*.ts', '!src/icons/**', '!src/**/*.test.ts'],
cwd: import.meta.dirname,
})entry can include files that are not Rolldown JavaScript entry points. Negated patterns are supported and relative paths use cwd.
Run a declaration-only builddeclarations-only
export default defineConfig({
input: 'src/index.ts',
plugins: [dts({ emitDtsOnly: true })],
output: { dir: 'dist/types', format: 'es' },
})Use this as a separate ESM pass when the package's JavaScript is built as CommonJS. Declaration bundling itself requires ESM output.
Bundle declarations generated elsewherebundle-existing-dts
dts({
dtsInput: true,
entry: ['types/index.d.ts'],
emitDtsOnly: true,
})dtsInput treats entries as existing declarations. The input should use ESM declaration syntax for reliable bundling.
Generate declarations for Vue filesvue-library
dts({
generator: 'tsc',
vue: true,
entry: ['src/**/*.ts', 'src/**/*.vue'],
})Install vue-tsc in a version accepted by the plugin's peer range. Vue support uses tsc; Oxc and tsgo cannot process this custom language path.
Follow TypeScript project referencesproject-references
dts({
generator: 'tsc',
tsconfig: './tsconfig.json',
build: true,
incremental: true,
})build enables TypeScript build mode. With incremental enabled, build products such as .tsbuildinfo are persisted to disk.
Merge declaration-specific compiler settingsoverride-tsconfig
dts({
tsconfig: true,
tsconfigRaw: {
compilerOptions: { declarationMap: true },
},
compilerOptions: { removeComments: true },
})tsconfig: true discovers the nearest config. These overrides do not apply to the tsgo generator.
Keep generated declarations out of Vite's Oxc transformvite-oxc-exclusions
import { defineConfig } from 'vite'
export default defineConfig({
oxc: {
exclude: [/\.js$/, /\.d\.[cm]?ts$/],
},
})Vite replaces its default exclusions when oxc.exclude is set, so keep JavaScript excluded as well as declaration files.
Name split declaration chunks correctlydeclaration-code-splitting
export default defineConfig({
codeSplitting: {
groups: [
{ test: /shared.*\.d\.[cm]?ts$/, name: 'shared.d' },
{ test: /shared/, name: 'shared' },
],
},
})A declaration chunk group's name must end in .d. Keep a separate group name for the JavaScript chunk.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| rollup-plugin-dts | npm | You build with Rollup and want a focused declaration bundler for existing .d.ts files |
| unplugin-dts | npm | You need one declaration plugin across Vite, Rollup, Rolldown, esbuild, Rspack, or Webpack |
| vite-plugin-dts | npm | Your library is Vite-first and needs Vue support plus API Extractor based declaration rolling |
| tsup | npm | You prefer a higher-level library bundler that can emit JavaScript and declarations with less configuration |