# Technical Documentation: isaacs/rimraf

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/isaacs/rimraf)

### Overview (`README.md`)

The [UNIX command](<http://en.wikipedia.org/wiki/Rm_(Unix)>) `rm -rf` for node
in a cross-platform implementation.

Install with `npm install rimraf`.

> [!CAUTION]
>
> ## Please Be Safe, this tool deletes and moves stuff, by design
>
> The _intended purpose_ of this tool is to remove files and
> directories from the filesystem, aggressively and recursively
> removing all items that it can find under a given target.
>
> It goes without saying that you _must not pass untrusted input
> to this function or CLI tool_, just as you would not to the
> `rm(1)` command or the `unlink(2)` function. It is very
> challenging to guarantee that _any_ user input will be safe to
> remove recursively in this way.
>
> Furthermore, note that if you allow untrusted parties to
> provide arguments to the `rimraf` command line tool, they may
> also specify the `--tmp=<dir>` folder used by the
> `--impl=move-remove` strategy, which can move files to an
> arbitrary place on disk.
>
> Because the intended purpose of this tool is the permanent
> destruction of filesystem entries, any security reports that
> rely on untrusted input being passed to the function or command
> line tool will be rejected.
>
> **It is your responsibility as a user to never pass untrusted
> user input to this module, or your system can be destroyed or
> compromised.**

## Major Changes

### v5 to v6

- Require node `20` or `>=22`
- Add `--version` to CLI

### v4 to v5

- There is no default export anymore. Import the functions directly
  using, e.g., `import { rimrafSync } from 'rimraf'`.

### v3 to v4

- The function returns a `Promise` instead of taking a callback.
- Globbing requires the `--glob` CLI option or `glob` option property
  to be set. (Removed in 4.0 and 4.1, opt-in support added in 4.2.)
- Functions take arrays of paths, as well as a single path.
- Native implementation used by default when available, except on
  Windows, where this implementation is faster and more reliable.
- New implementation on Windows, falling back to "move then
  remove" strategy when exponential backoff for `EBUSY` fails to
  resolve the situation.
- Simplified implementation on POSIX, since the Windows
  affordances are not necessary there.
- As of 4.3, return/resolve value is boolean instead of undefined.

## API

Hybrid module, load either with `import` or `require()`.

```js
// 'rimraf' export is the one you probably want, but other
// strategies exported as well.
import { rimraf, rimrafSync, native, nativeSync } from 'rimraf'
// or
const { rimraf, rimrafSync, native, nativeSync } = require('rimraf')
```

All removal functions return a boolean indicating that all
entries were successfully removed.

The only case in which this will not return `true` is if
something was omitted from the removal via a `filter` option.

### `rimraf(f, [opts]) -> Promise`

This first parameter is a path or array of paths. The second
argument is an options object.

Options:

- `preserveRoot`: If set to boolean `false`, then allow the
  recursive removal of the root directory. Otherwise, this is
  not allowed.
- `tmp`: Windows only. Temp folder to place files and
  folders for the "move then remove" fallback. Must be on the
  same physical device as the path being deleted. Defaults to
  `os.tmpdir()` when that is on the same drive letter as the path
  being deleted, or `${drive}:\temp` if present, or `${drive}:\`
  if not.
- `maxRetries`: Windows and Native only. Maximum number of
  retry attempts in case of `EBUSY`, `EMFILE`, and `ENFILE`
  errors. Default `10` for Windows implementation, `0` for Native
  implementation.
- `backoff`: Windows only. Rate of exponential backoff for async
  removal in case of `EBUSY`, `EMFILE`, and `ENFILE` errors.
  Should be a number greater than 1. Default `1.2`
- `maxBackoff`: Windows only. Maximum total backoff time in ms to
  attempt asynchronous retries in case of `EBUSY`, `EMFILE`, and
  `ENFILE` errors. Default `200`. With the default `1.2` backoff
  rate, this results in 14 retries, with the final retry being
  delayed 33ms.
- `retryDelay`: Native only. Time to wait between retries, using
  linear backoff. Default `100`.
- `signal` Pass in an AbortSignal to cancel the directory
  removal. This is useful when removing large folder structures,
  if you'd like to limit the time spent.

  Using a `signal` option prevents the use of Node's built-in
  `fs.rm` because that implementation does not support abort
  signals.

- `glob` Boolean flag to treat path as glob pattern, or an object
  specifying [`glob` options](https://github.com/isaacs/node-glob).
- `filter` Method that returns a boolean indicating whether that
  path should be deleted. With async `rimraf` methods, this may
  return a Promise that resolves to a boolean. (Since Promises
  are truthy, returning a Promise from a sync filter is the same
  as just not filtering anything.)

  The first argument to the filter is the path string. The
  second argument is either a `Dirent` or `Stats` object for that
  path. (The first path explored will be a `Stats`, the rest
  will be `Dirent`.)

  If a filter method is provided, it will _only_ remove entries
  if the filter returns (or resolves to) a truthy value. Omitting
  a directory will still allow its children to be removed, unless
  they are also filtered out, but any parents of a filtered entry
  will not be removed, since the directory will not be empty in
  that case.

  Using a filter method prevents the use of Node's built-in
  `fs.rm` because that implementation does not support filtering.

Any other options are provided to the native Node.js `fs.rm` implementation
when that is used.

This will attempt to choose the best implementation, based on the Node.js
version and `process.platform`. To force a specific implementation, use
one of the other functions provided.

### `rimraf.sync(f, [opts])` <br> `rimraf.rimrafSync(f, [opts])`

Synchronous form of `rimraf()`

Note that, unlike many file system operations, the synchronous form will
typically be significantly _slower_ than the async form, because recursive
deletion is extremely parallelizable.

### `rimraf.native(f, [opts])`

Uses the built-in `fs.rm` implementation that Node.js provides. This is
used by default on Node.js versions greater than or equal to `14.14.0`.

### `rimraf.native.sync(f, [opts])` <br> `rimraf.nativeSync(f, [opts])`

Synchronous form of `rimraf.native`

### `rimraf.manual(f, [opts])`

Use the JavaScript implementation appropriate for your operating system.

### `rimraf.manual.sync(f, [opts])` <br> `rimraf.manualSync(f, opts)`

Synchronous form of `rimraf.manual()`

### `rimraf.windows(f, [opts])`

JavaScript implementation of file removal appropriate for Windows
platforms. Works around `unlink` and `rmdir` not being atomic
operations, and `EPERM` when deleting files with certain
permission modes.

First deletes all non-directory files within the tree, and then
removes all directories, which should ideally be empty by that
time. When an `ENOTEMPTY` is raised in the second pass, falls
back to the `rimraf.moveRemove` strategy as needed.

### `rimraf.windows.sync(path, [opts])` <br> `rimraf.windowsSync(path, [opts])`

Synchronous form of `rimraf.windows()`

### `rimraf.moveRemove(path, [opts])`

Moves all files and folders to the parent directory of `path`
with a temporary filename prior to attempting to remove them.

Note that, in cases where the operation fails, this _may_ leave
files lying around in the parent directory with names like
`.file-basename.txt.0.123412341`. Until the Windows kernel
provides a way to perform atomic `unlink` and `rmdir` operations,
this is, unfortunately, unavoidable.

To move files to a different temporary directory other than the
parent, provide `opts.tmp`. Note that this _must_ be on the same
physical device as the folder being deleted, or else the
operation will fail.

This is the slowest strategy, but most reliable on Windows
platforms. Used as a last-ditch fallback by `rimraf.windows()`.

### `rimraf.moveRemove.sync(path, [opts])` <br> `rimraf.moveRemoveSync(path, [opts])`

Synchronous form of `rimraf.moveRemove()`

### Command Line Interface

```
/* Detailed source-code truncated for AI context efficiency. */
```

## mkdirp

If you need to _create_ a directory recursively, check out
[mkdirp](https://github.com/isaacs/node-mkdirp).

---

### Overview (`benchmark/old-rimraf/README.md`)

[](https://travis-ci.org/isaacs/rimraf) [](https://david-dm.org/isaacs/rimraf) [](https://david-dm.org/isaacs/rimraf#info=devDependencies)

The [UNIX command](http://en.wikipedia.org/wiki/Rm_(Unix)) `rm -rf` for node.

Install with `npm install rimraf`, or just drop rimraf.js somewhere.

## API

`rimraf(f, [opts], callback)`

The first parameter will be interpreted as a globbing pattern for files. If you
want to disable globbing you can do so with `opts.disableGlob` (defaults to
`false`). This might be handy, for instance, if you have filenames that contain
globbing wildcard characters.

The callback will be called with an error if there is one.  Certain
errors are handled for you:

* Windows: `EBUSY` and `ENOTEMPTY` - rimraf will back off a maximum of
  `opts.maxBusyTries` times before giving up, adding 100ms of wait
  between each attempt.  The default `maxBusyTries` is 3.
* `ENOENT` - If the file doesn't exist, rimraf will return
  successfully, since your desired outcome is already the case.
* `EMFILE` - Since `readdir` requires opening a file descriptor, it's
  possible to hit `EMFILE` if too many file descriptors are in use.
  In the sync case, there's nothing to be done for this.  But in the
  async case, rimraf will gradually back off with timeouts up to
  `opts.emfileWait` ms, which defaults to 1000.

## options

* unlink, chmod, stat, lstat, rmdir, readdir,
  unlinkSync, chmodSync, statSync, lstatSync, rmdirSync, readdirSync

    In order to use a custom file system library, you can override
    specific fs functions on the options object.

    If any of these functions are present on the options object, then
    the supplied function will be used instead of the default fs
    method.

    Sync methods are only relevant for `rimraf.sync()`, of course.

    For example:

    ```javascript
    var myCustomFS = require('some-custom-fs')

    rimraf('some-thing', myCustomFS, callback)
    ```

* maxBusyTries

    If an `EBUSY`, `ENOTEMPTY`, or `EPERM` error code is encountered
    on Windows systems, then rimraf will retry with a linear backoff
    wait of 100ms longer on each try.  The default maxBusyTries is 3.

    Only relevant for async usage.

* emfileWait

    If an `EMFILE` error is encountered, then rimraf will retry
    repeatedly with a linear backoff of 1ms longer on each try, until
    the timeout counter hits this max.  The default limit is 1000.

    If you repeatedly encounter `EMFILE` errors, then consider using
    [graceful-fs](http://npm.im/graceful-fs) in your program.

    Only relevant for async usage.

* glob

    Set to `false` to disable [glob](http://npm.im/glob) pattern
    matching.

    Set to an object to pass options to the glob module.  The default
    glob options are `{ nosort: true, silent: true }`.

    Glob version 6 is used in this module.

    Relevant for both sync and async usage.

* disableGlob

    Set to any non-falsey value to disable globbing entirely.
    (Equivalent to setting `glob: false`.)

## rimraf.sync

It can remove stuff synchronously, too.  But that's not so good.  Use
the async API.  It's better.

## CLI

If installed with `npm install rimraf -g` it can be used as a global
command `rimraf <path> [<path> ...]` which is useful for cross platform support.

## mkdirp

If you need to create a directory recursively, check out
[mkdirp](https://github.com/substack/node-mkdirp).

---

--- METRICS ---
- Files Extracted: 2
- Estimated Token Budget: ~2961 tokens
- Canonical Reference: https://codewiki.google/github.com/isaacs/rimraf
