Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/zhcndoc/bun/llms.txt

Use this file to discover all available pages before exploring further.

Bun provides full support for working with binary data through ArrayBuffer, TypedArrays, DataView, and Node.js Buffer.

ArrayBuffer

An ArrayBuffer is a fixed-length raw binary data buffer:
// Create a 16-byte buffer
const buffer = new ArrayBuffer(16);

console.log(buffer.byteLength); // 16

// Slice the buffer
const slice = buffer.slice(0, 8);

TypedArrays

TypedArrays provide a view into an ArrayBuffer:

Uint8Array

// Create from size
const bytes = new Uint8Array(4);
bytes[0] = 255;
bytes[1] = 128;

// Create from array
const bytes2 = new Uint8Array([1, 2, 3, 4]);

// Create from ArrayBuffer
const buffer = new ArrayBuffer(8);
const view = new Uint8Array(buffer);

// Create from buffer with offset and length
const view2 = new Uint8Array(buffer, 2, 4);

Other TypedArray Types

// 8-bit
const int8 = new Int8Array(4);
const uint8 = new Uint8Array(4);
const uint8clamped = new Uint8ClampedArray(4);

// 16-bit
const int16 = new Int16Array(4);
const uint16 = new Uint16Array(4);

// 32-bit
const int32 = new Int32Array(4);
const uint32 = new Uint32Array(4);
const float32 = new Float32Array(4);

// 64-bit
const float64 = new Float64Array(4);
const bigint64 = new BigInt64Array(4);
const biguint64 = new BigUint64Array(4);

TypedArray Operations

const bytes = new Uint8Array([1, 2, 3, 4, 5]);

// Properties
bytes.length; // 5
bytes.byteLength; // 5
bytes.byteOffset; // 0
bytes.buffer; // ArrayBuffer

// Slice
const slice = bytes.slice(1, 4); // [2, 3, 4]

// Subarray (view, not copy)
const sub = bytes.subarray(1, 4); // [2, 3, 4]

// Set
bytes.set([10, 20], 0); // [10, 20, 3, 4, 5]

// Copy within
bytes.copyWithin(0, 3); // [4, 5, 3, 4, 5]

// Fill
bytes.fill(0); // [0, 0, 0, 0, 0]

// Find
bytes.indexOf(3); // -1
bytes.includes(0); // true

// Iteration
for (const byte of bytes) {
  console.log(byte);
}

DataView

DataView provides a low-level interface for reading/writing multiple number types in an ArrayBuffer:
const buffer = new ArrayBuffer(16);
const view = new DataView(buffer);

// Write different types
view.setInt8(0, 127);
view.setInt16(1, 32767);
view.setInt32(3, 2147483647);
view.setFloat32(7, 3.14);
view.setFloat64(11, Math.PI);

// Read values
const int8 = view.getInt8(0); // 127
const int16 = view.getInt16(1); // 32767
const float32 = view.getFloat32(7); // 3.14

// Endianness
view.setInt16(0, 256, true); // Little-endian
view.setInt16(0, 256, false); // Big-endian (default)

Buffer (Node.js)

Buffer is a subclass of Uint8Array with additional methods:
// Create from size
const buf = Buffer.alloc(10);
const buf2 = Buffer.allocUnsafe(10); // Faster but uninitialized

// Create from string
const buf3 = Buffer.from("Hello", "utf-8");
const buf4 = Buffer.from("48656c6c6f", "hex");
const buf5 = Buffer.from("SGVsbG8=", "base64");

// Create from array
const buf6 = Buffer.from([72, 101, 108, 108, 111]);

// Create from ArrayBuffer
const ab = new ArrayBuffer(10);
const buf7 = Buffer.from(ab);

Buffer Methods

const buf = Buffer.from("Hello World");

// Convert to string
buf.toString(); // "Hello World"
buf.toString("hex"); // "48656c6c6f20576f726c64"
buf.toString("base64"); // "SGVsbG8gV29ybGQ="
buf.toString("utf-8", 0, 5); // "Hello"

// Write
buf.write("Hi", 0, "utf-8"); // "Hi World"

// Compare
const buf2 = Buffer.from("Hello World");
buf.equals(buf2); // false (was modified)
buf.compare(buf2); // -1, 0, or 1

// Concat
const combined = Buffer.concat([buf, buf2]);

// Copy
const dest = Buffer.alloc(5);
buf.copy(dest, 0, 0, 5);

// Slice
const slice = buf.slice(0, 5);

// Fill
buf.fill(0);
buf.fill("a");

Reading Numbers

const buf = Buffer.alloc(8);

// Write
buf.writeInt8(127, 0);
buf.writeInt16LE(32767, 1);
buf.writeInt32LE(2147483647, 3);
buf.writeFloatLE(3.14, 7);

// Read
buf.readInt8(0); // 127
buf.readInt16LE(1); // 32767
buf.readInt32LE(3); // 2147483647
buf.readFloatLE(7); // 3.14

// Big-endian
buf.writeInt16BE(256, 0);
buf.readInt16BE(0); // 256

Conversions

String ↔ Buffer

// String to Buffer
const buf = Buffer.from("Hello", "utf-8");

// Buffer to String
const str = buf.toString("utf-8");

// Encodings: "utf-8", "utf8", "utf16le", "latin1", "base64", "base64url", "hex", "ascii", "binary"

ArrayBuffer ↔ Buffer

// ArrayBuffer to Buffer
const ab = new ArrayBuffer(10);
const buf = Buffer.from(ab);

// Buffer to ArrayBuffer
const ab2 = buf.buffer;

TypedArray ↔ Buffer

// TypedArray to Buffer
const uint8 = new Uint8Array([1, 2, 3]);
const buf = Buffer.from(uint8);

// Buffer to TypedArray
const uint8_2 = new Uint8Array(buf);

Blob ↔ ArrayBuffer

// Blob to ArrayBuffer
const blob = new Blob(["Hello"]);
const ab = await blob.arrayBuffer();

// ArrayBuffer to Blob
const ab2 = new ArrayBuffer(10);
const blob2 = new Blob([ab2]);

Base64 Encoding/Decoding

Using Buffer

// Encode
const encoded = Buffer.from("Hello").toString("base64");
console.log(encoded); // "SGVsbG8="

// Decode
const decoded = Buffer.from(encoded, "base64").toString();
console.log(decoded); // "Hello"

Using bun:base64

import { encode, decode } from "bun:base64";

// Encode
const encoded = encode("Hello");
// or
const encoded2 = encode(new Uint8Array([72, 101, 108, 108, 111]));

// Decode
const decoded = decode(encoded);

Hex Encoding/Decoding

// Encode
const hex = Buffer.from("Hello").toString("hex");
console.log(hex); // "48656c6c6f"

// Decode
const bytes = Buffer.from(hex, "hex");
console.log(bytes.toString()); // "Hello"

SharedArrayBuffer

SharedArrayBuffer allows sharing memory between threads:
// Create shared buffer
const shared = new SharedArrayBuffer(1024);

// Create view
const view = new Uint8Array(shared);

// Share with worker
const worker = new Worker("./worker.js");
worker.postMessage(shared);

Crypto Random Bytes

// Generate random bytes
const bytes = crypto.getRandomValues(new Uint8Array(16));

// Or with Node.js API
import { randomBytes } from "node:crypto";
const bytes2 = randomBytes(16);

Reading Binary Files

// Read as ArrayBuffer
const file = Bun.file("./data.bin");
const buffer = await file.arrayBuffer();

// Read as Uint8Array
const bytes = new Uint8Array(await file.arrayBuffer());

// Read specific bytes
const header = await file.slice(0, 512).arrayBuffer();

Writing Binary Files

// Write ArrayBuffer
const buffer = new ArrayBuffer(10);
await Bun.write("./data.bin", buffer);

// Write TypedArray
const bytes = new Uint8Array([1, 2, 3, 4]);
await Bun.write("./data.bin", bytes);

// Write Buffer
const buf = Buffer.from([1, 2, 3, 4]);
await Bun.write("./data.bin", buf);

Performance Tips

  1. Use Buffer.allocUnsafe() for temporary buffers - Faster but contains uninitialized data
  2. Use subarray() instead of slice() when possible - Creates a view instead of copying
  3. Reuse buffers - Avoid frequent allocations
  4. Use TypedArrays for specific data types - Better performance than DataView
  5. Use Buffer.concat() for combining buffers - More efficient than manual copying
// Good: Reuse buffer
const buf = Buffer.allocUnsafe(1024);
for (let i = 0; i < 100; i++) {
  const bytesRead = readInto(buf);
  process(buf.subarray(0, bytesRead));
}

// Bad: Allocate each time
for (let i = 0; i < 100; i++) {
  const buf = Buffer.alloc(1024);
  const bytesRead = readInto(buf);
  process(buf.slice(0, bytesRead));
}

Build docs developers (and LLMs) love