Delete files and directories in Node.js

Use unlink for files and rm for recursive removal, handle missing paths deliberately, and understand permissions and deletion semantics.

Best practices
Illustration of files, modules, and their dependencies

Use unlink() to remove a file or symbolic link. Use rm() with recursive: true when you intentionally want to remove a directory tree.

Delete a file asynchronously

Save this Promise example as an ES module, such as delete-file.mjs:

import { unlink } from 'node:fs/promises';
try {
  await unlink('./temporary.txt');
  console.log('File removed');
} catch (error) {
  if (error.code === 'ENOENT') console.log('Path already absent');
  else throw error;
}

The example treats absence as success. If a missing file indicates a broken workflow, propagate that error instead. Relative filesystem paths are resolved from the process's working directory.

A CommonJS callback version is:

const { unlink } = require('node:fs');
unlink('./temporary.txt', (error) => {
  if (error) {
    console.error('Could not remove file:', error);
    process.exitCode = 1;
    return;
  }
  console.log('File removed');
});

For a short script where blocking is acceptable, require('node:fs').unlinkSync('./temporary.txt') is available. Handle its thrown errors as you would other synchronous filesystem failures.

Delete a directory

import { rmdir, rm } from 'node:fs/promises';
await rmdir('./empty-directory');
await rm('./temporary-directory', { recursive: true, force: true });

rmdir() here requires an empty directory. rm() was added in Node 14.14; recursive: true removes the tree, while force: true ignores a missing path. It does not override arbitrary permission or filesystem failures. Confirm the intended path before applying recursive deletion, particularly when it comes from external input.

Interpret failures

ENOENT can indicate a missing target or path component. EACCES and EPERM indicate permission or operation restrictions; attempting unlink() on a directory can also produce EISDIR, depending on the platform. An open handle can prevent deletion on Windows. Close resources you own and inspect directory permissions rather than retrying blindly or elevating the entire application.

Do not check existence first to make deletion safe: the path can change between checking and deleting. Perform the operation and handle its result.

What removal means

These APIs do not move files to the desktop trash. Implement a controlled move-to-trash policy or use an appropriate library if recovery is required.

On POSIX systems, unlinking removes a directory entry; other hard links or open descriptors can keep the underlying data alive. A large file need not be read to unlink it, but filesystem work, remote storage, and reclamation can still take time. Asynchronous APIs avoid blocking the JavaScript thread while that work runs; they do not promise instantaneous deletion or secure erasure.

References

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting