rolldown-plugin-dts
A Rolldown plugin that generates and bundles TypeScript declaration files.
Install
Requires Rolldown 1.2.0 or later and Node.js
^22.18.0 || ^24.11.0 || >=26.0.0.
npm i -D rolldown-plugin-dts
Install the compiler required by your generator:
npm i -D typescript@^6 # tsc
npm i -D typescript@7.1.0-beta # tsgo API
npm i -D tsrs # tsrs API
Oxc is provided by Rolldown and needs no additional dependency.
Usage
// rolldown.config.ts
import { defineConfig } from 'rolldown'
import { dts } from 'rolldown-plugin-dts'
export default defineConfig({
input: 'src/index.ts',
plugins: [dts()],
output: {
dir: 'dist',
format: 'es',
},
})
See rolldown.config.ts for the project's own setup.
Declaration-only builds
With dtsOnly: true, each entry resolves to its declaration and the build emits
no JavaScript. Entries may be source files, existing .d.ts files, or both:
export default defineConfig({
input: ['src/index.ts', 'types/globals.d.ts'],
plugins: [dts({ dtsOnly: true })],
output: { dir: 'dist' },
})
Generators
| Generator | Use it for | Requirement |
|---|---|---|
tsc |
Full TypeScript compatibility | TypeScript 5.x or 6.x |
oxc |
Fast generation for isolated declarations | Code compatible with isolatedDeclarations |
tsgo |
TypeScript Go's asynchronous declaration emit API | TypeScript 7.1 or later |
tsrs |
tsrs, highly experimental | Latest tsrs release |
When generator is omitted, the plugin selects:
oxcwhencompilerOptions.isolatedDeclarationsis enabled.tsgowhentypescriptexposesProgram.prototype.getDeclarationEmit, or when TypeScript 7.0 is installed (deprecated, see below).tscotherwise.
Automatic selection only inspects typescript and never selects tsrs.
Selecting tsgo explicitly requires TypeScript 7.1 or later, or the
deprecated TypeScript 7.0 backend below.
With TypeScript 7.0,
tsgofalls back to running thetsgoCLI. This backend is deprecated and will be removed in the next minor; upgrade to TypeScript 7.1 or later. It does not support custom languages, and among thetsgo.*options onlytsgo.path(the executable to run) applies.
generator also accepts an object implementing the exported Generator
interface.
dts({
generator: 'oxc',
})
Options
General
| Option | Description | Default |
|---|---|---|
generator |
Built-in generator name or a custom Generator implementation. |
Inferred |
tsc |
Options for the built-in tsc generator. |
{} |
entry |
Glob or globs filtering which Rolldown entries emit declarations. Supports ! negation and paths relative to cwd. |
All Rolldown entries |
cwd |
Base directory for config discovery, globs, and relative paths. | process.cwd() |
dtsOnly |
Build declarations only. See Declaration-only builds. | false |
tsconfig |
Config path; true discovers one and false disables loading. |
Nearest tsconfig.json |
tsconfigRaw |
Raw config values merged over the loaded config. | {} |
compilerOptions |
Compiler options merged over the loaded config. | {} |
sourcemap |
Emit .d.ts.map files. |
declarationMap |
resolver |
Resolve declaration imports with oxc or tsc. |
oxc |
cjsDefault |
Convert a single default export to export =. |
false |
sideEffects |
Mark declaration modules as having side effects. | false |
logger |
Logger implementing info, warn, and error. |
console |
tsc.*, oxc.*, tsgo.*, and tsrs.* apply only to their respective
generators.
entry filters Rolldown entries. It never adds declarations for files that
are not entries. For example, to skip declarations for icon entries:
dts({
entry: ['src/**/*.ts', '!src/icons/**'],
})
entry cannot be combined with dtsOnly. In a declaration-only build, list the
files in Rolldown input instead.
cjsDefault only changes the emitted export syntax. It does not enable
CommonJS-style declaration input.
TypeScript (tsc)
| Option | Description | Default |
|---|---|---|
tsc.build |
Use TypeScript build mode and follow project references. | false |
tsc.incremental |
Persist build outputs, including .tsbuildinfo, to disk. |
Enabled by the matching tsconfig options |
tsc.parallel |
Run tsc or vue-tsc in a separate process. |
false |
tsc.eager |
Load every file listed by tsconfig.json. |
false |
tsc.newContext |
Use an isolated compiler cache instead of the shared context. | false |
tsc.vue |
Register the built-in Vue integration using vue-tsc. |
false |
emitJs |
Generate declarations for JavaScript files with JSDoc types. | allowJs or checkJs |
Top-level build, incremental, parallel, eager, newContext, and vue are
deprecated. Use tsc.* instead.
tsc.incremental applies to build mode. When disabled, build outputs stay in
memory.
To invalidate a file in the shared compiler cache:
import {
globalContext,
invalidateContextFile,
} from 'rolldown-plugin-dts/tsc-context'
invalidateContextFile(globalContext, 'src/foo.ts')
Custom languages
customLanguages registers non-standard source files such as Vue or Astro.
Volar integrations must provide both volarTypeScript and
createVolarPlugins; they require the tsc generator. tsc.vue: true is the
preconfigured Vue shortcut.
This API is experimental and may change.
Oxc
Oxc generates declarations from each source file independently. Your code must
be compatible with isolatedDeclarations, including explicit type annotations
where required for exported declarations.
| Option | Description | Default |
|---|---|---|
oxc.stripInternal |
Omit declarations marked with /** @internal */. |
compilerOptions.stripInternal |
sourcemap |
Generate .d.ts.map files so editors can navigate from declarations to the original source. |
compilerOptions.declarationMap |
dts({
generator: 'oxc',
sourcemap: true,
oxc: {
stripInternal: true,
},
})
TypeScript Go
Experimental. Requires typescript@7.1.0-beta or a compatible version and a
tsconfig.json.
| Option | Description | Default |
|---|---|---|
tsgo.moduleUrl |
File URL of the TypeScript package that provides the Go API. | import.meta.resolve('typescript') |
tsgo.path |
Custom API server executable, passed as tsserverPath. |
Provided by the selected package |
tsgo.runExternalCode |
Allow execution of content mappers configured in tsconfig. | false |
tsgo.vfs |
Supply transformed source code through a virtual filesystem. | false |
- The plugin's current
tsgoimplementation reads compiler settings from the config file;tsconfigRawandcompilerOptionsdo not override them. - Declaration maps require
compilerOptions.declarationMap: truein the config file; setting only the plugin'ssourcemap: trueproduces a warning. - With
tsgo.vfs: true, source transforms must run before the dts transform hook. Non-Volar custom languages also require atoTsFilenamemapping. Volar integrations, includingtsc.vue, requiretsc.
dts({
generator: 'tsgo',
tsgo: {
moduleUrl: import.meta.resolve('typescript'),
vfs: true,
},
})
Content mappers
Configure contentMappers in your tsconfig and enable tsgo.runExternalCode:
dts({
generator: 'tsgo',
tsgo: { runExternalCode: true },
})
Extensions declared by content mappers (including inherited tsconfig settings)
are recognized automatically; customLanguages is not needed. Content mappers
read files from disk and cannot be combined with tsgo.vfs. If you also emit
JavaScript, use your framework's Rolldown plugin to transform these source files.
tsrs
Highly experimental; only the latest tsrs release is supported. Accepts the
same options as TypeScript Go under tsrs.* (moduleUrl defaults to
import.meta.resolve('tsrs')).
Vite
Exclude generated declarations from Oxc transformation. Because oxc.exclude
replaces Vite's default exclusions, keep JavaScript files excluded as well:
// vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig({
oxc: {
exclude: [/\.js$/, /\.d\.[cm]?ts$/],
},
})
Code splitting
Declaration chunk names must end in .d:
export default {
codeSplitting: {
groups: [
{ test: /foo.*\.d\.[cm]?ts$/, name: 'shared.d' },
{ test: /foo/, name: 'shared' },
],
},
}
Limitations
Declaration bundling requires an ESM Rolldown output. The cjs output format is
not supported. For CommonJS packages, build the JavaScript output separately
and use dtsOnly for a second declaration-only build.
The following declaration input cannot be bundled:
- CommonJS export assignments such as
export = value. - CommonJS import aliases such as
import value = require('package'). - Script-style ambient declarations, such as
declare module 'package' { ... }or unexported top-leveldeclarestatements. Bundled declaration chunks are always modules, which would change the meaning of these declarations.
Mark dependencies that use unsupported declaration syntax as external.
Credits
Inspired by rollup-plugin-dts, with an independent implementation. Its MIT-licensed test suite is used with permission.
Sponsors
License
MIT License 2025-PRESENT Kevin Deng