Skip to main content
Bun provides high-performance hashing functions for checksums, data integrity, and hash tables. All implementations are optimized with SIMD instructions where available.

Quick Start

import { hash } from "bun";

// Default hash (Wyhash)
const h = hash("Hello World");
console.log(h); // Fast 64-bit hash

// With seed
const h2 = hash("Hello World", 42);

Non-Cryptographic Hashes

Fast hashes for hash tables, checksums, and data structures.

Wyhash

Default hash function, extremely fast:
import { hash } from "bun";

// 64-bit hash
const h = hash.wyhash("data");
const h2 = hash.wyhash("data", seed);

// Also available as default export
const h3 = hash("data");
Characteristics:
  • Speed: ~25 GB/s
  • Output: 64-bit
  • Collision resistance: Excellent
  • Use for: Hash tables, general purpose

CityHash

Google’s CityHash family:
import { hash } from "bun";

// 32-bit variant
const h32 = hash.cityHash32("data");
const h32_seeded = hash.cityHash32("data", seed);

// 64-bit variant  
const h64 = hash.cityHash64("data");
const h64_seeded = hash.cityHash64("data", seed);
Characteristics:
  • Speed: ~20 GB/s
  • Output: 32-bit or 64-bit
  • Use for: Hash tables, databases

xxHash

Extremely fast hash with excellent distribution:
import { hash } from "bun";

// xxHash32
const h32 = hash.xxHash32("data");
const h32_seeded = hash.xxHash32("data", seed);

// xxHash64
const h64 = hash.xxHash64("data");
const h64_seeded = hash.xxHash64("data", seed);

// xxHash3 (latest, fastest)
const h3 = hash.xxHash3("data");
const h3_seeded = hash.xxHash3("data", seed);
Characteristics:
  • Speed: xxHash3 ~30 GB/s, others ~15 GB/s
  • Output: 32-bit or 64-bit
  • Collision resistance: Excellent
  • Use for: Checksums, hash tables, caching

Murmur Hash

Popular hash used in many databases:
import { hash } from "bun";

// MurmurHash2 32-bit
const h = hash.murmur32v2("data", seed);

// MurmurHash2 64-bit
const h64 = hash.murmur64v2("data", seed);

// MurmurHash3 32-bit
const h3 = hash.murmur32v3("data", seed);
Characteristics:
  • Speed: ~5 GB/s
  • Output: 32-bit or 64-bit
  • Use for: Hash tables, Bloom filters

CRC32

Cyclic redundancy check, hardware accelerated:
import { hash } from "bun";

const checksum = hash.crc32("data");
const checksum2 = hash.crc32("data", seed);
Characteristics:
  • Speed: ~10 GB/s (hardware accelerated)
  • Output: 32-bit
  • Use for: Data integrity, checksums

Adler-32

Simpler checksum algorithm:
import { hash } from "bun";

const checksum = hash.adler32("data");
const checksum2 = hash.adler32("data", seed);
Characteristics:
  • Speed: ~15 GB/s
  • Output: 32-bit
  • Use for: Checksums (faster but less reliable than CRC32)

Input Types

All hash functions accept multiple input types:

Strings

const h = hash("Hello World");

TypedArrays

const data = new Uint8Array([1, 2, 3, 4]);
const h = hash(data);

ArrayBuffer

const buffer = new ArrayBuffer(1024);
const h = hash(buffer);

Blob

const blob = new Blob(["data"]);
const h = hash(blob);

Cryptographic Hashes

For security-sensitive applications, use cryptographic hash functions:

SHA-256

import { SHA256 } from "bun";

const hasher = new SHA256();
hasher.update("Hello ");
hasher.update("World");

const digest = hasher.digest();
console.log(digest.toString("hex"));

// One-shot hashing
const hash = SHA256.hash("data");
console.log(hash.toString("hex"));

SHA-512

import { SHA512 } from "bun";

const hash = SHA512.hash("data");
console.log(hash.toString("hex"));

Other SHA Variants

import { SHA1, SHA224, SHA384, SHA512_256 } from "bun";

const h1 = SHA1.hash("data");
const h224 = SHA224.hash("data");
const h384 = SHA384.hash("data");
const h512_256 = SHA512_256.hash("data");

MD4 and MD5

⚠️ Warning: MD4 and MD5 are cryptographically broken. Only use for legacy compatibility.
import { MD4, MD5 } from "bun";

const md4 = MD4.hash("data");
const md5 = MD5.hash("data");

Performance Comparison

Throughput Benchmark

const data = new Uint8Array(1024 * 1024); // 1MB

const algorithms = [
  ["wyhash", hash.wyhash],
  ["xxHash3", hash.xxHash3],
  ["xxHash64", hash.xxHash64],
  ["cityHash64", hash.cityHash64],
  ["crc32", hash.crc32],
  ["adler32", hash.adler32],
];

for (const [name, fn] of algorithms) {
  const start = performance.now();
  for (let i = 0; i < 1000; i++) {
    fn(data);
  }
  const elapsed = performance.now() - start;
  const throughput = (1000 / elapsed) * 1024; // MB/s
  
  console.log(`${name}: ${throughput.toFixed(0)} MB/s`);
}

// Typical results on M1 Mac:
// wyhash: 25000 MB/s
// xxHash3: 30000 MB/s
// xxHash64: 15000 MB/s
// cityHash64: 20000 MB/s
// crc32: 10000 MB/s
// adler32: 15000 MB/s

Common Use Cases

Hash Table Keys

import { hash } from "bun";

class HashMap<V> {
  buckets = new Map<number, Array<[string, V]>>();
  
  set(key: string, value: V) {
    const h = hash(key);
    const bucket = this.buckets.get(h) ?? [];
    bucket.push([key, value]);
    this.buckets.set(h, bucket);
  }
  
  get(key: string): V | undefined {
    const h = hash(key);
    const bucket = this.buckets.get(h);
    if (!bucket) return undefined;
    
    for (const [k, v] of bucket) {
      if (k === key) return v;
    }
  }
}

File Integrity

import { hash } from "bun";

async function verifyFile(path: string, expectedHash: number) {
  const file = Bun.file(path);
  const contents = await file.arrayBuffer();
  const actualHash = hash(contents);
  
  return actualHash === expectedHash;
}

const isValid = await verifyFile("data.bin", 0x1234567890abcdef);

Content Addressing

import { hash } from "bun";

class ContentStore {
  store = new Map<string, Uint8Array>();
  
  async put(data: Uint8Array): Promise<string> {
    const h = hash(data);
    const id = h.toString(16);
    this.store.set(id, data);
    return id;
  }
  
  get(id: string): Uint8Array | undefined {
    return this.store.get(id);
  }
}

const store = new ContentStore();
const id = await store.put(new Uint8Array([1, 2, 3]));
const data = store.get(id);

Deduplication

import { hash } from "bun";

class Deduplicator {
  seen = new Set<number>();
  
  isDuplicate(data: string | Uint8Array): boolean {
    const h = hash(data);
    if (this.seen.has(h)) {
      return true;
    }
    this.seen.add(h);
    return false;
  }
}

const dedup = new Deduplicator();
console.log(dedup.isDuplicate("foo")); // false
console.log(dedup.isDuplicate("foo")); // true
console.log(dedup.isDuplicate("bar")); // false

Cache Keys

import { hash } from "bun";

class Cache<T> {
  data = new Map<number, T>();
  
  key(...args: any[]): number {
    const str = JSON.stringify(args);
    return hash(str);
  }
  
  get(...args: any[]): T | undefined {
    return this.data.get(this.key(...args));
  }
  
  set(value: T, ...args: any[]) {
    this.data.set(this.key(...args), value);
  }
}

const cache = new Cache<string>();
cache.set("result", "arg1", 42, true);
const result = cache.get("arg1", 42, true);

Password Hashing

⚠️ Warning: Use proper password hashing like bcrypt or Argon2. Never use fast hashes for passwords.
// DON'T DO THIS:
import { hash } from "bun";
const passwordHash = hash(password); // INSECURE!

// Instead, use:
import { password } from "bun";
const passwordHash = await password.hash(password);
const isValid = await password.verify(password, passwordHash);

Seeds and Determinism

All hash functions support seeds for deterministic results:
import { hash } from "bun";

// Without seed - uses random seed
const h1 = hash("data");
const h2 = hash("data"); // Different on each run

// With seed - deterministic
const h3 = hash("data", 0);
const h4 = hash("data", 0); // Always same

console.log(h3 === h4); // true

Reproducible Builds

const SEED = 0x1234567890abcdef;

function hashFile(path: string): number {
  const data = Bun.file(path).arrayBuffer();
  return hash(data, SEED);
}

// Always produces same hash for same file
const h1 = hashFile("input.js");
const h2 = hashFile("input.js");
console.log(h1 === h2); // true

Hash Quality

Collision Resistance

Test hash distribution:
function testCollisions(hashFn: Function, count: number) {
  const seen = new Set<number>();
  let collisions = 0;
  
  for (let i = 0; i < count; i++) {
    const h = hashFn(String(i));
    if (seen.has(h)) collisions++;
    seen.add(h);
  }
  
  console.log(`Collisions: ${collisions}/${count}`);
  console.log(`Rate: ${(collisions / count * 100).toFixed(4)}%`);
}

testCollisions(hash.wyhash, 1_000_000);
// Typical result: 0 collisions

Avalanche Effect

Small input changes should produce large hash changes:
const h1 = hash("test");
const h2 = hash("Test"); // One bit different
const diff = h1 ^ h2;
const bitCount = diff.toString(2).split('1').length - 1;

console.log(`Bits changed: ${bitCount}/64`);
// Good hash: ~32 bits

Best Practices

  1. Choose the right hash for your use case
    • Hash tables: wyhash, xxHash3
    • Checksums: crc32, xxHash64
    • Security: SHA256, SHA512
    • Legacy: MD5 (only if required)
  2. Use seeds for reproducibility
    const SEED = 0;
    const h = hash(data, SEED);
    
  3. Consider hash size
    // 32-bit: Good for small datasets
    const h32 = hash.cityHash32(data);
    
    // 64-bit: Better for large datasets
    const h64 = hash.cityHash64(data);
    
  4. Benchmark for your data
    // Test with your actual data patterns
    const start = performance.now();
    for (const item of myData) {
      hash(item);
    }
    console.log(`${performance.now() - start}ms`);
    

Platform Differences

Hardware Acceleration

  • x86_64: CRC32, SHA use CPU instructions
  • ARM64: CRC32, SHA use NEON instructions
  • Other: Software fallback

Endianness

Hashes are consistent across platforms:
// Same hash on little-endian and big-endian systems
const h = hash("test");

API Reference

hash()

Default fast hash function (Wyhash):
hash(data: string | TypedArray | ArrayBuffer, seed?: number): number

hash.wyhash()

hash.wyhash(data: string | TypedArray | ArrayBuffer, seed?: number): number

hash.xxHash3()

hash.xxHash3(data: string | TypedArray | ArrayBuffer, seed?: number): number

hash.crc32()

hash.crc32(data: string | TypedArray | ArrayBuffer, seed?: number): number
See FFI documentation for low-level hash implementations.

Build docs developers (and LLMs) love