Subchapter 8.14
references/option-dependencies.mdMarkdown7 KBView on GitHub
tsdown intelligently handles dependencies to keep your library lightweight while ensuring all necessary code is included.
These are NOT bundled by default:
dependencies - Installed automatically with your packagepeerDependencies - User must install manuallyoptionalDependencies - May or may not be installed depending on platform/configThese are bundled ONLY if imported:
devDependencies - Only if actually used in source codeAll dependency options are grouped under the deps field:
export default defineConfig({
deps: {
neverBundle: ['react', /^@myorg\//],
alwaysBundle: ['some-package'],
onlyBundle: ['cac', 'bumpp'],
skipNodeModulesBundle: true,
},
})Mark dependencies as external (not bundled):
export default defineConfig({
entry: ['src/index.ts'],
deps: {
neverBundle: [
'react', // Single package
'react-dom',
/^@myorg\//, // Regex pattern (all @myorg/* packages)
/^lodash/, // All lodash packages
],
},
})Force dependencies to be bundled:
export default defineConfig({
entry: ['src/index.ts'],
deps: {
alwaysBundle: [
'some-package', // Bundle this even if in dependencies
'vendor-lib',
],
},
})Whitelist of dependencies allowed to be bundled from node_modules. Throws an error if any unlisted dependency is bundled:
export default defineConfig({
entry: ['src/index.ts'],
deps: {
onlyBundle: [
'cac', // Allow bundling cac
'bumpp', // Allow bundling bumpp
/^my-utils/, // Regex patterns supported
],
},
})Behavior:
['cac', /^my-/]): Only matching dependencies can be bundled. Error for others.false: Suppress all warnings about bundled dependencies.Note: Include all sub-dependencies in the list, not just top-level imports.
Skip bundling ALL node_modules:
export default defineConfig({
entry: ['src/index.ts'],
deps: {
skipNodeModulesBundle: true,
},
})Result: No dependencies from node_modules are bundled.
Note: Cannot be used together with alwaysBundle.
export default defineConfig({
entry: ['src/index.tsx'],
format: ['esm', 'cjs'],
deps: {
neverBundle: [
'react',
'react-dom',
/^react\//, // react/jsx-runtime, etc.
],
},
dts: true,
})export default defineConfig({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
deps: {
alwaysBundle: ['lodash-es'],
},
dts: true,
})export default defineConfig({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
deps: {
neverBundle: [
/^@mycompany\//, // Don't bundle other workspace packages
],
},
dts: true,
})export default defineConfig({
entry: ['src/cli.ts'],
format: ['esm'],
platform: 'node',
deps: {
alwaysBundle: [/.*/],
},
shims: true,
})export default defineConfig({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
deps: {
neverBundle: [
'vue',
'@vue/runtime-core',
'@vue/reactivity',
],
},
dts: true,
})Dependency handling for .d.ts files follows the same rules as JavaScript.
Use TypeScript resolver for complex third-party types:
export default defineConfig({
entry: ['src/index.ts'],
dts: {
resolver: 'tsc', // Use TypeScript resolver instead of Oxc
},
})When to use tsc resolver:
@types/* packages with non-standard naming (e.g., @types/babel__generator)Trade-off: tsc is slower but more compatible.
tsdown --deps.never-bundle react --deps.never-bundle react-dom
tsdown --deps.never-bundle '/^@myorg\/.*/'tsdown --deps.skip-node-modules-bundle| Deprecated Option | New Option |
|---|---|
external | deps.neverBundle |
noExternal | deps.alwaysBundle |
inlineOnly | deps.onlyBundle |
deps.onlyAllowBundle | deps.onlyBundle |
skipNodeModulesBundle | deps.skipNodeModulesBundle |
// Don't bundle framework
export default defineConfig({
deps: {
neverBundle: ['vue', 'react', 'solid-js', 'svelte'],
},
})// Bundle everything
export default defineConfig({
deps: {
alwaysBundle: [/.*/],
},
})// Bundle only specific utils
export default defineConfig({
deps: {
neverBundle: [/.*/], // External by default
alwaysBundle: ['tiny-utils'], // Except this one
},
})// External workspace packages, bundle utilities
export default defineConfig({
deps: {
neverBundle: [
/^@workspace\//, // Other workspace packages
'react',
'react-dom',
],
alwaysBundle: [
'lodash-es', // Bundle utility libraries
],
},
})Check if it’s in devDependencies and imported. Move to dependencies:
{
"dependencies": {
"should-be-external": "^1.0.0"
}
}Or explicitly externalize:
export default defineConfig({
deps: {
neverBundle: ['should-be-external'],
},
})Ensure it’s in dependencies, peerDependencies, or optionalDependencies:
{
"dependencies": {
"needed-package": "^1.0.0"
}
}Or bundle it:
export default defineConfig({
deps: {
alwaysBundle: ['needed-package'],
},
})Use TypeScript resolver for complex types:
export default defineConfig({
dts: {
resolver: 'tsc',
},
})Default behavior:
dependencies, peerDependencies, & optionalDependencies → ExternaldevDependencies & phantom deps → Bundled if importedOverride (under deps):
neverBundle → Force externalalwaysBundle → Force bundledonlyBundle → Whitelist bundled depsskipNodeModulesBundle → Skip all node_modulesDeclaration files:
resolver: 'tsc' for complex types