Skip to content

Node.js Path Module — Complete Guide to File Path Operations

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about Node.js Path Module. We cover key concepts, practical examples, and best practices to help you master this topic.

The Node.js path module provides utilities for working with file and directory paths across platforms, handling separators, normalization, and resolution consistently.

What You'll Learn

By the end of this tutorial, you'll use path.join, path.resolve, path.basename, path.dirname, path.extname, and other methods to manipulate file paths reliably on any operating system.

Why Path Module Matters

Different operating systems use different path separators (Windows uses backslash, Linux uses forward slash). The path module abstracts these differences, preventing bugs when your code runs on different platforms.

Real-World Use

A file upload service needs to construct safe file paths for saving uploaded files to disk, extracting extensions for validation, and resolving relative paths to absolute ones.

Path Module Learning Path

flowchart LR
  A[ES Modules] --> B[Path Module]
  B --> C[File System]
  C --> D[Streams]
  D --> E[Express.js]
  A --> F{You Are Here}
  style F fill:#f90,color:#fff

path.join and path.resolve

path.join joins path segments using the platform separator. path.resolve resolves to an absolute path.

import path from "node:path";

const joined = path.join("users", "john", "docs", "file.txt");
console.log(joined);  // users/john/docs/file.txt

const resolved = path.resolve("docs", "file.txt");
console.log(resolved);  // /home/user/project/docs/file.txt

path.resolve processes from right to left, prepending the current working directory until an absolute path is found.

path.basename, path.dirname, path.extname

These extract parts of a path.

const filePath = "/home/user/project/src/app.js";

console.log(path.basename(filePath));       // app.js
console.log(path.basename(filePath, ".js")); // app
console.log(path.dirname(filePath));        // /home/user/project/src
console.log(path.extname(filePath));        // .js

path.parse and path.format

parse breaks a path into components. format reconstructs it.

const parsed = path.parse("/home/user/project/src/app.js");
console.log(parsed);
// {
//   root: '/',
//   dir: '/home/user/project/src',
//   base: 'app.js',
//   ext: '.js',
//   name: 'app'
// }

const formatted = path.format({ dir: "/home/user", base: "config.json" });
console.log(formatted);  // /home/user/config.json

path.normalize

Normalizes a path, resolving .. and . segments and converting separators.

const messy = "/users//john/../docs/./file.txt";
const clean = path.normalize(messy);
console.log(clean);  // /users/docs/file.txt

path.relative

Computes the relative path from one absolute path to another.

const from = "/data/projects/app/config";
const to = "/data/projects/app/src/utils/helper.js";
const relative = path.relative(from, to);
console.log(relative);  // ../src/utils/helper.js

Platform Path Properties

console.log(path.sep);   // / on Linux, \ on Windows
console.log(path.delimiter);  // : on Linux, ; on Windows
console.log(path.win32);  // Windows implementation
console.log(path.posix);  // POSIX implementation

Use path.posix.join() if you need forward slashes even on Windows.

Common Mistakes

1. String Concatenation Instead of path.join

path.join("dir", "file") handles separators correctly. String concatenation with + does not.

2. Assuming Forward Slashes on Windows

Hardcoded paths with forward slashes fail on Windows. Always use path methods.

3. Using path.resolve Without Understanding CWD

path.resolve("config") prepends Process.cwd(). If the working directory changes, the result changes.

4. Forgetting Trailing Separator in path.join

path.join("/data", "files/") and path.join("/data", "files") both produce the same result. No trailing slash.

5. Not Normalizing User-Provided Paths

User input like ../../etc/passwd can escape intended directories. Always normalize and validate.

Practice Questions

1. What is the difference between path.join and path.resolve?

path.join simply joins segments with separators. path.resolve produces an absolute path by prepending the current directory if needed.

2. What does path.basename("/a/b/c.js", ".js") return?

It returns "c". The second argument strips the extension.

3. How do you get just the file name without extension?

path.basename(file, path.extname(file)) or use path.parse(file).name.

4. Why should path methods be used instead of string manipulation?

Path methods handle platform differences, normalize separators, resolve relative paths, and prevent directory traversal vulnerabilities.

5. Challenge: Write a function that safely resolves a user-provided filename within a base directory, preventing directory traversal.

import path from "node:path";
function safeResolve(baseDir, userPath) {
  const fullPath = path.resolve(baseDir, userPath);
  if (!fullPath.startsWith(path.resolve(baseDir))) {
    throw new Error("Path traversal detected");
  }
  return fullPath;
}
console.log(safeResolve("/data/uploads", "profile.jpg"));
// /data/uploads/profile.jpg

FAQ

Is the path module available in the browser?

No. The path module is Node.js specific. Browsers use the URL API for path-like operations.

What is the difference between path.posix and path.win32?

path.posix always uses forward slashes. path.win32 uses backslashes. The default path module uses the current platform's implementation.

Does path.resolve work with relative paths?

Yes, it prepends process.cwd() to relative paths to produce an absolute result.

How do I check if a path is absolute?

Use path.isAbsolute('/foo') which returns true for absolute paths on the current platform.

What happens if path.join receives no arguments?

It returns '.' (current directory).

Mini Project: File Organizer

Create a script that organizes files by extension using path operations.

import fs from "node:fs";
import path from "node:path";
const targetDir = process.argv[2] || ".";
const files = fs.readdirSync(targetDir);
for (const file of files) {
  const ext = path.extname(file).slice(1) || "noext";
  const extDir = path.join(targetDir, ext);
  if (!fs.existsSync(extDir)) fs.mkdirSync(extDir);
  const src = path.join(targetDir, file);
  const dest = path.join(extDir, file);
  if (fs.statSync(src).isFile()) fs.renameSync(src, dest);
}
console.log("Files organized by extension.");

What's Next

Node.js File System Node.js Streams Express.js

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro