File paths look simple until you remember Windows uses backslashes (C:\Users\name) and macOS/Linux use forward slashes (/home/name). Concatenating path strings by hand — folder + '/' + file — breaks the moment your code runs on a different operating system than the one you tested on. The path module exists to make path handling correct everywhere, automatically.
path.join() — the one you'll use constantly
const path = require('path');
const filePath = path.join('uploads', 'images', 'profile.jpg');
console.log(filePath);
// uploads/images/profile.jpg (on Linux/macOS)
// uploads\images\profile.jpg (on Windows)
path.join() picks the correct separator for whatever OS the code is actually running on, and also cleans up any redundant slashes or .. segments along the way.
path.resolve() — turning a relative path into an absolute one
console.log(path.resolve('uploads', 'profile.jpg'));
// /home/user/project/uploads/profile.jpg
Unlike join(), which just combines segments as given, resolve() builds a full absolute path starting from the current working directory (or an earlier absolute segment, if one is provided).
Pulling a path apart
const fullPath = '/home/user/documents/report.pdf';
console.log(path.basename(fullPath)); // 'report.pdf'
console.log(path.basename(fullPath, '.pdf')); // 'report' — extension stripped
console.log(path.dirname(fullPath)); // '/home/user/documents'
console.log(path.extname(fullPath)); // '.pdf'
Getting every piece at once
console.log(path.parse(fullPath));
// {
// root: '/',
// dir: '/home/user/documents',
// base: 'report.pdf',
// ext: '.pdf',
// name: 'report'
// }
The pairing that solves the most common real bug
Combine __dirname (covered on the Global Objects page) with path.join() and you get a path that's always correct no matter where the project is deployed or from which folder the script happens to be run:
const configPath = path.join(__dirname, 'config', 'settings.json');
Without __dirname, a relative path like './config/settings.json' is resolved against the current working directory — which can be different from the script's own folder depending on where the node command was launched from. This mismatch is one of the more common "works on my machine" bugs, and reaching for path.join(__dirname, ...) sidesteps it entirely.
A quick check for OS-specific separators
console.log(path.sep); // '/' on POSIX systems, '\\' on Windows
console.log(path.delimiter); // ':' on POSIX, ';' on Windows — used when joining PATH-like lists
Rarely needed directly, but handy on the rare occasion your code has to work with raw separator characters itself.