create
directories
parent

How do I create a directory, and any missing parent directories?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

To create a directory along with any missing parent directories, use a recursive creation flag in your language or shell of choice: mkdir -p in Bash, Path.mkdir(parents=True, exist_ok=True) in Python, fs.mkdirSync(path, { recursive: true }) in Node.js, or Directory.CreateDirectory() in C#. Every modern platform provides this capability, and the critical behavior is always the same: create the full path if it does not exist, and do nothing if it already does.

This pattern appears constantly in deployment scripts, CI pipelines, test harnesses, and application startup code. Getting it right means writing idempotent filesystem operations that never crash on a second run.

Shell: mkdir -p

On Linux, macOS, and any POSIX-compatible system, mkdir -p is the standard tool.

bash
mkdir -p /var/app/data/cache/thumbnails

The -p flag does two things:

  1. Creates every intermediate directory in the path that does not already exist.
  2. Suppresses the error that mkdir would normally raise if the target directory is already present.

Without -p, attempting to create /var/app/data/cache/thumbnails when /var/app/data does not exist produces an error:

bash
mkdir /var/app/data/cache/thumbnails
# mkdir: cannot create directory '/var/app/data/cache/thumbnails': No such file or directory

You can also create multiple directory trees in a single command:

bash
mkdir -p /opt/app/{logs,config,data/cache}

This uses brace expansion to create /opt/app/logs, /opt/app/config, and /opt/app/data/cache in one call.

Setting Permissions During Creation

To set specific permissions on the leaf directory as it is created, combine -p with -m:

bash
mkdir -p -m 0750 /var/app/secrets

Note that -m only applies to the final directory. Intermediate directories inherit the default permissions from the process umask.

Python: pathlib and os.makedirs

Python offers two APIs. The modern approach is pathlib.Path.mkdir:

python
from pathlib import Path

Path("/var/app/data/cache").mkdir(parents=True, exist_ok=True)

The two keyword arguments are essential:

  • parents=True creates intermediate directories that do not exist.
  • exist_ok=True prevents a FileExistsError if the directory is already present.

The older os.makedirs function does the same job:

python
import os

os.makedirs("/var/app/data/cache", exist_ok=True)

Both accept an optional mode parameter for permissions:

python
from pathlib import Path

Path("/var/app/secrets").mkdir(parents=True, exist_ok=True, mode=0o750)

Choosing Between pathlib and os.makedirs

Featurepathlib.Path.mkdiros.makedirs
Available sincePython 3.4Python 2.0
Object-oriented path handlingYesNo
Chainable with other Path methodsYesNo
exist_ok parameterPython 3.5+Python 3.2+
Typical use caseModern codebasesLegacy code, quick scripts

In new projects, pathlib is the better choice. It integrates naturally with other path operations like .resolve(), .glob(), and / operator for path joining.

Node.js: Recursive fs.mkdir

Node.js 10.12+ supports the recursive option on both synchronous and asynchronous directory creation:

javascript
1const fs = require("fs");
2
3// Synchronous
4fs.mkdirSync("/var/app/data/cache", { recursive: true });
javascript
1const fs = require("fs/promises");
2
3// Async/await
4async function setup() {
5  await fs.mkdir("/var/app/data/cache", { recursive: true });
6  console.log("Directory tree created");
7}
8
9setup();

When recursive is true, the call returns undefined (sync) or resolves (async) without error if the directory already exists. Without it, an EEXIST error is thrown.

For older Node.js versions that lack the recursive option, the mkdirp npm package provides equivalent functionality.

Java: Files.createDirectories

Java's java.nio.file.Files class provides createDirectories, which creates a directory and all nonexistent parent directories:

java
1import java.nio.file.Files;
2import java.nio.file.Path;
3import java.nio.file.Paths;
4
5public class Setup {
6    public static void main(String[] args) throws Exception {
7        Path dir = Paths.get("/var/app/data/cache");
8        Files.createDirectories(dir);
9        System.out.println("Created: " + dir.toAbsolutePath());
10    }
11}

Unlike Files.createDirectory (singular), createDirectories does not throw FileAlreadyExistsException when the target exists, and it creates all missing ancestors. This is the Java equivalent of mkdir -p.

C# and .NET: Directory.CreateDirectory

In .NET, System.IO.Directory.CreateDirectory already handles the full path:

csharp
using System.IO;

Directory.CreateDirectory(@"C:\App\Data\Cache\Thumbnails");

This method creates every directory in the specified path that does not already exist, and it does not throw if the directory is already present. No special flags are needed because recursive creation and idempotency are the default behavior.

Windows: PowerShell and Command Prompt

PowerShell uses New-Item with the -Force flag:

powershell
New-Item -ItemType Directory -Path "C:\App\Data\Cache" -Force

The -Force flag prevents failure when the directory already exists.

The built-in Windows mkdir command also creates intermediate directories automatically:

cmd
mkdir C:\App\Data\Cache\Thumbnails

Unlike its Unix counterpart, Windows mkdir does not need a -p flag. It creates the full path by default.

Why Idempotence Matters

In automation, the best directory-creation commands are idempotent: running them once or a hundred times produces the same result with no errors. This is why flags like -p, exist_ok=True, and recursive: true exist.

Idempotent directory creation is critical in:

  • CI/CD pipelines: Build steps run on fresh agents and need to set up directories every time.
  • Container entrypoints: Docker containers often create runtime directories on startup.
  • Application initialization: Server processes create log, cache, and upload directories before accepting traffic.
  • Test setup: Test fixtures create temporary directory structures that may already exist from a previous run.

Without idempotency, any re-run of a setup script risks a crash at the first existing directory.

Common Pitfalls

  • Forgetting the recursive flag: The most frequent mistake. Without -p, parents=True, or recursive: true, deep paths fail when any intermediate directory is missing.
  • Permission errors masked by path errors: A "no such file or directory" error sometimes means the parent exists but is not writable. Print the resolved path and check permissions separately.
  • Relative path surprises: Creating build/output/data creates the path relative to the current working directory, which may differ between your terminal, your CI runner, and your application process. Always resolve the path first and log it.
  • Race conditions in concurrent code: Two processes calling mkdir on the same path without exist_ok or recursive can race. One succeeds, the other gets EEXIST. The idempotent flags eliminate this.
  • Manual string concatenation for paths: Building paths with + or string formatting (e.g., base + "/" + subdir) breaks on Windows backslashes. Use pathlib in Python, path.join in Node.js, or Path.Combine in C#.
  • Assuming cross-platform consistency: Unix mkdir without -p fails on existing directories. Windows mkdir succeeds. PowerShell New-Item without -Force succeeds on new directories but fails on existing ones. Always use the idempotent variant.

Summary

  • Use mkdir -p on Unix/Linux/macOS for shell scripts.
  • Use Path.mkdir(parents=True, exist_ok=True) in modern Python, or os.makedirs(path, exist_ok=True) for older codebases.
  • Use fs.mkdirSync(path, { recursive: true }) or the async equivalent in Node.js 10.12+.
  • Use Files.createDirectories(path) in Java.
  • Use Directory.CreateDirectory(path) in C#/.NET, which is recursive and idempotent by default.
  • Use New-Item -ItemType Directory -Force in PowerShell.
  • Always prefer idempotent creation to avoid failures on re-runs, concurrent execution, and CI pipelines.

Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.