[node.js] How to create a directory if it doesn't exist using Node.js?

Is this the right way to create a directory if it doesn't exist. It should have full permission for the script and readable by others.

var dir = __dirname + '/upload';
if (!path.existsSync(dir)) {
    fs.mkdirSync(dir, 0744);
}

This question is related to node.js

The answer is


    var filessystem = require('fs');
    var dir = './path/subpath/';

    if (!filessystem.existsSync(dir)){
        filessystem.mkdirSync(dir);
    }else
    {
        console.log("Directory already exist");
    }

This may help you :)


Here is a little function to recursivlely create directories:

const createDir = (dir) => {
  // This will create a dir given a path such as './folder/subfolder' 
  const splitPath = dir.split('/');
  splitPath.reduce((path, subPath) => {
    let currentPath;
    if(subPath != '.'){
      currentPath = path + '/' + subPath;
      if (!fs.existsSync(currentPath)){
        fs.mkdirSync(currentPath);
      }
    }
    else{
      currentPath = subPath;
    }
    return currentPath
  }, '')
}

I have found and npm module that works like a charm for this. It's simply do a recursively mkdir when needed, like a "mkdir -p ".

https://www.npmjs.com/package/mkdirp


I had to create sub-directories if they didn't exist. I used this:

const path = require('path');
const fs = require('fs');

function ensureDirectoryExists(p) {
    //console.log(ensureDirectoryExists.name, {p});
    const d = path.dirname(p);
    if (d && d !== p) {
        ensureDirectoryExists(d);
    }
    if (!fs.existsSync(d)) {
        fs.mkdirSync(d);
    }
}

From the docs this is how you do it asynchronously (and recursively):

const fs = require('fs');
const fsPromises = fs.promises;

fsPromises.access(dir, fs.constants.F_OK)
   .catch(async() => {
                await fs.mkdir(dir, { recursive: true }, function(err) {
                    if (err) {
                      console.log(err)
                    }
                  })
    });

No, for multiple reasons.

  1. The path module does not have an exists/existsSync method. It is in the fs module. (Perhaps you just made a typo in your question?)

  2. The docs explicitly discourage you from using exists.

    fs.exists() is an anachronism and exists only for historical reasons. There should almost never be a reason to use it in your own code.

    In particular, checking if a file exists before opening it is an anti-pattern that leaves you vulnerable to race conditions: another process may remove the file between the calls to fs.exists() and fs.open(). Just open the file and handle the error when it's not there.

    Since we're talking about a directory rather than a file, this advice implies you should just unconditionally call mkdir and ignore EEXIST.

  3. In general, You should avoid the *Sync methods. They're blocking, which means absolutely nothing else in your program can happen while you go to the disk. This is a very expensive operation, and the time it takes breaks the core assumption of node's event loop.

    The *Sync methods are usually fine in single-purpose quick scripts (those that do one thing and then exit), but should almost never be used when you're writing a server: your server will be unable to respond to anyone for the entire duration of the I/O requests. If multiple client requests require I/O operations, your server will very quickly grind to a halt.


    The only time I'd consider using *Sync methods in a server application is in an operation that happens once (and only once), at startup. For example, require actually uses readFileSync to load modules.

    Even then, you still have to be careful because lots of synchronous I/O can unnecessarily slow down your server's startup time.


    Instead, you should use the asynchronous I/O methods.

So if we put together those pieces of advice, we get something like this:

function ensureExists(path, mask, cb) {
    if (typeof mask == 'function') { // allow the `mask` parameter to be optional
        cb = mask;
        mask = 0777;
    }
    fs.mkdir(path, mask, function(err) {
        if (err) {
            if (err.code == 'EEXIST') cb(null); // ignore the error if the folder already exists
            else cb(err); // something else went wrong
        } else cb(null); // successfully created folder
    });
}

And we can use it like this:

ensureExists(__dirname + '/upload', 0744, function(err) {
    if (err) // handle folder creation error
    else // we're all good
});

Of course, this doesn't account for edge cases like

  • What happens if the folder gets deleted while your program is running? (assuming you only check that it exists once during startup)
  • What happens if the folder already exists but with the wrong permissions?

With the fs-extra package you can do this with a one-liner:

const fs = require('fs-extra');

const dir = '/tmp/this/path/does/not/exist';
fs.ensureDirSync(dir);

With Node 10 + ES6:

import path from 'path';
import fs from 'fs';

(async () => {
  const dir = path.join(__dirname, 'upload');

  try {
    await fs.promises.mkdir(dir);
  } catch (error) {
    if (error.code === 'EEXIST') {
      // Something already exists, but is it a file or directory?
      const lstat = await fs.promises.lstat(dir);

      if (!lstat.isDirectory()) {
        throw error;
      }
    } else {
      throw error;
    }
  }
})();

fs.exist() is deprecated. So I have used fs.stat() to check the directory status. If the directory does not exist fs.stat() throw an error with message like 'no such file or directory'. Then I have created a directory.

const fs = require('fs').promises;
    
const dir = './dir';
fs.stat(dir).catch(async (err) => {
  if (err.message.includes('no such file or directory')) {
    await fs.mkdir(dir);
  }
});

var dir = 'path/to/dir';
try {
  fs.mkdirSync(dir);
} catch(e) {
  if (e.code != 'EEXIST') throw e;
}

Using async / await:

const mkdirP = async (directory) => {
  try {
    return await fs.mkdirAsync(directory);
  } catch (error) {
    if (error.code != 'EEXIST') {
      throw e;
    }
  }
};

You will need to promisify fs:

import nodeFs from 'fs';
import bluebird from 'bluebird';

const fs = bluebird.promisifyAll(nodeFs);

You can use node File System command fs.stat to check if dir exists and fs.mkdir to create a directory with callback, or fs.mkdirSync to create a directory without callback, like this example:

//first require fs
const fs = require('fs');

// Create directory if not exist (function)
const createDir = (path) => {
    // check if dir exist
    fs.stat(path, (err, stats) => {
        if (stats.isDirectory()) {
            // do nothing
        } else {
            // if the given path is not a directory, create a directory
            fs.mkdirSync(path);
        }
    });
};

One Line Solution: Creates directory if NOT exist

// import
const fs = require('fs')  // in javascript
import * as fs from "fs"  // in typescript
import fs from "fs"       // in typescript

// use
!fs.existsSync(`./assets/`) && fs.mkdirSync(`./assets/`, { recursive: true })

Just in case any one interested in the one line version. :)

//or in typescript: import * as fs from 'fs';
const fs = require('fs');
!fs.existsSync(dir) && fs.mkdirSync(dir);

You can just use mkdir and catch the error if the folder exists.
This is async (so best practice) and safe.

fs.mkdir('/path', err => { 
    if (err && err.code != 'EEXIST') throw 'up'
    .. safely do your stuff here  
    })

(Optionally add a second argument with the mode.)


Other thoughts:

  1. You could use then or await by using native promisify.

    const util = require('util'), fs = require('fs');
    const mkdir = util.promisify(fs.mkdir);
    var myFunc = () => { ..do something.. } 
    
    mkdir('/path')
        .then(myFunc)
        .catch(err => { if (err.code != 'EEXIST') throw err; myFunc() })
    
  2. You can make your own promise method, something like (untested):

    let mkdirAsync = (path, mode) => new Promise(
       (resolve, reject) => mkdir (path, mode, 
          err => (err && err.code !== 'EEXIST') ? reject(err) : resolve()
          )
       )
    
  3. For synchronous checking, you can use:

    fs.existsSync(path) || fs.mkdirSync(path)
    
  4. Or you can use a library, the two most popular being

    • mkdirp (just does folders)
    • fsextra (supersets fs, adds lots of useful stuff)

I'd like to add a Typescript Promise refactor of josh3736's answer.

It does the same thing and has the same edge cases, it just happens to use Promises, typescript typedefs and works with "use strict".

// https://en.wikipedia.org/wiki/File_system_permissions#Numeric_notation
const allRWEPermissions = parseInt("0777", 8);

function ensureFilePathExists(path: string, mask: number = allRWEPermissions): Promise<void> {
    return new Promise<void>(
        function(resolve: (value?: void | PromiseLike<void>) => void,
            reject: (reason?: any) => void): void{
            mkdir(path, mask, function(err: NodeJS.ErrnoException): void {
                if (err) {
                    if (err.code === "EEXIST") {
                        resolve(null); // ignore the error if the folder already exists
                    } else {
                        reject(err); // something else went wrong
                    }
                } else {
                    resolve(null); // successfully created folder
                }
            });
    });
}

The mkdir method has the ability to recursively create any directories in a path that don't exist, and ignore the ones that do.

From the Node v10/11 docs:

// Creates /tmp/a/apple, regardless of whether `/tmp` and /tmp/a exist.
fs.mkdir('/tmp/a/apple', { recursive: true }, (err) => {
    if (err) throw err;
});

NOTE: You'll need to import the built-in fs module first.

Now here's a little more robust example that leverages native ES Modules (with flag enabled and .mjs extension), handles non-root paths, and accounts for full pathnames:

import fs from 'fs';
import path from 'path';

createDirectories(pathname) {
   const __dirname = path.resolve();
   pathname = pathname.replace(/^\.*\/|\/?[^\/]+\.[a-z]+|\/$/g, ''); // Remove leading directory markers, and remove ending /file-name.extension
   fs.mkdir(path.resolve(__dirname, pathname), { recursive: true }, e => {
       if (e) {
           console.error(e);
       } else {
           console.log('Success');
       }
    });
}

You can use it like createDirectories('/components/widget/widget.js');.

And of course, you'd probably want to get more fancy by using promises with async/await to leverage file creation in a more readable synchronous-looking way when the directories are created; but, that's beyond the question's scope.


The best solution would be to use the npm module called node-fs-extra. It has a method called mkdir which creates the directory you mentioned. If you give a long directory path, it will create the parent folders automatically. The module is a super set of npm module fs, so you can use all the functions in fs also if you add this module.