Files and paths
How to use the Node.js fs module with async/await
Learn how to use the Node.js fs module with async/await through the promise-based node:fs/promises API, so you can await calls like fs.readdir() directly.
8 minute lesson
Node’s filesystem module has a stable promise API in node:fs/promises:
import { readFile, readdir } from 'node:fs/promises'
const posts = await readdir('content')
const configText = await readFile('config.json', 'utf8')
const config = JSON.parse(configText)
The node: prefix makes it explicit that this is a Node built-in rather than a package from node_modules. readFile() returns a Buffer unless you request an encoding such as 'utf8'.
An awaited filesystem failure rejects the promise. Catch errors where you can add useful context or make a specific recovery decision:
async function loadOptionalConfig(path) {
try {
return JSON.parse(await readFile(path, 'utf8'))
} catch (error) {
if (error.code === 'ENOENT') return {}
throw new Error(`Cannot load ${path}`, { cause: error })
}
}
Do not turn every error into an empty value. ENOENT means the path is missing; invalid JSON, permission errors, and I/O failures should remain visible.
Avoid checking with access() before reading. The file can change between the check and the read. Attempt the real operation and handle its result.
Promise-based filesystem work uses Node’s worker pool, so it does not block the event-loop thread while waiting for ordinary file I/O. It is not automatically safe to launch overlapping writes to the same file. Those operations are not synchronized and can overwrite or corrupt the intended result.
Use new URL('./config.json', import.meta.url) when a resource belongs beside an ES module. Use a path relative to process.cwd() when the caller deliberately selects a file from the working directory.
Your action is to load one valid JSON file, one missing file, and one malformed file. Recover only from ENOENT, preserve the original error as cause for the others, and explain why a preflight existence check would still race.
Lesson completed