Append data to a file in Node.js
Append with callback, promise, synchronous, or stream APIs, and preserve write ordering and backpressure when records matter.
Use appendFile() for occasional additions and a write stream with { flags: 'a' } for sustained output. Both can create a missing file, but neither creates missing parent directories automatically.
Append with a callback
const fs = require('node:fs');
fs.appendFile('log.txt', 'A new line\n', 'utf8', (error) => {
if (error) {
console.error('Append failed:', error.message);
return;
}
console.log('Append completed');
});
Appending retains the existing content. writeFile() also creates a missing file, but normally replaces existing content because its default flag is w. File creation is not the distinction between the two APIs.
Use promises or a synchronous call
In an ES module:
import { appendFile } from 'node:fs/promises';
await appendFile('log.txt', 'Another line\n', 'utf8');
For a short CommonJS script where blocking is acceptable:
const fs = require('node:fs');
fs.appendFileSync('log.txt', 'A synchronous line\n', 'utf8');
Synchronous filesystem operations block the calling JavaScript thread. Prefer asynchronous operations in request handlers, and handle their failures at the application's error boundary.
Stream repeated output
A stream avoids reopening the file for every record. This ES module uses a pipeline so backpressure and stream errors are handled together:
import { createWriteStream } from 'node:fs';
import { Readable } from 'node:stream';
import { pipeline } from 'node:stream/promises';
await pipeline(
Readable.from(['First block\n', 'Second block\n']),
createWriteStream('big.log', { flags: 'a', encoding: 'utf8' }),
);
For a large source, supply an iterator or stream that produces chunks as needed. Wrapping an already enormous string in a stream does not undo the memory used to create it. If you call stream.write() directly, honor a false return value by waiting for backpressure to clear, handle errors, and call end() when finished.
| Workload | Suitable API |
|---|---|
| A few occasional records | fs.promises.appendFile |
| A small blocking script | fs.appendFileSync |
| Repeated or large output | A write stream with flags: 'a' |
FAQ
Can writeFile append? Yes, writeFile(path, data, { flag: 'a' }) selects append mode. appendFile() makes the intent easier to recognize. Notice the singular flag for these convenience calls and plural flags for createWriteStream().
Are concurrent appends ordered? Do not assume call order becomes record order. Serialize operations or use one managed writer when ordering matters. A logical application record may involve multiple system writes; separate processes and network filesystems require additional coordination.
Why are characters corrupted? Use the same encoding when writing and reading strings. Buffer data already contains bytes; do not reinterpret binary bytes as text unless that conversion is intended.
Does completion mean the data survived a power failure? Not necessarily. Successful writing and durable storage are different guarantees. Choose explicit synchronization or an appropriate logging/storage system if durability is part of the requirement.
References
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan