{% callout %}
Note — The Bun.file
and Bun.write
APIs documented on this page are heavily optimized and represent the recommended way to perform file-system tasks using Bun. For operations that are not yet available with Bun.file
, such as mkdir
, you can use Bun's nearly complete implementation of the node:fs
module.
{% /callout %}
Bun provides a set of optimized APIs for reading and writing files.
Bun.file(path): BunFile
Create a BunFile
instance with the Bun.file(path)
function. A BunFile
represents a lazily-loaded file; initializing it does not actually read the file from disk.
const foo = Bun.file("foo.txt"); // relative to cwd
foo.size; // number of bytes
foo.type; // MIME type
The reference conforms to the Blob
interface, so the contents can be read in various formats.
const foo = Bun.file("foo.txt");
await foo.text(); // contents as a string
await foo.stream(); // contents as ReadableStream
await foo.arrayBuffer(); // contents as ArrayBuffer
File references can also be created using numerical file descriptors or file://
URLs.
Bun.file(1234);
Bun.file(new URL(import.meta.url)); // reference to the current file
A BunFile
can point to a location on disk where a file does not exist.
const notreal = Bun.file("notreal.txt");
notreal.size; // 0
notreal.type; // "text/plain;charset=utf-8"
The default MIME type is text/plain;charset=utf-8
, but it can be overridden by passing a second argument to Bun.file
.
const notreal = Bun.file("notreal.json", { type: "application/json" });
notreal.type; // => "application/json;charset=utf-8"
For convenience, Bun exposes stdin
, stdout
and stderr
as instances of BunFile
.
Bun.stdin; // readonly
Bun.stdout;
Bun.stderr;
Bun.write(destination, data): Promise<number>
The Bun.write
function is a multi-tool for writing payloads of all kinds to disk.
The first argument is the destination
which can have any of the following types:
string
: A path to a location on the file system. Use the"path"
module to manipulate paths.URL
: Afile://
descriptor.BunFile
: A file reference.
The second argument is the data to be written. It can be any of the following:
string
Blob
(includingBunFile
)ArrayBuffer
orSharedArrayBuffer
TypedArray
(Uint8Array
, et. al.)Response
All possible permutations are handled using the fastest available system calls on the current platform.
{% details summary="See syscalls" %}
{% table %}
- Output
- Input
- System call
- Platform
- file
- file
- copy_file_range
- Linux
- file
- pipe
- sendfile
- Linux
- pipe
- pipe
- splice
- Linux
- terminal
- file
- sendfile
- Linux
- terminal
- terminal
- sendfile
- Linux
- socket
- file or pipe
- sendfile (if http, not https)
- Linux
- file (doesn't exist)
- file (path)
- clonefile
- macOS
- file (exists)
- file
- fcopyfile
- macOS
- file
- Blob or string
- write
- macOS
- file
- Blob or string
- write
- Linux
{% /table %}
{% /details %}
To write a string to disk:
const data = `It was the best of times, it was the worst of times.`;
await Bun.write("output.txt", data);
To copy a file to another location on disk:
const input = Bun.file("input.txt");
const output = Bun.file("output.txt"); // doesn't exist yet!
await Bun.write(output, input);
To write a byte array to disk:
const encoder = new TextEncoder();
const data = encoder.encode("datadatadata"); // Uint8Array
await Bun.write("output.txt", data);
To write a file to stdout
:
const input = Bun.file("input.txt");
await Bun.write(Bun.stdout, input);
To write an HTTP response to disk:
const response = await fetch("https://bun.sh");
await Bun.write("index.html", response);
The following is a 3-line implementation of the Linux cat
command.
// Usage
// $ bun ./cat.ts ./path-to-file
import { resolve } from "path";
const path = resolve(process.argv.at(-1));
await Bun.write(Bun.stdout, Bun.file(path));
To run the file:
$ bun ./cat.ts ./path-to-file
It runs 2x faster than GNU cat
for large files on Linux.
{% image src="/images/cat.jpg" /%}
interface Bun {
stdin: BunFile;
stdout: BunFile;
stderr: BunFile;
file(path: string | number | URL, options?: { type?: string }): BunFile;
write(
destination: string | number | BunFile | URL,
input: string | Blob | ArrayBuffer | SharedArrayBuffer | TypedArray | Response,
): Promise<number>;
}
interface BunFile {
readonly size: number;
readonly type: string;
text(): Promise<string>;
stream(): Promise<ReadableStream>;
arrayBuffer(): Promise<ArrayBuffer>;
json(): Promise<any>;
}