NodeJS by Example: Path Module

The Path module provides utilities for working with file and directory paths. It handles the differences between operating systems (Windows uses \, Unix uses /).

Import specific functions from the path module

import { join, resolve, dirname, basename, extname, parse, format, normalize, isAbsolute, relative, sep } from 'node:path';

Joining Paths join() combines path segments using the platform-specific separator. It normalizes the result. Unix: 'users/documents/file.txt' Windows: 'users\\documents\\file.txt' It handles ./ and ../ correctly

const joined = join('users', 'documents', 'file.txt');
console.log('Joined:', joined);

const normalized = join('users', '../admin', './config');
console.log('Normalized:', normalized); // 'admin/config'

Resolving Absolute Paths resolve() creates an absolute path. It processes from right to left until an absolute path is formed. Returns: /current/working/dir/src/utils/helper.js If you provide an absolute path, it uses that as the base

const absolute = resolve('src', 'utils', 'helper.js');
console.log('Absolute:', absolute);

const fromRoot = resolve('/home', 'user', 'file.js');
console.log('From root:', fromRoot); // '/home/user/file.js'

Getting Directory Name dirname() returns the directory portion of a path.

const dir = dirname('/users/admin/config.json');
console.log('Directory:', dir); // '/users/admin'

const parentDir = dirname(dirname('/a/b/c/file.txt'));
console.log('Grandparent:', parentDir); // '/a/b'

Getting File Name basename() returns the last portion of a path. Optionally removes the extension.

const filename = basename('/path/to/file.txt');
console.log('Filename:', filename); // 'file.txt'

const nameOnly = basename('/path/to/file.txt', '.txt');
console.log('Name only:', nameOnly); // 'file'

Getting Extension extname() returns the file extension, including the dot.

const ext = extname('report.pdf');
console.log('Extension:', ext); // '.pdf'

const noExt = extname('Makefile');
console.log('No extension:', noExt); // ''

const multiDot = extname('archive.tar.gz');
console.log('Multi-dot:', multiDot); // '.gz'

Parsing Paths parse() breaks a path into its components: root, dir, base, ext, name. { root: '/', dir: '/home/user/docs', base: 'report.pdf', ext: '.pdf', name: 'report' }

const parsed = parse('/home/user/docs/report.pdf');
console.log('Parsed:', parsed);

Formatting Paths format() is the opposite of parse() - it builds a path from components.

const formatted = format({
  dir: '/home/user',
  name: 'config',
  ext: '.json'
});
console.log('Formatted:', formatted); // '/home/user/config.json'

Normalizing Paths normalize() cleans up a path by resolving . and .. segments and removing redundant separators.

const messy = '/users//admin/../guest/./files';
console.log('Normalized:', normalize(messy)); // '/users/guest/files'

Checking Absolute Paths isAbsolute() returns true if the path is absolute.

console.log('Is absolute /tmp:', isAbsolute('/tmp')); // true
console.log('Is absolute ./src:', isAbsolute('./src')); // false

Relative Paths relative() calculates the relative path between two absolute paths.

const from = '/home/user/projects';
const to = '/home/user/documents/file.txt';
console.log('Relative:', relative(from, to)); // '../documents/file.txt'

Platform Separator sep is the platform-specific path separator.

console.log('Separator:', sep); // '/' on Unix, '\\' on Windows
console.log('Split path:', '/a/b/c'.split(sep)); // ['', 'a', 'b', 'c']

Practical Example Common pattern: get the directory of the current module and build paths from it. Build paths relative to current module

import { fileURLToPath } from 'node:url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

console.log('Current file:', __filename);
console.log('Current dir:', __dirname);

const configPath = join(__dirname, '..', 'config', 'settings.json');
console.log('Config path:', configPath);