Skip to content

jsxtools/rolldown-transform

Repository files navigation

@jsxtools/rolldown-transform

Write one Rolldown transform hook that also works in Vite and Rollup.

Rolldown supplies transform metadata such as a parsed AST, a native RolldownMagicString, and the module type. Older Vite and Rollup pipelines do not. rolldownTransform fills in those APIs lazily and adapts native MagicString results for legacy pipelines.

Install

npm install @jsxtools/rolldown-transform

Usage

import { rolldownTransform } from "@jsxtools/rolldown-transform";
import type { TransformMeta } from "@jsxtools/rolldown-transform";
import type { Plugin, TransformResult } from "rolldown";

export const plugin: Plugin = {
	name: "my-plugin",
	transform: rolldownTransform({
		filter: {
			id: /\.[cm]?[jt]sx?(?:\?|$)/,
			code: "console.log",
		},
		handler(_code, _id, meta: TransformMeta): TransformResult {
			meta.magicString.replaceAll("console.log", "console.debug");

			return meta.magicString.hasChanged() ? { code: meta.magicString } : null;
		},
	}),
};

The object-form hook, including filter and order, is passed through to the host. The handler's this value is preserved.

Metadata

The wrapped handler always receives a TransformMeta with:

  • moduleType — supplied by Rolldown or inferred from the module ID.
  • ast — an Oxc ESTree-compatible Program, parsed only when first read.
  • magicString — a RolldownMagicString, created only when first read.
  • ssr — Vite's optional SSR flag when supplied by Vite.

Existing Rolldown metadata is reused. When the host does not provide a native MagicString, a returned RolldownMagicString is converted to a string and an encoded source map automatically. An explicitly returned map, including null, is preserved.

Module type inference

Script extensions are normalized as follows:

ID moduleType
.js, .mjs, .cjs js
.jsx jsx
.ts, .mts, .cts ts
.tsx tsx
.txt text

Other extensions are used without the leading dot, and extensionless IDs default to js. Vite-style query parameters such as ?lang.ts and ?lang=tsx take precedence over the file extension.

API

rolldownTransform(options)

Returns an object-form transform hook compatible with a Rolldown or Vite plugin.

options.handler

The transform function. It receives (code, id, meta) and may return any Rolldown TransformResult, synchronously or asynchronously.

options.filter

An optional native Rolldown transform hook filter. Filtering remains the responsibility of the host bundler.

options.order

Optional hook order: "pre", "post", or null.

Performance

npm run benchmark isolates wrapper dispatch without parsing an AST or creating a MagicString. Across three seven-sample, one-million-iteration runs on Node.js 24.16.0 and an Apple M5 Max, the direct handler measured 2.2 ns/op, the native Rolldown path measured 6.0–6.2 ns/op, and the Rollup fallback path measured 329.3–331.4 ns/op. The previous unconditional async boundary measured 29.4–30.0 ns/op. This measures wrapper overhead, not end-to-end build throughput; results vary by runtime and hardware.

Requirements

  • Node.js ^20.19.0 || >=22.12.0
  • Rolldown ^1.0.0
  • ESM

The automated compatibility matrix exercises builds through Rollup 4.62.2 and development transforms through Vite 6.4.3, 7.3.6, and 8.1.4. Run npm test to execute it or npm run benchmark to compare direct dispatch with native Rolldown and fallback Rollup paths.

License

MIT-0

About

Write Rolldown transform hooks that also work in Vite and Rollup

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors