Files and paths
Choose a filesystem API style
Choose between synchronous, callback, and promise-based filesystem operations according to where the code runs.
8 minute lesson
Node exposes synchronous, callback, and promise-based filesystem APIs.
The three forms have different completion and error behavior:
import { readFileSync, readFile } from 'node:fs'
import { readFile as readFilePromise } from 'node:fs/promises'
const text = readFileSync('note.txt', 'utf8')
readFile('note.txt', 'utf8', (error, value) => {
if (error) return console.error(error)
console.log(value)
})
const value = await readFilePromise('note.txt', 'utf8')
The synchronous call blocks the event-loop thread until the filesystem operation finishes and throws an exception on failure. That can be acceptable for a tiny one-shot CLI or essential startup file before a server listens. It is dangerous inside a request handler because every client waits.
Callback and promise operations run asynchronously, normally using Node’s worker pool for filesystem work. The callback form passes the error first. The promise form rejects and fits naturally with await and try/catch.
Use node:fs/promises for clarity in most application code. Callback APIs can use less allocation and may matter in a measured, extremely hot path. Do not choose them merely because they look “lower level.”
Asynchronous does not mean synchronized. Two concurrent writes to the same file can race regardless of whether callbacks or promises are used. Serialize related modifications or use storage designed for concurrent writers.
For very large files, use streams instead of reading the complete contents into memory.
Streams control memory by processing chunks and can respect backpressure between a fast reader and a slower destination. They do not automatically make CPU-heavy processing non-blocking.
Your action is to read the same missing file with all three API styles and capture how each reports the error. Then place the synchronous version inside a timer-driven demo and observe which scheduled callback is delayed.
Lesson completed