Node.js Path Module
The Node.js path module helps you build and take apart file paths. Windows uses backslashes (C:\app\data) while Linux and macOS use forward slashes (/app/data). Gluing strings together by hand breaks across systems; path handles the differences for you.
path.join
join combines segments with the correct separator and cleans up extra slashes and .. parts.
import path from 'node:path';
console.log(path.join('src', 'routes', 'users.js'));
console.log(path.join('/var/www', '../logs', 'app.log'));src/routes/users.js /var/logs/app.log
path.resolve
resolve produces an absolute path. It works from right to left until it builds an absolute path, using the current working directory if needed.
console.log(process.cwd());
console.log(path.resolve('data', 'db.json'));
console.log(path.resolve('/etc', 'nginx.conf'));/home/naeem/api /home/naeem/api/data/db.json /etc/nginx.conf
Taking Paths Apart
const file = '/home/naeem/photos/beach.jpeg';
console.log(path.basename(file));
console.log(path.basename(file, '.jpeg'));
console.log(path.extname(file));
console.log(path.dirname(file));
console.log(path.parse(file));beach.jpeg
beach
.jpeg
/home/naeem/photos
{ root: '/', dir: '/home/naeem/photos', base: 'beach.jpeg', ext: '.jpeg', name: 'beach' }Paths Relative to Your Script
Relative paths are resolved from where you run the command, not where the file lives. To find files next to your script reliably, start from import.meta.dirname.
import path from 'node:path';
import { readFile } from 'node:fs/promises';
const templatePath = path.join(import.meta.dirname, 'templates', 'email.html');
const html = await readFile(templatePath, 'utf8');
console.log('Loaded', html.length, 'characters');Loaded 1834 characters
Path Module Cheat Sheet
- path.join(...parts) — combine segments
- path.resolve(...parts) — make an absolute path
- path.relative(from, to) — path from one location to another
- path.normalize(p) — clean up . and .. segments
- path.isAbsolute(p) — check if a path is absolute
- path.sep — the separator for this OS (\ or /)
Security Note
Never join user input straight into a file path. A request for ../../etc/passwd could escape your folder. Resolve the final path and check it still starts with your allowed base directory before reading the file.
Frequently asked questions
What is the difference between path.join and path.resolve?
join simply combines segments and may return a relative path. resolve always returns an absolute path, using the current working directory as the starting point.
How do I get a file extension in Node.js?
Use path.extname("photo.png"), which returns ".png". Use path.basename(file, ext) to get the name without the extension.
Why does my relative file path not work in Node?
Relative paths are resolved against process.cwd(), the folder you ran node from. Build paths from import.meta.dirname to make them relative to the script itself.