| name | Bun File I/O |
| description | Use for Bun file I/O: Bun.file, Bun.write, streams, directories, glob patterns, metadata. |
Bun File I/O
Bun provides fast, optimized file operations via Bun.file() and Bun.write().
Reading Files
Bun.file()
const file = Bun.file("./data.txt");
console.log(file.size);
console.log(file.type);
console.log(file.name);
console.log(await file.exists());
const text = await file.text();
const json = await file.json();
const buffer = await file.arrayBuffer();
const bytes = await file.bytes();
const stream = file.stream();
Read Specific Types
const config = await Bun.file("config.json").json();
const content = await Bun.file("readme.md").text();
const binary = await Bun.file("image.png").arrayBuffer();
import data from "./data.json" with { type: "json" };
import text from "./content.txt" with { type: "text" };
Writing Files
Bun.write()
await Bun.write("./output.txt", "Hello World");
await Bun.write("./data.json", JSON.stringify({ key: "value" }, null, 2));
await Bun.write("./output.bin", new Uint8Array([1, 2, 3]));
const response = await fetch("https://example.com/image.png");
await Bun.write("./image.png", response);
await Bun.write("./copy.txt", Bun.file("./original.txt"));
await Bun.write("./file.txt", "content", {
mode: 0o644,
});
Appending
const file = Bun.file("./log.txt");
const writer = file.writer();
writer.write("Line 1\n");
writer.write("Line 2\n");
await writer.flush();
writer.end();
import { appendFile } from "node:fs/promises";
await appendFile("./log.txt", "New line\n");
Streaming
Read Stream
const file = Bun.file("./large-file.txt");
const stream = file.stream();
const reader = stream.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
console.log(value);
}
Write Stream
const file = Bun.file("./output.txt");
const writer = file.writer();
for await (const chunk of dataSource) {
writer.write(chunk);
}
await writer.end();
Pipe Streams
const input = Bun.file("./input.txt");
const output = Bun.file("./output.txt");
await Bun.write(output, input);
const response = await fetch(url);
await Bun.write("./download.zip", response);
const file = Bun.file("./data.txt");
const stream = file.stream();
const transformed = stream.pipeThrough(
new TransformStream({
transform(chunk, controller) {
controller.enqueue(chunk.toUpperCase());
},
})
);
Directory Operations
import { readdir, mkdir, rmdir, stat } from "node:fs/promises";
import { existsSync, mkdirSync } from "node:fs";
const files = await readdir("./src");
const filesWithTypes = await readdir("./src", { withFileTypes: true });
for (const entry of filesWithTypes) {
if (entry.isDirectory()) {
console.log(`Dir: ${entry.name}`);
} else if (entry.isFile()) {
console.log(`File: ${entry.name}`);
}
}
await mkdir("./new-dir", { recursive: true });
await rmdir("./old-dir", { recursive: true });
const exists = existsSync("./path");
Glob Patterns
const glob = new Bun.Glob("**/*.ts");
for await (const file of glob.scan({ cwd: "./src" })) {
console.log(file);
}
const files = await Array.fromAsync(glob.scan("./src"));
const glob2 = new Bun.Glob("**/*.{ts,tsx}");
for await (const file of glob2.scan({
cwd: "./src",
dot: true,
absolute: true,
onlyFiles: true,
})) {
console.log(file);
}
const pattern = new Bun.Glob("*.ts");
pattern.match("file.ts");
pattern.match("file.js");
File Metadata
import { stat, lstat } from "node:fs/promises";
const stats = await stat("./file.txt");
console.log(stats.size);
console.log(stats.isFile());
console.log(stats.isDirectory());
console.log(stats.isSymbolicLink());
console.log(stats.mtime);
console.log(stats.ctime);
console.log(stats.atime);
console.log(stats.mode);
Path Operations
import { join, dirname, basename, extname, resolve } from "node:path";
const filePath = "/home/user/project/src/index.ts";
join("a", "b", "c");
dirname(filePath);
basename(filePath);
basename(filePath, ".ts");
extname(filePath);
resolve("./relative");
import.meta.dir;
import.meta.file;
import.meta.path;
Common Patterns
Read JSON Config
async function loadConfig<T>(path: string): Promise<T> {
const file = Bun.file(path);
if (!(await file.exists())) {
throw new Error(`Config not found: ${path}`);
}
return file.json();
}
const config = await loadConfig<AppConfig>("./config.json");
Copy Directory
import { readdir, mkdir, stat } from "node:fs/promises";
import { join } from "node:path";
async function copyDir(src: string, dest: string) {
await mkdir(dest, { recursive: true });
for (const entry of await readdir(src, { withFileTypes: true })) {
const srcPath = join(src, entry.name);
const destPath = join(dest, entry.name);
if (entry.isDirectory()) {
await copyDir(srcPath, destPath);
} else {
await Bun.write(destPath, Bun.file(srcPath));
}
}
}
Watch Files
import { watch } from "node:fs";
watch("./src", { recursive: true }, (event, filename) => {
console.log(`${event}: ${filename}`);
});
const watcher = Bun.spawn(["bun", "--watch", "src/index.ts"]);
Temp Files
import { mkdtemp } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
const tempDir = await mkdtemp(join(tmpdir(), "app-"));
console.log(tempDir);
const tempFile = join(tempDir, "data.txt");
await Bun.write(tempFile, "temporary data");
Common Errors
| Error | Cause | Fix |
|---|
ENOENT | File not found | Check path, use exists() |
EACCES | Permission denied | Check file permissions |
EISDIR | Is a directory | Use readdir() for directories |
EEXIST | Already exists | Use recursive: true for mkdir |
When to Load References
Load references/streams-advanced.md when:
- Transform streams
- Compression streams
- Binary protocols
Load references/performance.md when:
- Large file handling
- Memory optimization
- Concurrent operations