fs
Filesystem operations using POSIX file I/O. Both sync and async APIs are available.
Synchronous
fs.readFileSync(path)
Read the entire contents of a file as a string.
const content = fs.readFileSync("data.txt");
console.log(content);Returns an empty string if the file doesn't exist.
When the result is assigned to a Uint8Array variable, the file is read in binary mode ("rb") and the raw bytes are returned:
const data: Uint8Array = fs.readFileSync("image.png");
console.log(data.length); // exact byte count, including null bytesfs.writeFileSync(path, data)
Write a string to a file, replacing the file if it already exists.
fs.writeFileSync("output.txt", "hello world");When the second argument is a Uint8Array, the file is written in binary mode using the array's length (not strlen), so null bytes are preserved:
const data = new Uint8Array(4);
data[0] = 0x89;
data[1] = 0x50;
data[2] = 0x00; // null byte — preserved in binary write
data[3] = 0x47;
fs.writeFileSync("output.bin", data);Returns 0 on success, -1 on error.
fs.appendFileSync(path, data)
Append a string to a file.
fs.appendFileSync("log.txt", "new line\n");fs.existsSync(path)
Check if a file exists.
if (fs.existsSync("config.json")) {
const cfg = fs.readFileSync("config.json");
}fs.unlinkSync(path)
Delete a file.
fs.unlinkSync("temp.txt");Returns 0 on success, -1 on error.
fs.mkdirSync(path)
Create a directory.
fs.mkdirSync("output");fs.readdirSync(path)
List files in a directory. Excludes . and ...
const files = fs.readdirSync(".");
files.forEach((f: string) => {
console.log(f);
});fs.statSync(path)
Get file metadata.
const stat = fs.statSync("data.txt");
console.log(stat.size); // number — file size in bytes
console.log(stat.isFile); // boolean
console.log(stat.isDirectory); // booleanfs.renameSync(oldPath, newPath)
Rename or move a file.
fs.renameSync("old.txt", "new.txt");fs.copyFileSync(src, dest)
Copy a file.
fs.copyFileSync("original.txt", "backup.txt");Async (Promise-based)
All async methods return a Promise and run on the libuv thread pool via uv_queue_work.
fs.readFile(path)
const content: string = await fs.readFile("data.txt");fs.writeFile(path, data)
await fs.writeFile("output.txt", "hello");fs.readdir(path)
const files: string[] = await fs.readdir(".");fs.stat(path)
const stat = await fs.stat("data.txt");
console.log(stat.size);fs.unlink(path)
await fs.unlink("temp.txt");fs.mkdir(path)
await fs.mkdir("output");fs.appendFile(path, data)
await fs.appendFile("log.txt", "new line\n");fs.rename(oldPath, newPath)
await fs.rename("old.txt", "new.txt");fs.copyFile(src, dest)
await fs.copyFile("original.txt", "backup.txt");Native Implementation
| API | Maps to |
|---|---|
fs.readFileSync() | fopen() + fread() |
fs.writeFileSync() | fopen() + fwrite() |
Binary utilities
Uint8Array.fromRawBytes(data, len)
Wraps a raw pointer and byte length into a Uint8Array without copying. Useful when you already have a byte buffer and its length:
const bytes = Uint8Array.fromRawBytes(c.req.body, c.req.bodyLen);
fs.writeFileSync("upload.bin", bytes);Buffer.from(str, 'base64')
Decodes a base64 string into a Uint8Array:
const bytes: Uint8Array = Buffer.from("SGVsbG8gV29ybGQ=", "base64");
fs.writeFileSync("decoded.bin", bytes);Also strips data:...;base64, prefixes automatically, so data URLs work directly:
const bytes: Uint8Array = Buffer.from("data:image/jpeg;base64,/9j/4AAQ...", "base64");
fs.writeFileSync("image.jpg", bytes);POSIX mapping
| fs.existsSync() | access() | | fs.unlinkSync() | unlink() | | fs.readdirSync() | opendir() + readdir() | | fs.statSync() | stat() | | fs.renameSync() | rename() | | fs.copyFileSync() | fopen() + fread() + fwrite() | | Async variants | Same POSIX calls on uv_queue_work thread pool |