Description
We should document and codemod the migration from rimraf v3/v4/v5 to node:fs.rm() in Node.js v24.
- The migration should be divided by
rimraf v3, v4, and v5.
- The migration should separate import replacement from runtime behavior differences.
- The migration should call out observed output gaps so version-specific behavior is explicit.
- The migration should keep the deletion wiring and example structure aligned across all baselines.
- The migration should include compensating patterns for code that depends on legacy glob handling or retry behavior.
Important points
rimraf v3 and v4 expose the older package-style recursive delete APIs, while v5 uses named exports.
rimraf glob patterns do not map directly to fs.rm(), but they can be migrated with fs.globSync() plus fs.rm() or fs.rmSync().
- Most cases are a straight source-import migration, but a few cases need behavior notes because glob handling or missing-path behavior differs at runtime.
- The codemod should prefer built-in
node:fs imports for Node.js-only code.
fs.rmdir({ recursive: true }) is deprecated and should not be used as a replacement.
Examples
rimraf v3 -> node:fs v24
- import rimraf from "rimraf-v3";
+ import { globSync, rmSync } from "node:fs";
+ import { rm as rmPromise } from "node:fs/promises";
Literal recursive delete:
- rimraf("dist", (error) => {
- if (error) throw error;
- });
+ await rmPromise("dist", {
+ recursive: true,
+ force: true,
+ });
Observed runtime behavior:
--- rimraf v3
+++ node:fs v24
@@
(no changes)
Example of glob migration:
- rimraf("dist/**/*.js", (error) => {
- if (error) throw error;
- });
+ for (const filePath of globSync("dist/**/*.js")) {
+ rmSync(filePath, { recursive: true, force: true });
+ }
rimraf v4 -> node:fs v24
- import rimraf from "rimraf-v4";
+ import { globSync, rmSync } from "node:fs";
+ import { rm as rmPromise } from "node:fs/promises";
Observed runtime behavior:
--- rimraf v4
+++ node:fs v24
@@
(no changes)
Example of the same migration pattern with no compensation needed:
- await rimraf("dist", {
- glob: false,
- });
+ await rmPromise("dist", {
+ recursive: true,
+ force: true,
+ });
rimraf v5 -> node:fs v24
- import { rimraf, rimrafSync } from "rimraf-v5";
+ import { globSync, rmSync } from "node:fs";
+ import { rm as rmPromise } from "node:fs/promises";
Observed runtime behavior:
--- rimraf v5
+++ node:fs v24
@@
(no changes)
Example of sync migration:
- rimrafSync("dist");
+ rmSync("dist", {
+ recursive: true,
+ force: true,
+ });
Caveats
- These are migration differences, not stream-style output gaps.
- The version split matters when code depends on glob expansion, missing-path behavior, or Windows retry handling.
- If the code relies on package-specific retry semantics, keep the behavior explicit instead of assuming parity with native deletion.
- If the code only needs literal recursive deletion, prefer the Node core behavior and remove the
rimraf dependency.
- If the code depends on glob expansion, keep the globbing step separate and use
fs.globSync() before deletion.
Refs
Description
We should document and codemod the migration from
rimrafv3/v4/v5 tonode:fs.rm()in Node.js v24.rimrafv3, v4, and v5.Important points
rimrafv3 and v4 expose the older package-style recursive delete APIs, while v5 uses named exports.rimrafglob patterns do not map directly tofs.rm(), but they can be migrated withfs.globSync()plusfs.rm()orfs.rmSync().node:fsimports for Node.js-only code.fs.rmdir({ recursive: true })is deprecated and should not be used as a replacement.Examples
rimraf v3 -> node:fs v24
Literal recursive delete:
Observed runtime behavior:
Example of glob migration:
rimraf v4 -> node:fs v24
Observed runtime behavior:
Example of the same migration pattern with no compensation needed:
rimraf v5 -> node:fs v24
Observed runtime behavior:
Example of sync migration:
Caveats
rimrafdependency.fs.globSync()before deletion.Refs
fs.rm()documentation: https://nodejs.org/api/fs.html#fsrmpath-options-callbackfs.globSync()documentation: https://nodejs.org/api/fs.html#fsglobsyncpattern-optionsfs.rmdir()deprecation notes: https://nodejs.org/api/fs.html#fsrmdirpath-options-callbackrimrafreadme: https://github.com/isaacs/rimraf/blob/main/README.md