Runtime APIs

Read and write files

Use Bun.file and Bun.write to load and save text or JSON with small Web API-compatible primitives.

Bun has its own small API for files. Bun.file() creates a reference to a file. It does not read anything yet. It just points at a path and lets you decide how to read it later.

Let’s try it with a settings file. Create settings.json:

{
  "siteName": "Bun Notes",
  "itemsPerPage": 20
}

Read it as JSON:

type Settings = {
  siteName: string
  itemsPerPage: number
}

const file = Bun.file('settings.json')
const settings = await file.json() as Settings

console.log(settings.siteName)

Run it and Bun prints Bun Notes. The json() call reads the file and parses it in one step. The as Settings part is for TypeScript only. Bun doesn’t check that the file matches the type, it trusts you.

A BunFile follows the Web Blob interface, the same one browsers use for uploaded files. So you can read it as text with text(), as JSON with json(), as bytes with bytes(), or as a stream with stream(). You also get file.size and file.type without reading the contents.

Reading a file that doesn’t exist throws an error like ENOENT: no such file or directory. For optional data, check first:

const file = Bun.file('settings.json')

if (await file.exists()) {
  console.log(await file.text())
}

Notice that exists() is async. Almost everything in this API returns a promise, so you’ll be using await a lot.

Write a file

Bun.write() accepts a destination and some data. Let’s save an updated settings object:

const settings = {
  siteName: 'Bun Notes',
  itemsPerPage: 30,
}

const bytes = await Bun.write(
  'settings.json',
  JSON.stringify(settings, null, 2),
)

console.log(bytes)

This prints 51, the size of the JSON text in bytes. Bun.write() creates the file if it’s missing and replaces the contents if it exists. The null, 2 arguments to JSON.stringify() add two-space indentation, so the file stays readable by humans.

The data can be a string, a Blob, a typed array, or another BunFile. That last option gives you a one-line file copy:

await Bun.write('settings.backup.json', Bun.file('settings.json'))

Bun.write() only writes files, and it won’t create missing folders for you. For directory work such as mkdir() and readdir(), use node:fs. Bun implements those Node.js APIs, and they sit well beside Bun.file() and Bun.write(), which cover the common read-and-write path with less code.

Lesson completed