How to Perform File System Operations Using Bun.file in Bun
Bun.file creates a BunFile object—a subclass of the standard Blob—that provides async methods for reading, streaming, and inspecting files, while Bun.write() and the writer() handle writing operations.
Bun.file is the primary API for file-system operations in the Bun runtime (oven-sh/bun). It accepts a file path, URL, buffer, or file descriptor and returns a BunFile instance that integrates seamlessly with Web APIs like Fetch and FormData. Because BunFile inherits from Blob, it works natively with new Response(Bun.file(...)) and other web-compatible interfaces.
Understanding the BunFile Interface
The BunFile interface extends the standard Blob class and adds file-system-specific methods. According to the type definitions in packages/bun-types/bun.d.ts [line 3998], the interface includes properties like size and methods such as stat(), exists(), and unlink() [lines 2036-2080].
You can construct a BunFile from multiple sources:
- A string path (
"./data.txt") - A
URLobject - An
ArrayBufferor typed array - An open file descriptor
Reading Files with Bun.file
The BunFile object provides several async methods for reading content, all returning Promises that can be awaited directly.
Reading as Text
The text() method reads the entire file and resolves to a UTF-8 string:
const config = await Bun.file("./config.json").text();
console.log(config);
This pattern is validated in the test suite at test/js/web/fetch/fetch.test.ts [lines 957-967].
Parsing JSON Directly
Use json<T>() to parse the file content as JSON without an intermediate string step:
const data = await Bun.file("./data.json").json<Record<string, any>>();
console.log(data);
Streaming Large Files
For memory-efficient processing of large files, use stream() which returns a NodeJS.ReadableStream:
const stream = Bun.file("./large.log").stream();
for await (const chunk of stream) {
process.stdout.write(chunk);
}
Reference implementation in test/js/web/fetch/fetch.test.ts [lines 1410-1416].
Raw Binary Data
Access the file as an ArrayBuffer using arrayBuffer():
const bytes = await Bun.file("./binary.dat").arrayBuffer();
Partial File Reading
The slice() method creates a new BunFile representing a subset of the original file without loading it into memory:
const partial = Bun.file("./large.txt").slice(0, 1024); // First 1KB
const text = await partial.text();
Writing and Copying Files
While Bun.file itself is read-only, Bun provides two primary patterns for writing data: Bun.write() for one-shot operations and writer() for streaming.
Copying Files with Bun.write
Bun.write() accepts a BunFile as the source and copies it to a destination path:
// Copy source.txt to dest.txt with specific permissions
await Bun.write("dest.txt", Bun.file("source.txt"), { mode: 0o600 });
This mode handling is tested in test/regression/issue/25903.test.ts [lines 24-27].
Using the Writer API
For incremental writes or piping streams, use writer():
const writer = Bun.file("./output.txt").writer();
writer.write("Hello, Bun!\n");
writer.end(); // Finalize the stream
await writer.closed; // Wait for completion
File Metadata and Management
BunFile provides methods for inspecting and modifying the file system entry.
Checking File Properties
Access the size property directly for the byte length, or use stat() for detailed metadata:
const file = Bun.file("example.txt");
console.log(file.size); // Synchronous property
const info = await file.stat();
console.log(`Size: ${info.size} bytes, Mode: ${info.mode.toString(8)}`);
Checking Existence and Deleting
Verify a file exists before operations using exists(), and remove it with unlink() or delete():
if (await Bun.file("temp.tmp").exists()) {
await Bun.file("temp.tmp").unlink(); // or .delete()
}
This pattern is demonstrated in test/js/web/fetch/blob-write.test.ts [lines 32-34].
Integration with Web APIs
Because BunFile inherits from Blob, it works natively with the Fetch API. You can return files directly from HTTP handlers:
const server = Bun.serve({
fetch(req) {
return new Response(Bun.file("./static/index.html"));
}
});
This makes Bun.file ideal for both server-side file manipulation and web-compatible data handling.
Summary
Bun.filecreates aBlob-compatible file handle that accepts paths, URLs, buffers, or file descriptors.- Reading methods include
text(),json(),arrayBuffer(), andstream()for different use cases. - Writing operations use
Bun.write()for copying data orwriter()for streaming writes. - Metadata access via the
sizeproperty andstat()method provides file system details. - File management methods like
exists()andunlink()handle lifecycle operations. - All methods are Promise-based and integrate with the Fetch API and FormData.
Frequently Asked Questions
Can Bun.file replace Node.js fs promises?
Bun.file and Bun.write provide a modern, Promise-based alternative to Node.js fs.promises, but they serve different purposes. While Bun.file offers a Blob-compatible interface ideal for web standards integration, Node.js fs provides lower-level control over file descriptors and flags. For most high-level read/write operations, Bun.file is sufficient and more ergonomic.
How do I check if a file exists before reading it?
Use the exists() method on the BunFile instance. This returns a Promise that resolves to a boolean indicating whether the file system entry exists:
if (await Bun.file("data.json").exists()) {
const data = await Bun.file("data.json").json();
}
What is the difference between Bun.write and file.writer()?
Bun.write() is a one-shot operation that copies data from a source (string, buffer, or BunFile) to a destination path, suitable for atomic writes. file.writer() returns a writable stream for incremental writes, appending, or piping data from other streams, which is better for large files or network responses.
Can I use Bun.file with FormData?
Yes, BunFile can be appended directly to FormData because it inherits from Blob. This allows seamless file uploads via the Fetch API:
const form = new FormData();
form.append("file", Bun.file("./upload.txt"));
await fetch("https://api.example.com/upload", { method: "POST", body: form });
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →