# tsdown v0.23.0
- Product: tsdown (https://whatsnew.fyi/product/tsdown)
- Vendor: tsdown
- Date: 2026-09-03
- Version: v0.23.0
- Original notes: https://github.com/rolldown/tsdown/releases/tag/v0.23.0
- Permalink: https://whatsnew.fyi/product/tsdown/releases/v0.23.0
What's New is an index, not a publisher: every entry below links to the vendor's own release notes, which are the authoritative source. Entries are labelled where they are hand-curated sample data, pre-releases, or drawn from a secondary source such as a developer blog.
Reuse: the summaries, labels and curation here are © What's New. Quote freely with attribution and a link back; wholesale republication of the corpus is not permitted — terms: https://whatsnew.fyi/terms. The vendors' own release notes remain their publishers'.
---
- **removed** — Drop support for Node.js 25; use ^22.18.0, ^24.11.0, or >=26.0.0
- **removed** — Remove deprecated tsup compatibility options
- **removed** — Drop types and typesVersions fields from package exports
- **removed** — Remove deprecated deps.onlyAllowBundle option
- **removed** — Remove deprecated skipNodeModulesBundle option
- **removed** — Remove dts.cjsReexport option; dual-format builds now generate CJS declarations in a separate pass
- **changed** — Make dts.generator the only way to select generator
- **changed** — Change attw default profile from strict to esm-only
- **changed** — Disable resolveDepSubpath by default
- **changed** — build() now returns { bundles, watch } instead of bundles
- **added** — Expose programmatic watch controls
- **added** — Support function form for css.modules.localsConvention
- **added** — Add summary option to report to skip per-file size logs
- **fixed** — Allow unplugin-unused v0.5+
- **fixed** — Ignore optional dependencies in type definitions
- **fixed** — Camel-case nested flag keys in CLI
- **fixed** — Watch files imported via @import in CSS
- **fixed** — Apply resolveDepSubpath when neverBundle is true
- **fixed** — Scope inlined dependencies to configs with exports
- **changed** — Remove asyncDispose polyfill for performance
###### 🧭 Migration Guide
Most users can upgrade directly. Before upgrading, run one final build with `tsdown@0.22.14` and resolve all deprecation warnings.
- **config**:
- `bundle: false` → `unbundle: true`; `bundle: true` can be removed
- `outExtension` → `outExtensions`
- `publicDir` / `--public-dir` → `copy` / `--copy`
- `removeNodeProtocol: true` → `nodeProtocol: 'strip'`
- `injectStyle` → `css.inject`
- **deps**:
- `inlineOnly` / `deps.onlyAllowBundle` → `deps.onlyBundle`
- `skipNodeModulesBundle: true` → `deps.neverBundle: true`
- `resolveDepSubpath` now defaults to `false`; set it to `true` to preserve the previous behavior
- **dts**:
- Select a generator with `dts.generator`, for example `{ generator: 'oxc' }`
- `dts.cjsReexport` was removed; dual-format builds now generate CJS declarations in a separate pass
- **attw**:
- The default profile changed from `strict` to `esm-only`; set `profile: 'strict'` to preserve the previous checks
- **programmatic API**:
- `build()` now returns `{ bundles, watch }`; replace `const bundles = await build()` with `const { bundles } = await build()`
- **requirements**:
- Node.js 25 is no longer supported; use `^22.18.0`, `^24.11.0`, or `>=26.0.0`
- The packages no longer publish legacy `types` and `typesVersions` fallbacks; use TypeScript’s `bundler`, `node16`, or `nodenext` module resolution
###### 🚨 Breaking Changes
- Drop support for Node.js 25 - by @sxzz [(26950)](https://github.com/rolldown/tsdown/commit/26950f1)
- Remove deprecated tsup compatibility options - by @sxzz [(50766)](https://github.com/rolldown/tsdown/commit/507661c)
- Drop `types` and `typesVersions`fields - by @sxzz [(be3ea)](https://github.com/rolldown/tsdown/commit/be3ea86)
- **attw**:
- Change default profile to `esm-only` - by @sxzz [(9b3cf)](https://github.com/rolldown/tsdown/commit/9b3cfca)
- **deps**:
- Remove deprecated `deps.onlyAllowBundle` - by @sxzz [(30c55)](https://github.com/rolldown/tsdown/commit/30c553d)
- Disable `resolveDepSubpath` by default - by @sxzz [(d300f)](https://github.com/rolldown/tsdown/commit/d300fcc)
- Remove deprecated `skipNodeModulesBundle` - by @sxzz [(f2a3d)](https://github.com/rolldown/tsdown/commit/f2a3d8e)
- **dts**:
- Remove dts.cjsReexport option - by @sxzz [(9c70f)](https://github.com/rolldown/tsdown/commit/9c70fa9)
- Make `dts.generator` the only way to select generator - by @sxzz [(eb75f)](https://github.com/rolldown/tsdown/commit/eb75f9d)
###### 🚀 Features
- Expose programmatic watch controls - by @sxzz in https://github.com/rolldown/tsdown/issues/1062 [(96a40)](https://github.com/rolldown/tsdown/commit/96a4098)
- **css**: Support function form for `css.modules.localsConvention` - by @sxzz and @lazerg [(b566f)](https://github.com/rolldown/tsdown/commit/b566f6d)
- **report**: Add `summary` option to skip per-file size logs - by @lazerg in https://github.com/rolldown/tsdown/issues/1036 [(020e9)](https://github.com/rolldown/tsdown/commit/020e9cd)
###### 🐞 Bug Fixes
- Allow `unplugin-unused` v0.5+ - by @sxzz [(53c78)](https://github.com/rolldown/tsdown/commit/53c78cb)
- Ignore optional dependencies in type definitions - by @sxzz [(94622)](https://github.com/rolldown/tsdown/commit/946224d)
- **cli**:
- Camel-case nested flag keys - by @sxzz [(bf53f)](https://github.com/rolldown/tsdown/commit/bf53f43)
- **css**:
- Watch files imported via `@import` - by @lazerg in https://github.com/rolldown/tsdown/issues/1038 [(eb
_[Truncated at 4000 characters — full notes: https://github.com/rolldown/tsdown/releases/tag/v0.23.0]_