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. 1.Use __dirname for paths relative to the current file: Resolve from the source file location.
  2. 2.```javascript
  3. 3.const path = require('path');
  4. 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. 1.Use path.resolve for absolute paths: Create fully qualified paths.
  2. 2.```javascript
  3. 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. 1.Use import.meta.url for ES modules: ES modules don't have __dirname.
  2. 2.```javascript
  3. 3.import { fileURLToPath } from 'url';
  4. 4.import { dirname, join } from 'path';
  5. 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