Skip to content

Node.js path Module

File paths look different on Windows (C:\\Users\\me) than on macOS or Linux (/Users/me). The path module lets you build and inspect file paths in a way that works correctly on every operating system.

What Is the path Module?

path is a built-in Node.js module for working with file and directory paths. Instead of concatenating strings with / (which breaks on Windows) or \\ (which breaks everywhere else), you use path.join(), path.resolve(), and related helpers that handle platform differences automatically.

It also provides helpers to pull apart a path into useful pieces: the directory (dirname), the file name (basename), and the extension (extname), which are used constantly when working with uploads, logs, and static assets.

import path from 'node:path';

const fullPath = path.join('uploads', '2026', 'report.pdf');
console.log(fullPath); // 'uploads/2026/report.pdf' (or backslashes on Windows)

console.log(path.basename(fullPath)); // 'report.pdf'
console.log(path.extname(fullPath));  // '.pdf'
console.log(path.dirname(fullPath));  // 'uploads/2026'

path.join() automatically inserts the correct separator (/ or \\) for the current operating system, so the same code works everywhere.

Core path Methods

path.join(...segments)       // combine segments into one path
path.resolve(...segments)     // combine into an absolute path
path.basename(p)              // final segment, e.g. file name
path.dirname(p)                // parent directory
path.extname(p)                // file extension
  • path.join() combines segments but does not guarantee an absolute path.
  • path.resolve() always returns an absolute path, resolved against the current working directory if needed.
  • path.basename(p, ext) can optionally strip a known extension from the result.
  • path.sep gives the platform-specific separator (/ or \\) if you ever need it directly.

path Module Cheatsheet

The path helpers used in almost every file-handling Node.js script.

Method Example Input Example Output
path.join() path.join('a', 'b', 'c.txt') 'a/b/c.txt'
path.resolve() path.resolve('c.txt') /current/working/dir/c.txt
path.basename() path.basename('/a/b/c.txt') 'c.txt'
path.dirname() path.dirname('/a/b/c.txt') '/a/b'
path.extname() path.extname('c.txt') '.txt'
path.parse() path.parse('/a/b/c.txt') { dir, base, ext, name }

join() vs resolve()

path.join() simply concatenates segments with the correct separator and normalizes ../. in the result, it does not care whether the final path is absolute or relative. path.resolve() always produces an absolute path, working right-to-left until it has built a complete path, using the current working directory as a starting point if none of the segments are already absolute.

path.join('/a', '/b', 'c.txt');     // '/a/b/c.txt'
path.join('a', '../b', 'c.txt');    // 'b/c.txt'  (relative, .. resolved)

path.resolve('a', 'b', 'c.txt');
// '/current/working/directory/a/b/c.txt' (always absolute)

Combining path With __dirname

A very common real-world pattern is joining __dirname (CommonJS) or a computed equivalent (ES modules) with a relative path, so file lookups work correctly no matter which directory the process was started from.

import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const configPath = path.join(__dirname, 'config', 'default.json');

Common Mistakes

  • Building paths with manual string concatenation (dir + '/' + file) instead of path.join().
  • Assuming path.join() returns an absolute path when it may return a relative one.
  • Forgetting that path.resolve() uses the current working directory, which can differ from the script's own directory.
  • Using forward slashes hardcoded in path logic that later needs to run on Windows.

Key Takeaways

  • The path module builds and inspects file paths in a platform-independent way.
  • path.join() concatenates segments; path.resolve() always returns an absolute path.
  • basename, dirname, and extname extract specific pieces of a path.
  • Combining path.join() with __dirname (or its ESM equivalent) makes file lookups reliable regardless of the current working directory.

Pro Tip

Never hardcode / or \\ in path-building logic, always use path.join()/path.resolve(), even if you only ever plan to deploy to Linux. It costs nothing and prevents subtle bugs on any future Windows-based dev machine or CI runner.