I/O#
JavaScript’s I/O surface depends on the host. In Node (and Deno
/ Bun in Node-compat mode), reach for
node:fs/promises for files, node:stream for streams,
console and process.stdin/stdout/stderr for the standard
streams, JSON for serialisation, and Buffer / typed
arrays for binary data. In the browser, fetch, File,
Blob, ReadableStream, and FormData cover the same
ground.
This page leans on Node since that is where most CLI / server work happens. For networking I/O, see Networking. For CLI argument handling, see CLI.
Files#
node:fs/promises is the async surface. The synchronous
mirror (readFileSync, writeFileSync) lives on
node:fs and avoid it outside startup code.
import {readFile, writeFile, appendFile, rename} from "node:fs/promises";
const data = await readFile("config.json", "utf8");
await writeFile("out.txt", "hello\n");
await appendFile("log.txt", `${Date.now()}\n`);
await rename("tmp.json", "config.json");
Pass "utf8" (or the encoding) for text; omit it to get a
Buffer.
const raw = await readFile("logo.png"); // Buffer
const txt = await readFile("notes.md", "utf8");
Paths#
node:path joins and resolves; import.meta.url and
fileURLToPath locate the current module.
import {join, dirname, resolve} from "node:path";
import {fileURLToPath} from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
const configPath = join(__dirname, "config.json");
Streams#
Streams move data without buffering the whole payload. The
operator uses createReadStream for large files and
pipeline to chain stages.
import {createReadStream} from "node:fs";
import {createInterface} from "node:readline";
const rl = createInterface({input: createReadStream("/var/log/syslog")});
for await (const line of rl) {
if (line.includes("error")) console.log(line);
}
import {pipeline} from "node:stream/promises";
import {createWriteStream} from "node:fs";
import {createGzip} from "node:zlib";
await pipeline(
createReadStream("input.txt"),
createGzip(),
createWriteStream("input.txt.gz"),
);
Standard streams#
process.stdin, process.stdout, process.stderr are
the Node-side streams. console.log writes to stdout;
console.error writes to stderr.
import {createInterface} from "node:readline";
for await (const line of createInterface({input: process.stdin})) {
process.stdout.write(line.toUpperCase() + "\n");
}
console.error("debug:", obj);
JSON#
JSON.parse and JSON.stringify are the surface. The
operator passes a reviver on parse to transform values, and a
replacer plus an indent on stringify for safe / pretty
output.
const obj = JSON.parse('{"name":"rk","ts":"2026-01-01"}', (k, v) =>
k === "ts" ? new Date(v) : v
);
const pretty = JSON.stringify(obj, null, 2);
const safe = JSON.stringify(obj, (k, v) =>
k === "password" ? undefined : v // drop secrets
);
JSON.stringify throws on circular references and silently
drops functions, undefined, and symbol values. For
complex structures (Map, Set, Date, typed arrays,
cycles) use structuredClone or a library
(superjson).
Binary data#
Node’s Buffer is a subclass of Uint8Array with
hex / base64 / utf-8 helpers. The operator stays on Buffer
for Node code and on Uint8Array for portable code.
const buf = Buffer.from("hello", "utf8");
buf.toString("hex"); // "68656c6c6f"
buf.toString("base64"); // "aGVsbG8="
const fromHex = Buffer.from("48656c6c6f", "hex");
const u8 = new Uint8Array([0x48, 0x69]);
const text = new TextDecoder("utf-8").decode(u8);
const bytes = new TextEncoder().encode(text);
For binary parsing, DataView reads typed values out of an
ArrayBuffer with explicit endianness.
const view = new DataView(buf.buffer);
const port = view.getUint16(0, false); // big-endian
Console#
console.log / error / warn / info /
debug / trace write structured output. console.table
is useful for arrays of objects; console.dir shows objects
with depth.
console.table([{ip: "1.2.3.4", port: 80}, {ip: "5.6.7.8", port: 443}]);
console.dir(deep, {depth: null, colors: true});
References#
Types for
stringandobjectsemantics underlying JSON.CLI for
process.argvand CLI plumbing.Networking for sockets and HTTP.
Runtime for
processand the Node environment.