Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A Node.js script to remove all files in a directory recursively
var fs = require('fs')
, path = require('path')
, _ = require('underscore');
var rootPath = "/path/to/remove";
removeDirForce(rootPath);
// path should have trailing slash
function removeDirForce(dirPath) {
fs.readdir(dirPath, function(err, files) {
if (err) {
console.log(JSON.stringify(err));
} else {
if (files.length === 0) {
fs.rmdir(dirPath, function(err) {
if (err) {
console.log(JSON.stringify(err));
} else {
var parentPath = path.normalize(dirPath + '/..') + '/';
if (parentPath != path.normalize(rootPath)) {
removeDirForce(parentPath);
}
}
});
} else {
_.each(files, function(file) {
var filePath = dirPath + file;
fs.stat(filePath, function(err, stats) {
if (err) {
console.log(JSON.stringify(err));
} else {
if (stats.isFile()) {
fs.unlink(filePath, function(err) {
if (err) {
console.log(JSON.stringify(err));
}
});
}
if (stats.isDirectory()) {
removeDirForce(filePath + '/');
}
}
});
});
}
}
});
}
@mader80

This comment has been minimized.

Copy link

commented Feb 28, 2012

I am not able to get this to work. It will fail based on the fact that if something is a directory, the function will call itself, remove that directory and then stop running. Not to mention the fact that the stats.isDirectory is returning true for files.

@guybedford

This comment has been minimized.

Copy link

commented May 31, 2012

Here's a synchronous version:

    rmDir = function(dirPath) {
      try { var files = fs.readdirSync(dirPath); }
      catch(e) { return; }
      if (files.length > 0)
        for (var i = 0; i < files.length; i++) {
          var filePath = dirPath + '/' + files[i];
          if (fs.statSync(filePath).isFile())
            fs.unlinkSync(filePath);
          else
            rmDir(filePath);
        }
      fs.rmdirSync(dirPath);
    };
@Diullei

This comment has been minimized.

Copy link

commented Jan 21, 2013

@guybedford nice!

@vasiliyb

This comment has been minimized.

Copy link

commented Mar 22, 2014

@guybedford, ty :)

@serge10d1n

This comment has been minimized.

Copy link

commented Dec 5, 2014

Maybe it will be usefull for someone. Extend @guybedfrod function, to remove all in dir but not dir itself.

    rmDir = function(dirPath, removeSelf) {
      if (removeSelf === undefined)
        removeSelf = true;
      try { var files = fs.readdirSync(dirPath); }
      catch(e) { return; }
      if (files.length > 0)
        for (var i = 0; i < files.length; i++) {
          var filePath = dirPath + '/' + files[i];
          if (fs.statSync(filePath).isFile())
            fs.unlinkSync(filePath);
          else
            rmDir(filePath);
        }
      if (removeSelf)
        fs.rmdirSync(dirPath);
    };

Call rmDir('path/to/dir') to remove all inside dir and dir itself. Call rmDir('path/to/dir', false) to remove all inside, but not dir itself.

@willemx

This comment has been minimized.

Copy link

commented Jan 23, 2015

you could replace:

var filePath = dirPath + '/' + files[i];

with:

var filePath = path.join(dirPath, files[i]);

and then it might even work on Windows...

@PWKad

This comment has been minimized.

Copy link

commented May 18, 2015

That crawler and destroyer that @guybedford posted works great, just be careful to not have any npm links or symlinks for that matter :) Found that out the hard way.

@ghost

This comment has been minimized.

Copy link

commented Jun 19, 2016

@guybedford : Time saving 'code block',thank you.

@jameymcelveen

This comment has been minimized.

Copy link

commented Jul 4, 2016

Thanks! Need change rootPath to dirPath here L20

@narainsagar

This comment has been minimized.

Copy link

commented Sep 30, 2016

@liangzan Nice. 👍

@richie50

This comment has been minimized.

Copy link

commented Aug 3, 2017

@guybedford Bless your soul

@OddMorning

This comment has been minimized.

Copy link

commented Jun 28, 2018

I made an async/await version of @guybedford's code with some changes based on @iserdmi's, @willemx's, and @PWKad's comments.

It can accept object as a second argument that can allow delete just folder's content with { removeContentOnly: true } or allow drilling symbolic links down with { drillDownSymlinks: true } (by default it just deletes a symlink, not its content)

Usage: await rmdir('some/path') or await rmdir('some/path', { (optionsDescridedAbove) })

let rmdir = async (dirPath, options = {}) => {
  const
    { removeContentOnly = false, drillDownSymlinks = false } = options,
    { promisify } = require('util'),
    path = require('path'),
    fs = require('fs'),
    readdirAsync = promisify(fs.readdir),
    unlinkAsync = promisify(fs.unlink),
    rmdirAsync = promisify(fs.rmdir),
    lstatAsync = promisify(fs.lstat) // fs.lstat can detect symlinks, fs.stat can't
  let
    files

  try {
    files = await readdirAsync(dirPath)
  } catch (e) {
    throw new Error(e)
  }

  if (files.length) {
    for (let fileName of files) {
      let
        filePath = path.join(dirPath, fileName),
        fileStat = await lstatAsync(filePath),
        isSymlink = fileStat.isSymbolicLink(),
        isDir = fileStat.isDirectory()

      if (isDir || (isSymlink && drillDownSymlinks)) {
        await rmdir(filePath)
      } else {
        await unlinkAsync(filePath)
      }
    }
  }

  if (!removeContentOnly)
    await rmdirAsync(dirPath)
}
@rubanraj54

This comment has been minimized.

Copy link

commented Feb 20, 2019

Here's a synchronous version:

    rmDir = function(dirPath) {
      try { var files = fs.readdirSync(dirPath); }
      catch(e) { return; }
      if (files.length > 0)
        for (var i = 0; i < files.length; i++) {
          var filePath = dirPath + '/' + files[i];
          if (fs.statSync(filePath).isFile())
            fs.unlinkSync(filePath);
          else
            rmDir(filePath);
        }
      fs.rmdirSync(dirPath);
    };

This worked for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.