Files
agent-skills/skills/tsdown/references/option-unbundle.md
Jason Woltje f5792c40be feat: Complete fleet — 94 skills across 10+ domains
Pulled ALL skills from 15 source repositories:
- anthropics/skills: 16 (docs, design, MCP, testing)
- obra/superpowers: 14 (TDD, debugging, agents, planning)
- coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth)
- better-auth/skills: 5 (auth patterns)
- vercel-labs/agent-skills: 5 (React, design, Vercel)
- antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo)
- Plus 13 individual skills from various repos

Mosaic Stack is not limited to coding — the Orchestrator and
subagents serve coding, business, design, marketing, writing,
logistics, analysis, and more.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:27:42 -06:00

5.5 KiB

Unbundle Mode

Preserve source directory structure in output.

Overview

Unbundle mode (also called "bundleless" or "transpile-only") outputs files that mirror your source structure, rather than bundling everything into single files. Each source file is compiled individually with a one-to-one mapping.

Basic Usage

CLI

tsdown --unbundle

Config File

export default defineConfig({
  entry: ['src/**/*.ts', '!**/*.test.ts'],
  unbundle: true,
})

How It Works

Source Structure

src/
├── index.ts
├── utils/
│   ├── helper.ts
│   └── format.ts
└── components/
    └── button.ts

With Unbundle

Config:

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

Output:

dist/
├── index.mjs
├── utils/
│   ├── helper.mjs
│   └── format.mjs
└── components/
    └── button.mjs

All imported files are output individually, preserving structure.

Without Unbundle (Default)

Output:

dist/
└── index.mjs  (all code bundled together)

When to Use

Use Unbundle When:

Building monorepo packages with shared utilities Users need to import individual modules Want clear source-to-output mapping Library with many independent utilities Debugging requires tracing specific files Incremental builds for faster development

Use Standard Bundling When:

Single entry point application Want to optimize bundle size Need aggressive tree shaking Creating IIFE/UMD bundles Deploying to browsers directly

Common Patterns

Utility Library

export default defineConfig({
  entry: ['src/**/*.ts', '!**/*.test.ts'],
  format: ['esm', 'cjs'],
  unbundle: true,
  dts: true,
})

Benefits:

  • Users import only what they need
  • Tree shaking still works at user's build
  • Clear module boundaries

Usage:

// Users can import specific utilities
import { helper } from 'my-lib/utils/helper'
import { Button } from 'my-lib/components/button'

Monorepo Shared Package

export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm'],
  unbundle: true,
  outDir: 'dist',
})

TypeScript Compilation Only

export default defineConfig({
  entry: ['src/**/*.ts'],
  format: ['esm'],
  unbundle: true,
  minify: false,
  treeshake: false,
  dts: true,
})

Pure TypeScript to JavaScript transformation.

Development Mode

export default defineConfig((options) => ({
  entry: ['src/**/*.ts'],
  unbundle: options.watch,  // Unbundle in dev only
  minify: !options.watch,
}))

Fast rebuilds during development, optimized for production.

With Entry Patterns

Include/Exclude

export default defineConfig({
  entry: [
    'src/**/*.ts',
    '!**/*.test.ts',
    '!**/*.spec.ts',
    '!**/fixtures/**',
  ],
  unbundle: true,
})

Multiple Entry Points

export default defineConfig({
  entry: {
    index: 'src/index.ts',
    cli: 'src/cli.ts',
  },
  unbundle: true,
})

Both entry files and all imports preserved.

Output Control

Custom Extension

export default defineConfig({
  entry: ['src/**/*.ts'],
  unbundle: true,
  outExtensions: () => ({ js: '.js' }),
})

Preserve Directory

export default defineConfig({
  entry: ['src/**/*.ts'],
  unbundle: true,
  outDir: 'lib',
})

Output:

lib/
├── index.js
├── utils/
│   └── helper.js
└── components/
    └── button.js

Package.json Setup

{
  "name": "my-library",
  "type": "module",
  "main": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": "./dist/index.js",
    "./utils/*": "./dist/utils/*.js",
    "./components/*": "./dist/components/*.js"
  },
  "files": ["dist"]
}

Or use exports: true to auto-generate.

Comparison

Feature Bundled Unbundled
Output files Few Many
File size Smaller Larger
Build speed Slower Faster
Tree shaking Build time User's build
Source mapping Complex Simple
Module imports Entry only Any module
Dev rebuilds Slower Faster

Performance

Build Speed

Unbundle is typically faster:

  • No bundling overhead
  • Parallel file processing
  • Incremental builds possible

Bundle Size

Unbundle produces larger output:

  • Each file has its own overhead
  • No cross-module optimizations
  • User's bundler handles final optimization

Tips

  1. Use with glob patterns for multiple files
  2. Enable in development for faster rebuilds
  3. Let users bundle for production optimization
  4. Preserve structure for utilities/components
  5. Combine with DTS for type definitions
  6. Use with monorepos for shared code

Troubleshooting

Too Many Files

  • Adjust entry patterns
  • Exclude unnecessary files
  • Use specific entry points

Missing Files

  • Check entry patterns
  • Verify files are imported
  • Look for excluded patterns

Import Paths Wrong

  • Check relative paths
  • Verify output structure
  • Update package.json exports

CLI Examples

# Enable unbundle
tsdown --unbundle

# With specific entry
tsdown src/**/*.ts --unbundle

# With other options
tsdown --unbundle --format esm --dts