🌱BeginnerNode.js Foundations

The path Module

Cross-platform file path manipulation with Node's built-in path module

Overview

File paths look different on Windows (`C:\Users\alice\file.txt`) than on macOS and Linux (`/home/alice/file.txt`). If you hard-code path separators in your Node.js code, your application breaks on a different operating system. The built-in `path` module solves this by providing functions that handle path construction and parsing in a cross-platform way. The most important function to internalize is `path.join()`, which joins segments with the correct separator for the current OS. This means you can write `path.join('src', 'data', 'file.json')` and get `src/data/file.json` on Unix or `src\\data\\file.json` on Windows without any conditional logic. `path.resolve()` builds an absolute path by resolving each segment from right to left until it hits an absolute segment, then fills in the current working directory if needed. This is what you reach for when you need a guaranteed absolute path from a mix of relative segments. The module also includes useful getters: `path.dirname(p)` returns the directory portion of a path, `path.basename(p)` returns the filename (optionally stripping an extension), and `path.extname(p)` returns the file extension. These are especially handy when building build tools, CLI scripts, or any code that manipulates file trees.

Key Points

  • β€’path.join() assembles path segments with the OS-correct separator β€” use this everywhere instead of string concatenation
  • β€’path.resolve() returns an absolute path, resolving relative segments against process.cwd() if needed
  • β€’path.dirname(p) returns the directory portion; path.basename(p) returns the filename part
  • β€’path.extname(p) returns the file extension including the dot, e.g. ".json"
  • β€’path.parse(p) returns an object with root, dir, base, name, and ext properties
  • β€’path.sep is the OS-specific separator ('/' on Unix, '\\' on Windows); path.delimiter separates PATH env entries

Examples

path.join β€” safe cross-platform path construction

const path = require('path');

// Safe: works on both Unix and Windows
console.log(path.join('src', 'data', 'users.json'));
// Unix:    src/data/users.json
// Windows: src\data\users.json

// Handles extra/double separators gracefully
console.log(path.join('src/', '/data/', 'file.txt'));
// β†’ src/data/file.txt  (normalises the extra slashes)

path.resolve β€” build absolute paths

const path = require('path');

// process.cwd() is /home/alice/projects
console.log(path.resolve('src', 'index.js'));
// β†’ /home/alice/projects/src/index.js

// An absolute segment resets the base
console.log(path.resolve('/tmp', 'logs', 'app.log'));
// β†’ /tmp/logs/app.log

// Common pattern: resolve relative to the current file
const configPath = path.resolve(__dirname, '..', 'config.json');
// __dirname is the directory of the current file

__dirname gives the directory of the current file and is safe to use with path.resolve.

Parsing and extracting path components

const path = require('path');
const p = '/home/alice/projects/app/src/index.ts';

console.log(path.dirname(p));   // /home/alice/projects/app/src
console.log(path.basename(p));  // index.ts
console.log(path.basename(p, '.ts')); // index  (strip extension)
console.log(path.extname(p));   // .ts

const parsed = path.parse(p);
// {
//   root: '/',
//   dir: '/home/alice/projects/app/src',
//   base: 'index.ts',
//   ext:  '.ts',
//   name: 'index'
// }

path.relative β€” find the relative path between two absolute paths

const path = require('path');

const from = '/home/alice/projects/app/src';
const to   = '/home/alice/projects/app/public/images/logo.png';

console.log(path.relative(from, to));
// β†’ ../public/images/logo.png

// Useful in bundlers and build tools to generate import paths

Common Mistakes

  • String-concatenating paths with '/' directly instead of path.join β€” this breaks on Windows and can create double-slash paths
  • Confusing path.join and path.resolve: join just concatenates, resolve produces an absolute path using cwd as the base
  • Using __filename instead of __dirname when you need the directory β€” __filename is the full file path, __dirname is its parent directory
  • Forgetting that path.resolve with no arguments returns process.cwd(), not the current file's directory

Note

Use `path.resolve(__dirname, 'relative/path')` when you need a file path relative to the source file β€” this is robust regardless of where you invoke the script from. Using `path.join(process.cwd(), 'relative/path')` works only when you run the script from the right directory.

Exercises

Write Node.js code in your local terminal. Use the editor below to follow along, then mark each exercise as done once it works.

Loading editor…

Completed: 0 / 6 exercises

Knowledge Check

Question 1 of 4

What is the key difference between path.join() and path.resolve()?