Introduction
Node.js resolves relative paths from the current working directory (process.cwd()), not from the file where the code is written. When the application is started from a different directory, deployed to a different location, or run from a different context, relative paths break with ENOENT "No such file or directory" errors.
This is a common issue in Node.js applications that reference configuration files, templates, or static assets using relative paths.
Symptoms
- Node.js throws "Error: ENOENT: no such file or directory, open './config/settings.json'"
- File exists but Node.js cannot find it at runtime
- Application works when run from one directory but fails from another
Common Causes
- Relative path resolves from process.cwd() which varies depending on how the app is started
- File path uses ./ or ../ which is relative to the working directory, not the source file
- Deployment changes the directory structure from development environment
Step-by-Step Fix
- 1.Use __dirname for paths relative to the current file: Resolve from the source file location.
- 2.```javascript
- 3.const path = require('path');
- 4.const fs = require('fs');
// BAD: resolves from process.cwd(), not this file's directory const config = JSON.parse(fs.readFileSync('./config/settings.json', 'utf8'));
// GOOD: resolves from this file's directory const configPath = path.join(__dirname, 'config', 'settings.json'); const config = JSON.parse(fs.readFileSync(configPath, 'utf8')); ```
- 1.Use path.resolve for absolute paths: Create fully qualified paths.
- 2.```javascript
- 3.const path = require('path');
// __dirname is always the directory of the current module const absolutePath = path.resolve(__dirname, '..', 'data', 'file.txt'); // On Linux: /home/user/project/data/file.txt // On Windows: C:\Users\user\project\data\file.txt
// For project root from any nested file: const rootPath = path.resolve(__dirname, '..'); const configPath = path.join(rootPath, 'config', 'default.json'); ```
- 1.Use import.meta.url for ES modules: ES modules don't have __dirname.
- 2.```javascript
- 3.import { fileURLToPath } from 'url';
- 4.import { dirname, join } from 'path';
- 5.import { readFileSync } from 'fs';
// ES modules equivalent of __dirname: const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename);
const configPath = join(__dirname, 'config', 'settings.json'); const config = JSON.parse(readFileSync(configPath, 'utf8')); ```
Prevention
- Never use relative paths (./ or ../) for file operations in Node.js
- Always use path.join(__dirname, ...) or path.resolve(__dirname, ...)
- For ES modules, create __dirname from import.meta.url
- Test your application by starting it from different directories