The path Module

Build, Join, and Parse Filesystem Paths — Safely

The path Module

Building paths with string concat breaks on Windows and double slashes. The path module handles it correctly.

3 min read Level 1/5 #nodejs#path#filesystem
What you'll learn
  • Join and resolve paths
  • Extract parts (basename, dirname, extname)
  • Use path.sep correctly

Building paths by string concat is fine until it isn’t: "foo/" + "/bar" gives foo//bar. Different OSes use different separators. The node:path module fixes both.

Join

import { join } from "node:path";

const p = join("src", "components", "Button.tsx");
// "src/components/Button.tsx" (or "src\\components\\Button.tsx" on Windows)

join normalizes slashes — never doubles them, never leaves trailing.

Resolve

resolve builds an absolute path from segments, walking up from process.cwd() if needed:

import { resolve } from "node:path";

resolve("src", "index.js");
// → "/Users/me/project/src/index.js"

resolve("/etc", "host.conf");
// → "/etc/host.conf"

Parsing

import { basename, dirname, extname, parse } from "node:path";

const p = "/Users/me/project/src/Button.tsx";

basename(p);              // "Button.tsx"
basename(p, ".tsx");      // "Button"
dirname(p);               // "/Users/me/project/src"
extname(p);               // ".tsx"

parse(p);
// {
//   root: '/',
//   dir: '/Users/me/project/src',
//   base: 'Button.tsx',
//   ext: '.tsx',
//   name: 'Button'
// }

__dirname Replacement in ESM

CJS has __dirname for free. ESM doesn’t — derive it:

import { fileURLToPath } from "node:url";
import { dirname, join }  from "node:path";

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

const data = join(__dirname, "data", "users.json");

Memorize this snippet — you’ll write it on every ESM project.

Cross-Platform

Always use path.join / path.resolve instead of "a/" + "b/". Same code runs on macOS, Linux, and Windows.

Streams →