Use the built-in fs module, which offers each read and write operation in three styles. The callback and promise versions hand the disk work to libuv's thread pool, a few background threads, so the server keeps answering other requests. The Sync versions block the event loop until the disk responds.
const fs = require('fs');
// Asynchronous (recommended)
fs.readFile('input.txt', 'utf8', (err, data) => {
if (err) return console.error(err);
console.log('File content:', data);
});
fs.writeFile('output.txt', 'Hello World', (err) => {
if (err) return console.error(err);
console.log('File written successfully');
});
// Synchronous (blocking)
try {
const data = fs.readFileSync('input.txt', 'utf8');
fs.writeFileSync('output.txt', data.toUpperCase());
} catch (err) {
console.error('Error:', err);
}
// Promise-based
const fsPromises = require('fs').promises;
fsPromises.readFile('input.txt', 'utf8').then((text) => console.log(text)).catch(console.error);
In server code, use an asynchronous style. The promise version also works with await inside an async function. Use the Sync calls only in startup code and command-line scripts, where blocking does not matter.
This answer doesn't lend itself to a diagram - it reads best . No credits were charged.
Why there's no diagram: “”
The interactive diagram is below the answer - jump to diagram ↓ · Below it, the related concept . Jump to it ↓
The diagram below the answer is the concept . Jump to it ↓