Skip to content

File System

Node ships the same filesystem operations in three distinct APIs:

StyleImportWhen to use
Callback (async)import fs from 'node:fs'Legacy code, Node streams
Synchronousimport fs from 'node:fs'CLI scripts, startup-time config
Promise (async)import fs from 'node:fs/promises'All new server code
import fs from 'node:fs';
fs.readFile('./hello.txt', 'utf8', function(err, data) {
if (err) throw err;
console.log(data);
});
Node.js

Needs the Node.js runtime — open in StackBlitz to run.

writeFile creates the file if it does not exist and replaces the contents if it does. Use appendFile to add to an existing file.

Node.js

Needs the Node.js runtime — open in StackBlitz to run.

Node.js

Needs the Node.js runtime — open in StackBlitz to run.

import { readFileSync } from 'node:fs';
// Acceptable at startup — process has not yet started accepting requests
const config = JSON.parse(readFileSync('./config.json', 'utf8'));

Never call readFileSync inside a request handler, route callback, or any function invoked after the server starts.

Why should you avoid fs.readFileSync inside a server request handler?
What does fs.writeFile do if the target file already exists?
Which import gives you the promise-based fs API?