Migrating from Bun

Bun's Web-standard surface carries over unchanged. What moves is the Bun.* namespace: each ambient global becomes an explicit runtime: import.

1. File handling (Bun.file, Bun.write)

JavaScript
// ❌ Bun
const text = await Bun.file("./data.txt").text();
const json = await Bun.file("./data.json").json();
await Bun.write("./out.txt", "data");

// ✅ esrun
import { file, write } from "runtime:fs";

const text = await file("./data.txt").text();
const json = await file("./data.json").json();
await write("./out.txt", "data");

2. Subprocesses (Bun.spawn, Bun.$)

JavaScript
// ❌ Bun
const proc = Bun.spawn(["git", "rev-parse", "HEAD"]);
const text = await new Response(proc.stdout).text();

// ✅ esrun
import { Command } from "runtime:system";

const { stdout } = await new Command("git", {
  args: ["rev-parse", "HEAD"],
}).output();

const text = new TextDecoder().decode(stdout).trim();

3. Hashing and passwords (Bun.hash, Bun.CryptoHasher, Bun.password)

JavaScript
// ❌ Bun
const key = Bun.hash(data);
const digest = new Bun.CryptoHasher("sha256").update("data").digest("hex");
const stored = await Bun.password.hash(input);

// ✅ esrun
import { hash, Hasher, password } from "runtime:hashing";

const key = hash("xxhash64", data);
const digest = new Hasher("sha256").update("data").digest("hex");
const stored = await password.hash(input);
Last updated on
Edit this page