Node.js Path Module
The path module provides cross-platform utilities for building, parsing, and normalizing file system paths without hand-rolling string concatenation.
Why Use the path Module
It's tempting to build a file path by gluing strings together with a forward slash, but that approach breaks the moment your code runs on Windows, where paths use backslashes, or when a folder name accidentally contains a trailing slash. Node's core path module, brought in with require('node:path'), abstracts away those operating-system differences so the same code produces a correct path on Linux, macOS, and Windows alike.
Joining and Resolving Paths
path.join() takes any number of path segments, concatenates them with the correct separator for the current OS, and normalizes the result (collapsing things like './' and resolving '..'). path.resolve() does something subtly different: it processes segments from right to left, building an absolute path, and stops as soon as it has constructed one—falling back to the current working directory if none of the segments were already absolute. In practice, join() is what you reach for to combine known pieces, while resolve() is what you reach for when you need a guaranteed absolute path.
- path.join(...segments) — combines segments into one normalized path
- path.resolve(...segments) — builds an absolute path, resolving against the current working directory if needed
- path.basename(path) — returns the last portion of a path (the file or folder name)
- path.extname(path) — returns the file extension, including the leading dot
- path.dirname(path) — returns everything before the last segment
- path.parse(path) — returns an object with root, dir, base, ext, and name all at once
join() vs resolve()
const path = require('node:path');
const joined = path.join('users', 'alice', '..', 'bob', 'notes.txt');
console.log(joined); // users/bob/notes.txt (segments combined and normalized)
const resolved = path.resolve('users', 'bob', 'notes.txt');
console.log(resolved); // e.g. /home/project/users/bob/notes.txt (absolute path)
const resolvedFromRoot = path.resolve('/etc', 'config', 'app.json');
console.log(resolvedFromRoot); // /etc/config/app.json — stops once absoluteExtracting Path Components
Once you have a path, you often need to pull out just one piece of it: the directory it lives in, its file name, or its extension. path.dirname, path.basename, and path.extname each isolate one component, while path.parse hands back all of them at once as a plain object—useful when you need several pieces and don't want to call multiple functions.
Extracting components from a path
const path = require('node:path');
const filePath = '/projects/app/src/index.js';
console.log(path.dirname(filePath)); // /projects/app/src
console.log(path.basename(filePath)); // index.js
console.log(path.extname(filePath)); // .js
// Strip the extension by passing it as the second argument to basename
console.log(path.basename(filePath, path.extname(filePath))); // index
console.log(path.parse(filePath));
// { root: '/', dir: '/projects/app/src', base: 'index.js', ext: '.js', name: 'index' }Building an absolute path relative to the current file
const path = require('node:path');
// __dirname is the directory of the currently executing file
const dataFilePath = path.join(__dirname, 'data', 'users.json');
console.log(dataFilePath);
// e.g. /home/project/scripts/data/users.json — correct on every OSExercise: Node.js Path Module
What is the main purpose of Node.js's path module?