Skip to content

Migrate build setup from tsup to tsdown - #766

Open
veksa wants to merge 3 commits into
reduxjs:masterfrom
veksa:feature/build-tsdown
Open

Migrate build setup from tsup to tsdown#766
veksa wants to merge 3 commits into
reduxjs:masterfrom
veksa:feature/build-tsdown

Conversation

@veksa

@veksa veksa commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Closes #757.

This swaps the build over from tsup to tsdown. I kept it deliberately boring: the goal was to change the tool, not the output, and the dist tree that comes out the other side is identical to what tsup produced — same file names, same formats, same entry points — so there's nothing here that consumers would ever notice. The reason to bother now is TypeScript 7. The native compiler is nearly here, the current setup is going to need replacing regardless, and tsdown (through rolldown-plugin-dts) is the piece that generates our types cleanly under it.

Most of the config carried straight over, since tsdown reads a lot like tsup — entry, format, platform, env, target, minify and sourcemap all behave the same. Three things actually needed thought. outExtension is outExtensions now, and it can drive the .d.ts extension as well as the .js one, which turned out to matter for the second thing: tsdown has no dts: { only: true } mode, so rather than a standalone declaration pass I let the types come out alongside the modern ESM build and used outExtensions to force .d.ts instead of .d.mts, so the file still lands at dist/reselect.d.ts exactly where package.json expects it. The third was cleaning — tsdown wipes the output dir on every build by default, which in a multi-config setup means each build clobbers the last, so only the first one cleans and the rest add to dist. The little onSuccess that writes the dist/cjs/index.js shim (the dev/prod require switch) is unchanged.

The rest is just the swap itself: tsup out of the dev deps and tsdown in, the build script repointed, and .eslintignore following the config rename.

For sanity I built it and diffed the output against the old tsup build — same twelve files, down to the .cjs/.mjs/.map split. The built CJS and ESM entries both import and expose the API, are-the-types-wrong comes back clean across node10, node16 (CJS and ESM) and bundler, and lint and the test suite pass untouched.

One thing didn't survive the move: CodeSandbox CI. Its build runner tops out at Node 20 (the node field in .codesandbox/ci.json only accepts a fixed set of versions on their side — 10 through 18 by the docs, 20 in practice), and rolldown's CLI builds its option schema at load time with styleText(["underline", "gray"], …). The array form of util.styleText only landed in Node 22.5, so on their runner it throws ERR_INVALID_ARG_VALUE before the build even starts — the whole thing is dead on arrival, with no version we're allowed to set that fixes it. Since we can't raise their Node and the tooling fundamentally needs a newer one, I dropped the .codesandbox/ci.json config rather than leave a check that can only ever fail. dinero.js hit the same wall with the same toolchain and did the same thing in dinerojs/dinero.js#818. Everything else — GitHub Actions (Node 22.x/24.x) and are-the-types-wrong — is unaffected.

@netlify

netlify Bot commented Jul 26, 2026

Copy link
Copy Markdown

Deploy Preview for reselect-docs canceled.

Name Link
🔨 Latest commit 3cfbe13
🔍 Latest deploy log https://app.netlify.com/projects/reselect-docs/deploys/6a670a42d786f700084dd8f1

@veksa
veksa force-pushed the feature/build-tsdown branch from 73b5368 to 515ad8c Compare July 27, 2026 07:25
@aryaemami59 aryaemami59 self-assigned this Jul 27, 2026
@veksa
veksa force-pushed the feature/build-tsdown branch from 515ad8c to 3cfbe13 Compare July 27, 2026 07:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

build: migrate build setup to tsdown

2 participants