mrkeyoor.com_
Sun 20 Sept 07:00 UTC
npmCLI & Toolingupdated 20 Sept 2026

rolldown review

Rolldown 1.2.6 is a Rust-based JavaScript and TypeScript bundler exposed through a Node CLI, config files, a Rollup-shaped build API, watch mode, code splitting, transforms, minification, and plugins. It is intended for Vite's future bundling path and aims at a broader job than a strict Rollup reimplementation. The current release adds property-name mangling, a `tsconfig` option to `transform`, top-level tsconfig handling in Vite resolution, and development module-graph queries, plus several dev-engine and code-splitting fixes. Our measured 1.2.5 install used 21 MB because platform-native code is part of the toolchain, and its browser bundle failed. This belongs in Node build tooling, not application runtime code.

68.7Mdownloads / wk
Verdict

Our rolldown 1.2.5 install took 1.6 seconds, occupied 21 MB across 4 packages, produced 0 audit findings, and could not be bundled for the browser. Test current 1.2.6 in Node build pipelines where Rollup-shaped APIs and native performance matter, but keep the old bundler available until plugin and output fixtures match.

We installed it

Lab card: what happened when we installed rolldownScreenshot of rolldown documentation
Install✓ · 1.6s4 packages on disk · 21 MB
ImportESM import works · require() works · ESM package with exports map
Browsern/acould not be bundled for the browser (Node-only code, most likely)
TypesTypeScript types bundled
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does rolldown install cleanly?

Yes. In a fresh container with an empty cache, npm install rolldown finished in 2 seconds, leaving 4 packages and 21 MB on disk. npm audit reported no known vulnerabilities.

Can rolldown run in a browser?

Not directly: esbuild could not bundle it for the browser in our run, which normally means it depends on Node built-ins. Use it on the server, or find a browser-targeted alternative.

Does rolldown work with both ESM and CommonJS?

Yes. Both import 'rolldown' and require('rolldown') worked in Node 22 in our run. The package is published as ESM with an exports map.

Does rolldown include TypeScript types?

Yes, type declarations ship inside the package, so no @types install is needed.

rolldown or rollup: which should you use?

rollup: Choose it when its mature plugin behavior and established library-bundling semantics outweigh a native speed experiment. Our rolldown 1.2.5 install took 1.6 seconds, occupied 21 MB across 4 packages, produced 0 audit findings, and could not be bundled for the browser.

When should you not use rolldown?

Your Node runtime is below 20.19 or between unsupported 21.x releases. Version 1.2.6 requires ^20.19.0 || >=22.12.0.

API stability3/5The top-level `rolldown`, `watch`, `defineConfig`, inputs, outputs, plugins, externals, and Rollup-shaped lifecycle make migration approachable. Version 1.x is shipping weekly features and fixes across code splitting, the dev engine, transforms, resolution, watchers, bindings, and minification. The project also states that its scope will move closer to esbuild than strict Rollup equivalence. Pin exact versions for production builds, because small output or plugin differences can change deployed artifacts even when the config type still compiles.
Docs4/5The hosted site has getting-started material, CLI and config instructions, input and output options, plugin guides, Rollup compatibility notes, migration guidance, code splitting, transforms, watch mode, troubleshooting, and a generated option reference. Release notes enumerate every 1.2.6 feature and fix with pull-request links. The difficult gaps concern behavior at the compatibility boundary: users still need fixtures to determine whether a particular Rollup plugin, sourcemap, CommonJS edge, or chunk graph matches their existing build.
Maintenance5/5The unarchived repository was pushed on 2026-08-26, reports 399 open issues and pull requests, and has 13,911 stars. Version 1.2.6 shipped the same day with property mangling, tsconfig support, development graph APIs, several dev-runtime corrections, code-splitting validation, watcher work, cache cleanup, performance changes, and an Oxc upgrade. The 399-item queue reflects a young, fast-moving compiler project rather than neglect, but it also means adopters should expect frequent patch releases and regressions around unusual graphs.
Ecosystem4/5The npm downloads endpoint counted 87,852,340 downloads in the latest week. Rolldown connects to Vite's future direction, speaks a familiar Rollup-like API, provides typed config helpers and programmatic output, and draws on Oxc, napi-rs, Rollup, and esbuild work. Our Node checks loaded both module styles and npm audit found no issues. The ecosystem is still transitional: plugin compatibility needs testing, native binaries expand installation concerns, and existing Rollup, webpack, and esbuild pipelines have more years of production edge cases behind them.

Discussed on

  1. hnRolldown: Rollup compatible bundler written in Rust186 points
  2. hnRolldown-Vite: a Rust-Rewrite of Rollup23 points
  3. hnVoidZero Announces Rolldown 1.09 points
  4. hnRolldown-Vite4 points
  5. hnVitejs team is working on a new bundler: rolldown4 points

Use it if

  • A project wants Rollup-shaped configuration and plugins while testing the Rust bundler that Vite is adopting.
  • Build speed on a large JavaScript or TypeScript graph matters enough to benchmark a native tool against the current Rollup or esbuild pipeline.
  • You need code splitting, tree shaking, transforms, watch mode, library formats, and programmatic generation in one Node bundler.
  • The team can run compatibility fixtures for every plugin, output format, sourcemap, and edge-case module before switching production builds.
Skip it if

Setup reality

We installed rolldown 1.2.5 in a clean Node 22 Bookworm container. npm finished in 1.6 seconds and left 4 packages using 21 MB on disk. npm audit found 0 vulnerabilities at critical, high, moderate, and low severities. The package declares 2 direct dependencies and 0 peers and is 960 KB unpacked before its platform binding is considered. It requires Node ^20.19.0 || >=22.12.0, includes TypeScript declarations, uses ESM with an exports map, and passed our require() and ESM import probes.

No credential is needed. Put repeatable builds in rolldown.config.*, choose one or more inputs, and send multiple chunks to output.dir. The cleanDir option removes existing output, so it must point at a dedicated generated directory. TypeScript parsing does not check types or write declaration files. Version 1.2.6 adds tsconfig routing and transform support, but a separate type-check remains part of CI.

Our attempt to bundle rolldown itself for a browser with esbuild failed, which is expected for native Node build tooling. The 21 MB installed footprint includes the selected native binding; unsupported platforms may use different packages or fail during loading. Cache npm artifacts per platform and architecture rather than copying one node_modules tree between machines. Close programmatic bundles and watchers so native handles and plugin resources are released.

Rollup compatibility should be proven with output snapshots, plugin integration tests, sourcemap checks, and runtime tests for every format you publish. Externalized packages remain imports and must exist for users at runtime. Manual chunk groups can worsen caching when they produce one oversized vendor file. Property-name mangling in 1.2.6 can break reflective access, serialized keys, or public APIs unless names are reserved carefully. Watch mode and the development engine are long-running processes, so close them on signals and surface rebuild errors instead of treating one successful startup as proof.

Patterns

Bundle one TypeScript entry bundle-from-cli

npx rolldown src/main.ts --file dist/app.js --format esm --sourcemap

This transforms TypeScript syntax and writes JavaScript. It does not run the type checker or emit declaration files.

Define a repeatable browser build configure-build

import { defineConfig } from 'rolldown';

export default defineConfig({
  input: 'src/main.ts',
  platform: 'browser',
  output: {
    dir: 'dist',
    format: 'esm',
    sourcemap: true,
    cleanDir: true,
  },
});

Run with `rolldown -c`. `cleanDir` deletes existing contents, so reserve the directory for generated files.

Name two entry chunks bundle-multiple-entries

export default defineConfig({
  input: { app: 'src/app.ts', worker: 'src/worker.ts' },
  output: {
    dir: 'dist',
    entryFileNames: '[name]-[hash].js',
    chunkFileNames: 'chunks/[name]-[hash].js',
  },
});

Shared dependencies and dynamic imports can add chunks, which is why this build uses `output.dir` instead of one file.

Write output through the Node API bundle-programmatically

import { rolldown } from 'rolldown';

const bundle = await rolldown({ input: 'src/main.ts' });
try {
  await bundle.write({ file: 'dist/app.mjs', format: 'esm' });
} finally {
  await bundle.close();
}

Close the bundle to release native and plugin resources. Use `generate()` when files should stay in memory.

Generate ESM and CommonJS in memory generate-two-formats

const bundle = await rolldown({ input: 'src/index.ts' });
try {
  const esm = await bundle.generate({ format: 'esm' });
  const cjs = await bundle.generate({ format: 'cjs' });
  inspect(esm.output, cjs.output);
} finally {
  await bundle.close();
}

`generate()` does not write to disk. Exercise both formats because interop behavior can diverge.

Keep runtime packages out of a library bundle externalize-dependencies

const dependencies = new Set(['react', 'react-dom']);

export default defineConfig({
  input: 'src/index.ts',
  external(id) {
    return [...dependencies].some(name => id === name || id.startsWith(`${name}/`));
  },
  output: { file: 'dist/index.mjs', format: 'esm' },
});

External imports remain in the artifact. Consumers must install them, and subpath imports need to match the predicate.

Use a project tsconfig apply-tsconfig

export default defineConfig({
  input: 'src/main.ts',
  tsconfig: './tsconfig.json',
  transform: { target: 'es2020' },
  output: { dir: 'dist' },
});

Version 1.2.6 expands tsconfig support. Resolution and transforms can use it, but no TypeScript type check runs.

Replace build-time globals define-constants

export default defineConfig({
  input: 'src/main.ts',
  transform: {
    define: {
      IS_PROD: 'true',
      'process.env.NODE_ENV': '"production"',
    },
  },
  output: { dir: 'dist' },
});

Definitions are code expressions. A string value needs quotes inside the replacement text.

Provide a virtual module write-plugin

const buildInfo = {
  name: 'build-info',
  resolveId(id) {
    if (id === 'virtual:build-info') return '\0virtual:build-info';
  },
  load(id) {
    if (id === '\0virtual:build-info') return 'export const channel = "stable";';
  },
};

The zero byte marks an internal ID. Test reused Rollup plugins because hook compatibility is broad but not absolute.

Group node_modules into a chunk split-vendor-chunk

export default defineConfig({
  input: 'src/main.ts',
  output: {
    dir: 'dist',
    codeSplitting: {
      groups: [{ name: 'vendor', test: /node_modules/ }],
    },
  },
});

Inspect the emitted graph. One vendor group can create a large file with worse cache invalidation than automatic splitting.

Close a watcher on interruption watch-files

import { watch } from 'rolldown';

const watcher = watch({ input: 'src/main.ts', output: { dir: 'dist' } });
watcher.on('event', event => {
  if (event.code === 'ERROR') console.error(event.error);
});
process.once('SIGINT', async () => {
  await watcher.close();
});

Watcher shutdown is asynchronous. Await it so native handles and pending plugin work can settle before exit.

Build a CommonJS Node command target-node

export default defineConfig({
  input: 'src/cli.ts',
  platform: 'node',
  external: [/^node:/],
  output: {
    file: 'dist/cli.cjs',
    format: 'cjs',
    sourcemap: true,
  },
});

The Node platform changes resolution defaults. Keep built-ins external and decide which package dependencies remain runtime imports.

Alternatives

PackageRegistryPick it when
rollupnpmChoose it when its mature plugin behavior and established library-bundling semantics outweigh a native speed experiment.
esbuildnpmChoose it for a mature fast native bundler and transformer with a smaller Rollup-compatibility goal.
vitenpmChoose it for a full development server and application build workflow rather than operating the bundler directly.
rspacknpmChoose it when webpack compatibility, loaders, and plugin migration are the primary constraints.

More cli & tooling guides

commander · chalk · typescript · esbuild · yargs · click · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.