Files
stack/packages/mosaic/framework/skills/tsdown/references/option-dependencies.md
T
fargo 1a822493ba format: apply repo prettier (3.8.1) to the folded skills tree
963 markdown files reformatted with the repository's pinned prettier so
pnpm format:check covers the folded tree like every other repo file.

The formatter's embedded-language pass also normalized code fences
(TS semicolons, closed HTML tags in examples, lowercased CSS hex colors,
one renumbered list that skipped an index). Alphanumeric token deltas vs
the fold commit were audited file-by-file; all are formatter-equivalent
markup normalizations plus the four sanitized skills.
2026-08-19 14:37:17 -05:00

5.6 KiB

Dependencies

Control how dependencies are bundled or externalized.

Overview

tsdown intelligently handles dependencies to keep your library lightweight while ensuring all necessary code is included.

Default Behavior

Auto-Externalized

These are NOT bundled by default:

  • dependencies - Installed automatically with your package
  • peerDependencies - User must install manually

Conditionally Bundled

These are bundled ONLY if imported:

  • devDependencies - Only if actually used in source code
  • Phantom dependencies - In node_modules but not in package.json

Configuration Options

external

Mark dependencies as external (not bundled):

export default defineConfig({
  entry: ['src/index.ts'],
  external: [
    'react', // Single package
    'react-dom',
    /^@myorg\//, // Regex pattern (all @myorg/* packages)
    /^lodash/, // All lodash packages
  ],
});

noExternal

Force dependencies to be bundled:

export default defineConfig({
  entry: ['src/index.ts'],
  noExternal: [
    'some-package', // Bundle this even if in dependencies
    'vendor-lib',
  ],
});

skipNodeModulesBundle

Skip resolving and bundling ALL node_modules:

export default defineConfig({
  entry: ['src/index.ts'],
  skipNodeModulesBundle: true,
});

Result: No dependencies from node_modules are parsed or bundled.

Common Patterns

React Component Library

export default defineConfig({
  entry: ['src/index.tsx'],
  format: ['esm', 'cjs'],
  external: [
    'react',
    'react-dom',
    /^react\//, // react/jsx-runtime, etc.
  ],
  dts: true,
});

Utility Library with Shared Deps

export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  // Bundle lodash utilities
  noExternal: ['lodash-es'],
  dts: true,
});

Monorepo Package

export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  external: [
    /^@mycompany\//, // Don't bundle other workspace packages
  ],
  dts: true,
});

CLI Tool (Bundle Everything)

export default defineConfig({
  entry: ['src/cli.ts'],
  format: ['esm'],
  platform: 'node',
  // Bundle all dependencies for standalone CLI
  noExternal: [/.*/],
  shims: true,
});

Library with Specific Externals

export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  external: ['vue', '@vue/runtime-core', '@vue/reactivity'],
  dts: true,
});

Declaration Files

Dependency handling for .d.ts files follows the same rules as JavaScript.

Complex Type Resolution

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 in @types/* packages with non-standard naming (e.g., @types/babel__generator)
  • Complex type dependencies
  • Issues with default Oxc resolver

Trade-off: tsc is slower but more compatible.

CLI Usage

External

tsdown --external react --external react-dom
tsdown --external '/^@myorg\/.*/'

No External

tsdown --no-external some-package

Examples by Use Case

Framework Component

// Don't bundle framework
export default defineConfig({
  external: ['vue', 'react', 'solid-js', 'svelte'],
});

Standalone App

// Bundle everything
export default defineConfig({
  noExternal: [/.*/],
  skipNodeModulesBundle: false,
});

Shared Library

// Bundle only specific utils
export default defineConfig({
  external: [/.*/], // External by default
  noExternal: ['tiny-utils'], // Except this one
});

Monorepo Package

// External workspace packages, bundle utilities
export default defineConfig({
  external: [
    /^@workspace\//, // Other workspace packages
    'react',
    'react-dom',
  ],
  noExternal: [
    'lodash-es', // Bundle utility libraries
  ],
});

Troubleshooting

Dependency Bundled Unexpectedly

Check if it's in devDependencies and imported. Move to dependencies:

{
  "dependencies": {
    "should-be-external": "^1.0.0"
  }
}

Or explicitly externalize:

export default defineConfig({
  external: ['should-be-external'],
});

Missing Dependency at Runtime

Ensure it's in dependencies or peerDependencies:

{
  "dependencies": {
    "needed-package": "^1.0.0"
  }
}

Or bundle it:

export default defineConfig({
  noExternal: ['needed-package'],
});

Type Resolution Errors

Use TypeScript resolver for complex types:

export default defineConfig({
  dts: {
    resolver: 'tsc',
  },
});

Summary

Default behavior:

  • dependencies & peerDependencies → External
  • devDependencies & phantom deps → Bundled if imported

Override:

  • external → Force external
  • noExternal → Force bundled
  • skipNodeModulesBundle → Skip all node_modules

Declaration files:

  • Same bundling logic as JavaScript
  • Use resolver: 'tsc' for complex types

Tips

  1. Keep dependencies external for libraries
  2. Bundle everything for standalone CLIs
  3. Use regex patterns for namespaced packages
  4. Check bundle size to verify external/bundled split
  5. Test with fresh install to catch missing dependencies
  6. Use tsc resolver only when needed (slower)