ScriptsApr 14, 2026·3 min read

tsup — Bundle Your TypeScript Library with Zero Config

tsup is the zero-config TypeScript bundler built on esbuild. It emits ESM, CJS, IIFE, and DTS files from a single command — the fastest way to ship a polished TypeScript package without writing Rollup config.

Introduction

tsup makes shipping TypeScript libraries almost too easy. Run one command and you get CJS + ESM bundles, .d.ts type declarations, source maps, and a watch mode — without writing Rollup config, tsc invocation, or a custom build script. It's built on esbuild, so builds finish in milliseconds.

With over 11,000 GitHub stars, tsup is the go-to library bundler for the TypeScript ecosystem. It powers tRPC, antfu's packages, and thousands of npm libraries.

What tsup Does

tsup takes entry files, bundles them with esbuild, and optionally generates .d.ts via the TypeScript compiler (or rollup-plugin-dts for speed). It handles multiple output formats, code splitting, minification, source maps, tree shaking, and watch mode — all configurable by CLI flags or a tsup.config.ts file.

Architecture Overview

package source (src/*.ts)
        |
  [tsup CLI]
        |
  +-------+-------+-------+
  |       |       |       |
 [esbuild] [DTS]  [Watcher] [Publish hints]
   bundle   tsc-based      (--watch mode)
   + tree-shake  or rollup-plugin-dts
        |
  dist/
    index.js      (CJS)
    index.mjs     (ESM)
    index.d.ts    (types)
    *.map         (source maps)

Self-Hosting & Configuration

// tsup.config.ts
import { defineConfig } from "tsup";

export default defineConfig({
  entry: ["src/index.ts", "src/cli.ts"],
  format: ["cjs", "esm"],
  dts: true,
  splitting: true,
  sourcemap: true,
  clean: true,
  treeshake: true,
  minify: false,
  target: "node18",
  external: ["react"],
  banner: { js: "#!/usr/bin/env node" },   // for CLI entries
  onSuccess: "node dist/cli.js --smoke",
});

Key Features

  • Zero config — sensible defaults for TypeScript libraries
  • Multiple formats — ESM, CJS, IIFE in a single run
  • Type declarations--dts emits .d.ts alongside the bundle
  • esbuild speed — sub-second builds for most libraries
  • Watch mode — incremental rebuilds for development
  • Code splitting — share chunks across entries
  • Tree shaking — remove unused exports
  • CLI or config file — flags for quick use, tsup.config.ts for projects

Comparison with Similar Tools

Feature tsup unbuild tsdx vite (lib mode) Rollup
Config complexity Very Low Low Low Low High
Speed Very Fast Fast Slow (tsc) Fast Moderate
DTS Yes (--dts) Yes Yes Plugin needed Plugin needed
Multi-format Yes Yes Yes Yes Yes (manual)
Tree shaking Good Good Good Excellent Excellent
Best For Any TS lib UnJS / Nuxt-style Legacy React libs Vue/React libs Complex control

FAQ

Q: tsup vs Rollup — do I ever pick Rollup? A: Pick Rollup when you need precise control over chunking, advanced plugins, or maximum tree-shaking. For 95% of TypeScript libraries, tsup produces equivalent output with much less config.

Q: tsup vs unbuild? A: Both zero-config. unbuild is from UnJS (Nitro/Nuxt), uses Rollup under the hood, and has stricter stub/shim behavior. tsup uses esbuild and tends to build faster. Functionally similar for most libraries.

Q: Does tsup emit correct DTS for complex generics? A: --dts runs the TypeScript compiler (tsc) — it emits whatever your tsc would. --dts-resolve uses rollup-plugin-dts which is faster but stricter.

Q: Can I build a CLI with tsup? A: Yes. Add banner: { js: "#!/usr/bin/env node" } and configure a binary in package.json. tsup handles shebangs, externals, and watch-restart for CLI dev.

Sources

Discussion

Sign in to join the discussion.
No comments yet. Be the first to share your thoughts.

Related Assets