tsdown: a library bundler built on Rolldown and Oxc
The elegant bundler for libraries powered by Rolldown
At a glance
- What is it?
- tsdown is a TypeScript library bundler that preconfigures Rolldown, Oxc and declaration file generation, and keeps tsup's main options. It is aimed at package authors, and its Node engine floor is the first thing to check.
- Who is it for?
- Adopt tsdown if you publish a TypeScript library on Node 22.18.0 or newer and you want declaration files and a tsup-shaped config without assembling a plugin chain. Do not adopt it if you are on an older Node runtime, if you need a documented rollback path from v0.23, or if you need a stable release line rather than pre-1.0 semver.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What tsdown bundles that tsc does not
A TypeScript library has two output problems, and tsc only solves one. It emits JavaScript and declaration files, but it emits them module by module, so the published package mirrors your source tree. tsdown takes the other approach: it treats the package as a bundling target. The README describes it as "the elegant bundler for libraries powered by Rolldown", and the package.json description is shorter still, "The Elegant Bundler for Libraries".
The audience is narrow and specific. This is for people who publish packages to npm and care about what the tarball contains: the entry points, the declaration files, and how many files a consumer's bundler has to walk. It is not a general application bundler, and nothing in the README positions it that way. The repository topics list bundler, library, oxc, rolldown and typescript, which is a fair summary of the scope.
The reason to care about Rolldown and Oxc specifically is the pipeline. Oxc handles the parsing and transformation work, Rolldown handles the bundling, and tsdown sits above both as configuration and orchestration. Declaration generation is part of that same pipeline rather than a separate tsc pass, which is the difference that shows up in build time for a project with many modules.
How the Rolldown and Oxc pipeline is wired
The mechanism is visible in the repository layout. There is a src/ directory, a packages/ directory, and a tsdown.config.ts at the root of the project itself, so tsdown builds tsdown. That is a useful signal about whether the tool is usable on a real package, though it says nothing about how fast it is.
The published entry points are the part that matters for integration. The package.json exports map has six subpaths: the root, ./config, ./internal, ./plugins, ./run and ./package.json, plus a ./client entry that resolves to client.d.ts. Each one has a dev condition pointing at TypeScript source and a default condition pointing at a built .mjs file. In publishConfig, the dev conditions are stripped and only the dist paths remain. That means the package you install is not the package the maintainers run.
The ./plugins subpath is where the ecosystem claim lives. The README states support for Rollup, Rolldown and unplugin plugins, plus some Vite plugins. That is a compatibility surface, not a guarantee: the word "some" in the README is doing real work, and a Vite plugin that depends on Vite-specific hooks is the kind of thing that would fall outside it. The ./config subpath is the programmatic config API, and ./run is the CLI entry, which the bin field points at.
One detail that is easy to miss: the package.json declares sideEffects for ./dist/run.mjs and ./tests/**. The run entry is marked as having side effects because it is the CLI. If you import the root entry in a consumer's build, tree shaking is not blocked by that, but a bundler reading the manifest will keep run.mjs if it is reachable.
Installing tsdown and running a first build
The README gives two commands and nothing else. Install as a dev dependency, then run the CLI with npx.
npm i -D tsdownnpx tsdownThere is no init command in the README and no config file is required to get a first run. Because the repository ships a tsdown.config.ts at its own root, a config file at that path is the convention the project itself follows, but the README does not document its keys. For anything beyond the defaults, the README points at tsdown.dev, and that is where the option reference lives.
A StackBlitz starter is linked from the README badges, so the fastest way to see a working setup without installing anything locally is to open that template rather than guess at a config.
The engines field is the constraint to read before you install. It reads:
"engines": {
"node": "^22.18.0 || ^24.11.0 || >=26.0.0"
}That is not a soft warning range. It excludes Node 20 entirely, and it excludes 22.x versions below 22.18.0 and 24.x versions below 24.11.0. If your CI matrix pins an older LTS, the install will not match the declared support, and you should fix the runtime before you debug anything else.
The tsup migration claim and where it stops
The README lists "Seamless migration" as a feature and says tsdown is "Compatible with tsup's main options and features". Read that sentence carefully. It says main options, which is a claim about the common configuration surface, not about every option tsup has accumulated.
In practice this is the strongest argument for the project. tsup users have configs they do not want to rewrite, and a bundler that accepts the same option names lowers the cost of trying it. The risk is the same as any compatibility promise: the options that are not in the "main" set are the ones you discover by running a build and finding the output differs. The README does not publish a list of unsupported tsup options, so the only way to know is to run your own config through both and diff the output.
There is also a versioning question underneath the migration story. The latest release is v0.23.0, published on 2026-09-03, with v0.23.0-rc.1 and v0.23.0-rc.0 before it in August. The project is pre-1.0. Pre-1.0 semver permits breaking changes in minor releases, so a tsup migration today is a migration onto a moving target. The release notes are the place to check what a given minor changed; the README does not carry a changelog.
Where tsdown is the wrong tool
The clearest boundary is the runtime floor. Node 22.18.0, 24.11.0 or 26.0.0 and above. If you maintain a library that still supports Node 18 or Node 20 consumers, that is a statement about the consumer's runtime, not yours, and a bundler running on your machine does not change it. But if your build environment is pinned to an older Node for other reasons, tsdown will not fit without changing that environment first.
The second boundary is the maturity of the release line. v0.23.0 is a pre-1.0 minor. A team that needs a stable config surface across a long support window is taking on upgrade work that a 1.x tool would not impose. That is a real cost, and it is not offset by the migration compatibility, because compatibility with tsup's options does not imply stability of tsdown's own.
The third is scope. tsdown bundles libraries. If you are building an application with code splitting, HTML entry points and a dev server, this is not that tool, and the README makes no claim that it is. The Vite plugin compatibility is a plugin-loading convenience, not an indication that tsdown is a Vite replacement.
Finally, there is the question of what happens when a build goes wrong. The README documents installation and usage and links to tsdown.dev for the rest. It does not document a rollback procedure, and the repository has no CHANGELOG file at the top level. If your process requires a documented revert path before you adopt a build tool, that path is not in the README.
tsdown against tsc, tsup and Vite
The honest comparison is with tsc, because that is what most library authors start with. tsc type-checks and emits per-file output. tsdown bundles, and it generates declarations as part of the same run. If your package has a single entry and a handful of files, the difference is small and tsc's predictability may be worth more to you. If your package has several entry points and a deep module graph, bundling changes what lands in the tarball, and declaration generation stops being a second command you have to keep in sync.
Against tsup, the difference is the engine. tsup is the tool tsdown is explicitly compatible with, and the README frames that as a migration path. The underlying bundler and transformer are where the two diverge, and that is what the compatibility layer is insulating you from. If your tsup config is simple, the migration is mostly a dependency swap. If it is not, expect to verify output rather than assume it.
Against Vite, the difference is the target. Vite is built around applications and a dev server. tsdown is built around producing a package. The overlap is that tsdown can load some Vite plugins, which is useful when a plugin you already depend on does a transform you need. It does not make the two interchangeable, and treating the plugin support as evidence of equivalence would be a misreading of the README.
Against Rolldown directly, tsdown is a layer on top. If you want to configure Rolldown yourself, you can, and you get control that tsdown's defaults take away. What you lose is the preconfiguration the README leads with, and you would be writing the declaration pipeline yourself.
Licence and the cost of staying current
tsdown is MIT licensed, per the LICENSE file and the license field in package.json. MIT is permissive: it allows use, modification and redistribution with the licence text retained. It does not impose copyleft obligations on your package. That is a statement about the licence text, not legal advice, and if your organisation has a policy review for build tooling, the MIT identifier is the input to that review.
The upgrade cost is the part that deserves more attention than it usually gets. The release cadence visible here is three releases in a month: v0.23.0-rc.0 on 2026-08-12, v0.23.0-rc.1 on 2026-08-28, and v0.23.0 on 2026-09-03. The last push to the repository was on 2026-09-22. That is a project moving quickly on a pre-1.0 line, which means minor versions can change behaviour. Pinning an exact version in your lockfile is the mechanism that keeps your build reproducible, and it is the only mechanism the repository files describe.
There is no CHANGELOG at the repository root, so the release notes attached to each tag are the record of what changed. Reading them before bumping is the upgrade procedure the project makes available. The repository also carries AGENTS.md and CLAUDE.md at the top level, which suggests the maintainers run coding agents against the codebase, though the README says nothing about what those files direct.
Editorial conclusion
Adopt tsdown if you publish a TypeScript library on Node 22.18.0 or newer and you want declaration files and a tsup-shaped config without assembling a plugin chain. Do not adopt it if you are on an older Node runtime, if you need a documented rollback path from v0.23, or if you need a stable release line rather than pre-1.0 semver. Verify three things before committing: that your CI runs a Node version the engines field allows, that your existing tsup config keys still behave as you expect, and that the .d.ts output matches what your package.json exports map promises.
Frequently asked questions
What is tsdown?
tsdown is a bundler for libraries, powered by Rolldown and Oxc, that also generates declaration files as part of the build. Its package.json describes it as "The Elegant Bundler for Libraries", and the README says it preconfigures what you need so you can focus on writing code.
How do I use tsdown?
Install it as a dev dependency with npm i -D tsdown, then run npx tsdown. The README shows no other required step, and full documentation is at tsdown.dev.
Is tsdown production ready?
The latest release is v0.23.0, so the project is on a pre-1.0 version line where minor releases can carry breaking changes. The README does not make a stability claim, and there is no CHANGELOG at the repository root; the release notes for each tag are the record of what changed.
What is the difference between tsdown and tsup?
The README lists "Compatible with tsup's main options and features" as a feature and describes migration as smooth, so the option surface is deliberately similar. The difference is the engine underneath: tsdown builds on Rolldown and Oxc, and the README does not publish a list of tsup options it does not support.
What is the difference between tsdown and Rollup?
The README states that tsdown supports Rollup plugins, so Rollup is treated as a plugin source rather than a rival bundler. tsdown itself is powered by Rolldown and Oxc, and the README does not compare the two bundlers directly.
What is the difference between tsdown and tsx?
The README does not mention tsx, so there is no documented comparison to draw on. What the README does say is that tsdown bundles libraries and generates declaration files, which is a build-time task rather than a runtime execution concern.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/rolldown-tsdown)