{"id":11952,"library":"rimraf","title":"rimraf: Cross-Platform `rm -rf`","description":"rimraf is a robust, cross-platform Node.js module that provides functionality akin to the `rm -rf` UNIX command for deep, recursive file and directory deletion. Currently at version 6.1.3, it is actively maintained with periodic major releases introducing significant changes, such as the shift from callbacks to Promises and the move away from default exports. A key differentiator is its specialized handling of common file system issues on Windows, such as `EBUSY` or `EMFILE` errors, through strategies like \"move then remove\" and exponential backoff, making it more reliable than simple native `fs.rm` alternatives in certain scenarios. It offers both synchronous and asynchronous APIs, as well as options to select native or JavaScript-based implementations. A critical aspect of its usage is the explicit warning against passing untrusted input due to its aggressive deletion capabilities, which can lead to system destruction or compromise if misused.","status":"active","version":"6.1.3","language":"javascript","source_language":"en","source_url":"ssh://git@github.com/isaacs/rimraf","tags":["javascript","rm","rm -rf","rm -fr","remove","directory","cli","rmdir","recursive","typescript"],"install":[{"cmd":"npm install rimraf","lang":"bash","label":"npm"},{"cmd":"yarn add rimraf","lang":"bash","label":"yarn"},{"cmd":"pnpm add rimraf","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Since v5, the package no longer has a default export; named imports are required for all functions like `rimraf`. In CommonJS, use `const { rimraf } = require('rimraf')`.","wrong":"import rimraf from 'rimraf'","symbol":"rimraf","correct":"import { rimraf } from 'rimraf'"},{"note":"For synchronous deep deletion. The module is hybrid, supporting both ESM and CJS named imports.","wrong":"const rimrafSync = require('rimraf').rimrafSync","symbol":"rimrafSync","correct":"import { rimrafSync } from 'rimraf'"},{"note":"To explicitly use Node.js's built-in `fs.rm` implementation (when available, default on Node.js >=14.14.0 except Windows). The main `rimraf` function uses this by default where optimal.","wrong":"import { rimraf } from 'rimraf/native'","symbol":"native","correct":"import { native } from 'rimraf'"}],"quickstart":{"code":"import { rimraf } from 'rimraf';\nimport { mkdir, writeFile, stat } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { tmpdir } from 'node:os';\n\nasync function exampleUsage() {\n  const tempDirPath = join(tmpdir(), `rimraf-example-${Date.now()}`);\n  const tempFilePath = join(tempDirPath, 'test-file.txt');\n\n  console.log(`Creating temporary directory: ${tempDirPath}`);\n  await mkdir(tempDirPath, { recursive: true });\n  await writeFile(tempFilePath, 'Hello, rimraf!');\n  console.log(`Created temporary file: ${tempFilePath}`);\n\n  try {\n    const stats = await stat(tempDirPath);\n    console.log(`Directory exists before deletion: ${stats.isDirectory()}`);\n  } catch (err) {\n    console.error(`Error checking directory before deletion: ${err}`);\n  }\n\n  console.log(`Attempting to delete: ${tempDirPath}`);\n  // The 'rimraf' function returns a boolean indicating successful removal\n  const success = await rimraf(tempDirPath);\n\n  if (success) {\n    console.log(`Successfully deleted: ${tempDirPath}`);\n    try {\n      await stat(tempDirPath);\n      console.error('ERROR: Directory still exists after deletion!');\n    } catch (err: any) {\n      if (err.code === 'ENOENT') {\n        console.log('Directory no longer exists (as expected).');\n      } else {\n        console.error(`Error checking directory after deletion: ${err}`);\n      }\n    }\n  } else {\n    console.error(`Failed to delete: ${tempDirPath}. (A filter might have prevented full removal.)`);\n  }\n}\n\nexampleUsage().catch(console.error);","lang":"typescript","description":"Demonstrates basic asynchronous usage of `rimraf` to create a temporary directory and file, then recursively delete the directory, verifying its removal."},"warnings":[{"fix":"Upgrade your Node.js environment to version 20 or 22+.","message":"Node.js runtime requirement was updated to `20 || >=22` in v6.0.0. Older Node.js versions are no longer supported.","severity":"breaking","affected_versions":">=6.0.0"},{"fix":"Change `import rimraf from 'rimraf'` to `import { rimraf } from 'rimraf'` or `const { rimraf } = require('rimraf')`.","message":"The default export was removed in v5.0.0. Direct named imports are now required for all functions like `rimraf` and `rimrafSync`.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Refactor code to use `await rimraf(...)` or `.then()` syntax instead of passing a callback function as the last argument.","message":"Starting with v4.0.0, `rimraf` functions return a `Promise` instead of accepting a callback. This significantly changes the asynchronous API usage.","severity":"breaking","affected_versions":">=4.0.0 <5.0.0"},{"fix":"Ensure globbing is explicitly enabled if paths contain glob patterns, for example: `await rimraf('path/*.txt', { glob: true })`. If using the CLI, add the `--glob` flag.","message":"In v4.0.0, globbing functionality was initially removed. It was reintroduced as an opt-in feature in v4.2.0, requiring the `--glob` CLI option or `glob: true` option property to be set for glob patterns to be processed.","severity":"breaking","affected_versions":">=4.0.0 <4.2.0"},{"fix":"Always sanitize and validate any user-supplied paths. Restrict `rimraf` usage to known, safe, application-controlled paths.","message":"NEVER pass untrusted user input directly to `rimraf` or its CLI tool. This utility aggressively deletes files and directories, and malicious input can lead to irreversible data loss, system destruction, or compromise. The `tmp` option for `--impl=move-remove` can also be exploited to move files to arbitrary locations.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"When experiencing persistent deletion issues on Windows, consider adjusting `maxRetries` or providing a `tmp` path that is on the same physical device as the target.","message":"On Windows, `rimraf` employs specific strategies (like 'move then remove' and exponential backoff) to handle `EBUSY`, `EMFILE`, and `ENFILE` errors. You can configure these retries and backoff parameters via the `maxRetries`, `backoff`, and `maxBackoff` options, and specify a `tmp` directory.","severity":"gotcha","affected_versions":">=4.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Update your import statement to use named imports: `import { rimraf } from 'rimraf'`.","cause":"Attempting to use `rimraf` as a default import after version 5, where the default export was removed. This is common in TypeScript or Babel environments.","error":"TypeError: (0 , rimraf_1.default) is not a function"},{"fix":"Refactor your code to use the Promise-based API: `await rimraf(path)` or `rimraf(path).then(() => ...)`. Do not pass a callback as the last argument.","cause":"Using the pre-v4 callback-based API with `rimraf` versions 4 or newer, which exclusively return Promises.","error":"Error: The last argument must be a callback function"},{"fix":"Ensure no other processes (IDEs, terminals, antivirus) are accessing the target path. On Windows, consider configuring `maxRetries` or providing a `tmp` path. If possible, defer deletion until the resource is released.","cause":"Attempting to delete a directory or file that is currently in use by another process, especially common on Windows. While `rimraf` has internal retries, persistent locks can still cause issues.","error":"Error: EBUSY: resource busy or locked, rmdir 'some-directory'"},{"fix":"Ensure `rimraf` is installed as a `devDependency` (`npm install --save-dev rimraf`) and run it via `npm script` (e.g., `npm run clean`) or `npx rimraf`. For global use, install with `npm install -g rimraf` and verify `npm`'s global bin directory is in your PATH.","cause":"The `rimraf` CLI command is not found in the system's PATH, often when used in `package.json` scripts without `npm run` or `npx`, or if `rimraf` was not installed globally/locally.","error":"sh: 1: rimraf: not found"},{"fix":"Add the `{ glob: true }` option to your `rimraf` call: `await rimraf('path/*.txt', { glob: true })`. If using the CLI, add the `--glob` flag.","cause":"Globbing functionality is no longer implicitly enabled in `rimraf` v4+ and requires explicit opt-in.","error":"Paths with glob patterns are not being deleted as expected."}],"ecosystem":"npm"}