How do you create a directory in Node.js?
1. Asynchronous folder creation (via a callback)
The classic way:
import fs from 'fs';
fs.mkdir('./uploads', (err) => {
if (err) {
console.error('Error creating the folder:', err);
return;
}
console.log('Folder created!');
});- If the folder already exists → you get an
EEXISTerror; - This method doesn't block the event loop, safe for servers.
2. The modern way (via fs/promises and await)
The most convenient, modern option, with promises and async/await:
import { mkdir } from 'fs/promises';
try {
await mkdir('./uploads');
console.log('Folder created!');
} catch (err) {
if (err.code === 'EEXIST') {
console.log('The folder already exists.');
} else {
console.error('Error:', err);
}
}- Asynchronous, clean, no callbacks;
- Recommended for all modern versions of Node.js (v14+).
3. Creating nested directories (recursively)
To create nested folders, for example:
uploads/images/2025/januaryjust add the { recursive: true } flag:
import { mkdir } from 'fs/promises';
await mkdir('./uploads/images/2025/january', { recursive: true });
console.log('Nested folders created!');- Node creates every missing level itself;
- If the directory already exists, there's no error.
This is the equivalent of the Linux command:
mkdir -p uploads/images/2025/january4. The synchronous way (blocking)
If you're creating folders at script startup (for example, for logs or configuration):
import fs from 'fs';
try {
fs.mkdirSync('./uploads');
console.log('Folder created!');
} catch (err) {
if (err.code === 'EEXIST') {
console.log('It already exists.');
} else {
console.error('Error:', err);
}
}- Runs instantly, but blocks the event loop.
- Not recommended for server applications, only for setup scripts.
5. Checking existence before creating
The folder's presence can be checked ahead of time:
import fs from 'fs';
if (!fs.existsSync('./uploads')) {
fs.mkdirSync('./uploads');
console.log('Folder created!');
} else {
console.log('The folder is already there.');
}But on newer Node versions, it's simpler to just use { recursive: true }, no check needed.
6. Permissions (mode)
The mode option sets the folder's permissions (UNIX-style):
await mkdir('./secure', { mode: 0o700 });0o777, everyone can read/write/execute;0o700, only the owner;- By default, Node inherits the system's permissions.
7. Deleting and recreating (an example)
To clear a directory before recreating it:
import { rm, mkdir } from 'fs/promises';
await rm('./uploads', { recursive: true, force: true });
await mkdir('./uploads');
console.log('The folder was recreated!');8. Handling common errors
| Error code | Cause | Fix |
|---|---|---|
EEXIST | The folder already exists | Use { recursive: true } |
ENOENT | The parent folder doesn't exist | Use { recursive: true } |
EACCES | No permission to create it | Check file permissions |
EPERM | A system restriction (Windows) | Run as administrator |
9. Example: setting up a project structure
import { mkdir } from 'fs/promises';
const dirs = ['logs', 'data/uploads', 'data/backups'];
for (const dir of dirs) {
await mkdir(dir, { recursive: true });
console.log(`${dir} created`);
}This automatically builds the needed structure, even if some folders are missing.
10. Quick summary
| Method | Asynchronous | Creates nested folders | Recommended |
|---|---|---|---|
fs.mkdir() | Yes (callback) | No | The older style |
fs.promises.mkdir() | Yes (await) | Yes ({ recursive: true }) | The modern choice |
fs.mkdirSync() | No | No | CLI only |
fs.mkdirSync(..., { recursive: true }) | No | Yes | At initialization |
In one sentence
To create a folder in Node.js, use
await fs.promises.mkdir('path', { recursive: true }), it's safe, modern, doesn't block the thread, and automatically creates nested directories.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.