SaaS stacks
Mara Lindqvist11 min read5 views

tsup vs unbuild vs bunchee: TypeScript package bundlers in 2026

Three zero-config bundlers for shipping a TypeScript package, measured against live registry and repository state on 28 September 2026. One carries a maintainer deprecation notice, one has not released in over a year, and one requires Node 22.12. Plus what Vercel's turborepo actually uses, which is not what the usual citation says.

Flat vector illustration: three separate build pipelines converging into a single published npm package containing a module file and a type declaration file, in moss green and charcoal on off-white.
Flat vector illustration: three separate build pipelines converging into a single published npm package containing a module file and a type declaration file, in moss green and charcoal on off-white.
On this page

Quick answer (September 2026). If you are starting a new TypeScript package today, bunchee logo bunchee is the only one of these three still shipping releases, and it wants Node 22.12.0 or newer. tsup logo tsup is still the most downloaded library bundler in the ecosystem by a wide margin, and its own README now tells you to leave. unbuild logo unbuild sits in between: no deprecation notice, but no release in over a year either. The interesting part is not which of the three wins. It is that all three belong to the same generation, and the generation is turning over.

We measured every number in this piece against live registry, repository and API state on 28 September 2026. Nothing here is copied from another comparison page.

The one thing that decides this for most people

Fetch the three READMEs and you get your answer before you get to any benchmark.

tsup's README opens with a warning box. The exact wording, as of 28 September 2026:

"This project is not actively maintained anymore. Please consider using tsdown instead."

That is the maintainer talking, on the default branch, with a link to a migration guide. It is not a community rumour and it is not an inference from commit gaps.

unbuild's README opens with a note instead, and the difference in register matters:

"We are experimenting with obuild as the next next-gen successor based on rolldown. If you mainly need faster build speeds and don't mind trying beta software, give it a try."

That is an invitation to try something new, explicitly labelled beta. It is not a deprecation. Anyone who flattens those two banners into "both are dead" is reading them carelessly.

bunchee's README has no banner of either kind. It describes what the tool does and gets on with it.

Release cadence, measured

Scroll to see more

tsupunbuildbunchee
Latest stable8.5.13.6.17.0.1
Published12 Nov 202515 Aug 20258 Aug 2026
Days ago (28 Sep 2026)31940850
Releases in trailing 365 days1022
Total versions ever204110199

unbuild has published nothing in a year. tsup has published once, and that release was an esbuild bump to fix a sourcemap bug. bunchee shipped twenty-two times, including a major version.

A trap in the GitHub data

Here is where a lazy check goes wrong, and it is worth carrying with you to any repository you evaluate.

GitHub's pushed_at field for tsup reads 23 September 2026. Five days before we measured. That looks like a live project.

It is not maintenance. Pull the branch list and every branch other than main is a bot: twenty branches, all of them dependabot/ or renovate/ prefixes bumping cross-spawn, nanoid, postcss, rollup and various GitHub Actions. pushed_at counts pushes to any branch, so an unattended Renovate schedule keeps it fresh forever on a project nobody is steering.

Read the default branch instead. tsup's last commit to main is a CI workflow rename on 5 May 2026. Its last commit that changed any code is 12 November 2025.

unbuild shows the same shape but with a real signal inside it: its last main commit is a CI digest bump on 11 March 2026, and its last substantive commit is a dependency update on 9 February 2026. Unlike tsup, though, its branch list contains genuine feature work, feat/isolated-decl and feat/fail-on-implicit-externals, alongside the bot noise. Somebody has been thinking about it, even if nothing has shipped.

bunchee's last commit is 18 August 2026, and its branches are work, not bots: rolldown, run-rolldown, fix/worker-directive-chunks.

All three are rollup underneath

The folk model in most threads is "tsup is the esbuild one, unbuild is the rollup one, bunchee is the swc one". That is wrong about at least one of them, and you can check it in the published manifests.

Scroll to see more

PackageEngine dependencies it actually ships
tsup 8.5.1esbuild, rollup, sucrase
unbuild 3.6.1rollup, esbuild, mkdist, rollup-plugin-dts
bunchee 7.0.1rollup, @swc/core, rollup-plugin-swc3, rollup-plugin-dts

tsup is "powered by esbuild" for your JavaScript, and it pulls rollup in anyway to produce the .d.ts files, because esbuild does not do type declarations. Every one of these three has a rollup dependency in its production tree. If your objection to a tool is "I do not want rollup in my lockfile", none of the three clears that bar.

This also explains why the Rust rewrite wave lands on all of them at once. tsdown, obuild and bunchee's rolldown branch are all attempts to swap that rollup core for Rolldown.

Weight and runtime requirements

Scroll to see more

tsupunbuildbunchee
Unpacked size389,734 B66,929 B233,833 B
Files in tarball1876
Direct dependencies172421
Node engines declared18 or newernone declared22.12.0 or newer

That last row is the most likely thing to stop you adopting bunchee today. bunchee 7 requires Node 22.12.0 or newer. If your CI is pinned to Node 20 LTS, version 7 will refuse to install.

There is a way out, and it is not "give up". bunchee 6.12.2, published 27 July 2026, still declares Node 18 or newer. That is a recent release on the older line, so a Node 20 project can adopt bunchee on 6.x today and move to 7 when it upgrades the runtime.

Worth noting for anyone eyeing the successor: tsdown 0.23.0 declares an unusually specific engine range: 22.18.0 and up within the 22 line, 24.11.0 and up within the 24 line, or anything from 26 onward. Read it carefully. It excludes Node 23 and 25 entirely, and it also excludes Node 24.0 through 24.10. A "modern Node" assumption is not enough there.

What Vercel actually does

This one is widely half-remembered, so we went and read it.

There is a real turborepo pull request, #9850, titled "chore: use bunchee instead of tsup", merged 3 February 2025. It is usually cited as "Vercel moved turborepo to bunchee". That overstates it in one direction and understates it in another.

Read the PR body and it scopes itself: bunchee "is an incredible bundler that automatically handles a bunch of the complexities of setting up Node.js packages. We want to encourage its usage so using it in the kitchen-sink example". That is an example, not turborepo's own build.

So we checked both halves of the repository on the default branch, on 28 September 2026:

  • The kitchen-sink example packages, ui and logger, build with bunchee 7.0.1. The current release. The 2025 change stuck.
  • turborepo's own published packages, turbo-gen, turbo-workspaces, eslint-plugin-turbo, create-turbo, turbo-codemod and turbo-ignore, build with tsdown 0.12.0.

Neither half uses tsup anymore. The honest summary is that Vercel teaches bunchee to users in its reference monorepo and uses tsdown for its own CLI packages. Both are post-tsup choices, and they are different choices for different jobs.

Adoption, and why the download numbers mislead

Downloads for the month ending 27 September 2026:

Scroll to see more

PackageDownloads
tsup31,279,614
tsdown18,784,237
unbuild1,025,067
bunchee185,222
obuild61,214

Taken alone, that table says tsup wins by 169x over bunchee and you should obviously use tsup. Taken with the deprecation notice, it says something quite different: roughly 31 million monthly installs are sitting on a bundler whose maintainer has asked them to move, and the named replacement is already at 60 percent of tsup's volume after a fraction of the time.

A large install base is a measure of where the ecosystem has been. It is not a measure of where it is going, and on a deprecated package the two point in opposite directions.

The issue backlogs line up with the same story. Counting genuine issues only, and excluding pull requests, which GitHub's open_issues_count silently folds in:

Scroll to see more

Open issuesOpen PRsStars
tsup3566911,301
unbuild48232,727
bunchee801,408

356 open issues against one release in a year is the arithmetic of a backlog that is not going to be worked.

The licence detail nobody checks

We read the licence out of each published tarball rather than trusting the registry's one-word license field, because that field cannot express a condition and cannot tell you whether any text actually ships.

  • tsup 8.5.1 ships LICENSE, 1,063 characters, stock MIT, "Copyright (c) 2021 EGOIST".
  • unbuild 3.6.1 ships LICENSE, 1,078 characters, stock MIT, "Copyright (c) Pooya Parsa".
  • bunchee 7.0.1 ships no licence file at all. Six files in the tarball, all of them dist output plus the README and manifest.

We probed the repository too, for LICENSE, LICENSE.md, LICENCE and license. All four return 404, and the repository root listing contains no licence file. bunchee's files field is ["dist", "*.md"], so there is nothing to ship because there is nothing in the repository.

Be careful how you read that, because the alarming version is not the honest one. bunchee's package.json declares "license": "MIT", unambiguously and deliberately. In npm practice that field is the licence grant, and the author's intent is not in any doubt. This is a paperwork gap, not a trap. But if your organisation runs a compliance scan that requires licence text rather than an SPDX identifier, bunchee is the one of the three that will flag, and you should know that before the audit rather than during it.

Related: GitHub's licence detector reports spdx_id: None for bunchee and MIT for the other two. That detector is unreliable enough in general that a None is usually worth re-checking by hand. Here the re-check confirmed it.

Stale dist-tags, a small thing worth a glance

Both of the older two carry dist-tags pointing below their own latest release. unbuild publishes an rc tag at 3.0.0-rc.11 while latest is 3.6.1. bunchee publishes next at 2.0.0-beta.5 while latest is 7.0.1.

Nothing breaks because of this, and npm install resolves latest regardless. It matters only if you have automation that installs from next or rc on the assumption that those track ahead of stable. On these packages they do not, and you would silently pin yourself several majors back.

So which one

Starting a new package, on Node 22.12 or newer: bunchee. It is the only one of the three under active development, its exports-driven config means there is usually nothing to configure, and it has an eight-issue backlog rather than a 356-issue one.

Starting a new package, pinned to Node 20: bunchee 6.12.2, then upgrade the line when you upgrade the runtime. Do not start on tsup in 2026 just because it installs on Node 18.

Already on tsup and shipping: do not panic, and do not migrate this week. A deprecated bundler does not stop working, your builds are reproducible from a lockfile, and tsup 8.5.1 is a stable artefact. But stop treating it as the default for new packages, and read the tsdown migration guide before your next major. tsdown is the maintainer's own recommendation and is the lowest-friction move from a tsup config.

Already on unbuild, inside the unjs ecosystem: stay for now. It is not deprecated, the mkdist bundleless mode has no clean equivalent in the other two, and obuild is the in-family path when it stabilises. Just be honest with yourself that zero releases in a year is a real signal, and set a date to re-check rather than drifting.

If you want the fewest moving parts: unbuild's tarball is 66,929 bytes across seven files, by far the smallest of the three. That is a genuine point in its favour and it is the one thing the release-cadence table does not capture.

The pattern underneath all of this is worth stating plainly. tsup, unbuild and bunchee are three takes on the same idea, wrapping rollup and an ES-syntax transpiler so you do not have to configure a library build by hand. That idea is intact. The layer under it is being rewritten in Rust, and each of the three responded differently: tsup handed off to a separate successor, unbuild started one alongside itself, and bunchee is attempting it in place on a branch. Choosing between them in 2026 is mostly choosing which of those three responses you want to be attached to.

We test these in the ShipGarden gallery as part of the stack we actually ship on. If you are publishing a package you will want documentation for it too, and we put the documentation frameworks through the same treatment.

Sources, all read live on 28 September 2026: tsup, unbuild and bunchee repositories and READMEs on their default branches; the npm registry documents and published tarballs for each package; the npm downloads API; the GitHub repositories, branches, commits and issue-search APIs; and turborepo pull request #9850, linked above, plus the current package.json of turborepo's own packages and its kitchen-sink example.

Mara Lindqvist

Written by

Mara Lindqvist

Mara Lindqvist curates the ShipGarden gallery, where we test open-source building blocks so we can own the stack that funds the life.

Frequently asked questions

Is tsup deprecated in 2026?

Yes, by its own maintainer. As of 28 September 2026 the tsup README on its default branch opens with a warning box reading "This project is not actively maintained anymore. Please consider using tsdown instead", with a link to a migration guide. It still works and version 8.5.1 is a stable artefact, so there is no emergency, but it should not be the default choice for a new package.

Is unbuild dead too?

No, and conflating the two is a misreading. unbuild carries no deprecation notice. What it carries is a note saying the unjs team is experimenting with obuild as a rolldown-based successor, explicitly described as beta software. That said, unbuild published its last release, 3.6.1, on 15 August 2025, and has shipped nothing in the trailing 365 days, so the low activity is real even though the deprecation is not.

Which of the three is actually being maintained?

bunchee. Measured on 28 September 2026 it had 22 releases in the trailing 365 days, the most recent being 7.0.1 on 8 August 2026, against one release for tsup and zero for unbuild. Its open-issue backlog is 8 issues and 0 pull requests, compared with 356 issues for tsup.

Can I use bunchee on Node 20?

Not version 7, which declares Node 22.12.0 or newer and will refuse to install. Use the 6.x line instead: bunchee 6.12.2 was published on 27 July 2026 and still declares Node 18 or newer, so it is a recent release that works on Node 20 LTS. Move to 7 when you upgrade the runtime.

Is it true that tsup uses esbuild and unbuild uses rollup?

Only half true, and it is a common mistake. Reading the published manifests, all three depend on rollup. tsup ships esbuild, rollup and sucrase, because esbuild cannot emit type declarations so rollup does the .d.ts work. unbuild ships rollup, esbuild, mkdist and rollup-plugin-dts. bunchee ships rollup, @swc/core, rollup-plugin-swc3 and rollup-plugin-dts. If your goal is to keep rollup out of your lockfile, none of the three does that.

Did Vercel move turborepo from tsup to bunchee?

Partly, and the usual citation overstates it. Pull request 9850, merged 3 February 2025, did swap tsup for bunchee, but its own body scopes the change to the kitchen-sink example. Checked on 28 September 2026, turborepo's kitchen-sink example packages build with bunchee 7.0.1 while turborepo's own published packages, including turbo-gen, turbo-workspaces and create-turbo, build with tsdown 0.12.0. Neither half uses tsup anymore.

SaaS stacks

Sonner vs react-hot-toast vs react-toastify for Next.js in 2026

Three React toast libraries whose reputations are all slightly wrong. Read from the npm registry, the published tarballs, the GitHub API and the live shadcn registry on 23 September 2026: the most downloaded one is the heaviest, the one with the steepest search decline shipped a release seven days ago, and the oldest has the best accessibility.

12 min read73