Skip to main content

ohash vs object-hash vs hash-wasm: Object Hashing in JavaScript (2026)

·PkgPulse Team

TL;DR

ohash is the UnJS super-fast object hashing library — deterministic hash of any JavaScript value, tiny, zero dependencies, used for cache keys and content addressing. object-hash is the mature object hashing library — SHA-1/SHA-256/MD5 of JavaScript objects, handles circular references, configurable key ordering. hash-wasm is a WebAssembly-based hashing library — blazing fast SHA-256, MD5, xxHash, Blake3 on raw data (strings/buffers), not specific to objects. In 2026: ohash for hashing JS objects (cache keys, ETags), object-hash for configurable object hashing, hash-wasm for raw data hashing at maximum speed.

Key Takeaways

  • ohash: ~10M weekly downloads — UnJS, fast object hashing, deterministic, tiny
  • object-hash: ~10M weekly downloads — configurable, multiple algorithms, circular reference support
  • hash-wasm: ~3M weekly downloads — WASM-based, 30+ algorithms, raw data hashing
  • ohash produces a quick hash for cache invalidation — not cryptographic
  • object-hash produces SHA-1/SHA-256 — deterministic and verifiable
  • hash-wasm is for raw data — hashing strings, buffers, files (not JS objects)

Common Use Cases

Why hash JavaScript objects?
  ✅ Cache keys — hash(requestParams) → unique cache key
  ✅ ETags — hash(responseBody) → HTTP ETag header
  ✅ Change detection — hash(config) changed? → reload
  ✅ Deduplication — hash(record) → check if already processed
  ✅ Content addressing — hash(data) → deterministic filename

Why hash raw data?
  ✅ File integrity — SHA-256(file) → verify downloads
  ✅ Password hashing — (use bcrypt/argon2 instead)
  ✅ Checksums — MD5(payload) → quick integrity check
  ✅ Bloom filters — xxHash(key) → fast probabilistic lookup

ohash

ohash — fast object hashing:

Basic usage

import { hash, objectHash, murmurHash, sha256 } from "ohash"

// hash() — quick hash of any value:
hash({ name: "react", version: "19.0.0" })
// → "aBcDeFgH" (short, deterministic hash string)

hash([1, 2, 3])
// → "xYzAbCdE"

hash("hello world")
// → "qRsTuVwX"

// Same input → same output (deterministic):
hash({ a: 1, b: 2 }) === hash({ b: 2, a: 1 })
// → true (key order doesn't matter)

Object hashing for cache keys

import { hash } from "ohash"

// API response caching:
function getCacheKey(endpoint: string, params: Record<string, unknown>) {
  return hash({ endpoint, params })
}

const key = getCacheKey("/api/packages", { sort: "downloads", limit: 10 })
// → deterministic cache key

// ETag generation:
function generateETag(data: unknown) {
  return `"${hash(data)}"`
}

app.get("/api/packages", (req, res) => {
  const packages = getPackages()
  const etag = generateETag(packages)

  if (req.headers["if-none-match"] === etag) {
    return res.status(304).end()  // Not modified
  }

  res.setHeader("ETag", etag)
  res.json(packages)
})

SHA-256 and Murmur hash

import { sha256, murmurHash } from "ohash"

// SHA-256 (cryptographic):
sha256("hello world")
// → "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"

// Murmur hash (fast, non-cryptographic):
murmurHash("hello world")
// → 1586663183

// sha256 for content integrity:
const contentHash = sha256(JSON.stringify(config))

Diff and comparison

import { hash, diff } from "ohash"

// diff() — find differences between objects:
const changes = diff(
  { name: "react", version: "18.0.0", downloads: 5_000_000 },
  { name: "react", version: "19.0.0", downloads: 5_500_000 }
)
// → [
//   { type: "changed", key: "version", oldValue: "18.0.0", newValue: "19.0.0" },
//   { type: "changed", key: "downloads", oldValue: 5000000, newValue: 5500000 }
// ]

// isEqual — deep equality check:
import { isEqual } from "ohash"
isEqual({ a: 1 }, { a: 1 }) // → true

object-hash

object-hash — configurable object hashing:

Basic usage

import objectHash from "object-hash"

// SHA-1 by default:
objectHash({ name: "react", version: "19.0.0" })
// → "a1b2c3d4e5f6..." (40-char SHA-1 hex)

// SHA-256:
objectHash({ name: "react" }, { algorithm: "sha256" })
// → "abcdef123456..." (64-char SHA-256 hex)

// MD5:
objectHash({ name: "react" }, { algorithm: "md5" })
// → "a1b2c3d4..." (32-char MD5 hex)

Configuration options

import objectHash from "object-hash"

// Key ordering (default: sorted):
objectHash({ b: 2, a: 1 }) === objectHash({ a: 1, b: 2 })
// → true (keys sorted before hashing)

// Disable key sorting:
objectHash({ b: 2, a: 1 }, { unorderedObjects: false })
// → different from objectHash({ a: 1, b: 2 }, { unorderedObjects: false })

// Exclude specific keys:
objectHash({ name: "react", _internal: "skip" }, {
  excludeKeys: (key) => key.startsWith("_"),
})

// Respect type differences:
objectHash({ value: 1 }, { respectType: true })
// Different from objectHash({ value: "1" })

Circular references

import objectHash from "object-hash"

// Handles circular references:
const obj: any = { name: "react" }
obj.self = obj  // Circular!

objectHash(obj)
// → works fine, circular reference detected and handled

// ohash would throw on circular references by default

Specific value hashing

import objectHash from "object-hash"

// Hash specific types:
objectHash.sha1({ name: "react" })     // SHA-1
objectHash.MD5({ name: "react" })      // MD5
objectHash.keysMD5({ name: "react" })  // MD5 of keys only

// Write to stream (for large objects):
objectHash.writeToStream({ name: "react" }, { algorithm: "sha256" })

hash-wasm

hash-wasm — WASM-based hashing:

Fast hashing

import { sha256, md5, xxhash64, blake3 } from "hash-wasm"

// SHA-256:
const hash = await sha256("hello world")
// → "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"

// MD5:
const md5Hash = await md5("hello world")
// → "5eb63bbbe01eeed093cb22bb8f5acdc3"

// xxHash64 (ultra-fast, non-cryptographic):
const xxHash = await xxhash64("hello world")
// → "d4a1185c118f2a57"

// Blake3 (modern, fast cryptographic):
const blake = await blake3("hello world")
// → "d74981efa70a0c880b8d8c1985d075dbcbf679b99a5f9914e5aaf96b831a9e24"

Buffer/file hashing

import { sha256, createSHA256 } from "hash-wasm"
import { readFile } from "node:fs/promises"

// Hash a file:
const buffer = await readFile("package.json")
const fileHash = await sha256(buffer)

// Streaming hash (for large files):
const hasher = await createSHA256()
hasher.init()

// Process in chunks:
for await (const chunk of readStream) {
  hasher.update(chunk)
}

const result = hasher.digest("hex")

Performance advantage

Benchmark (hashing 1 MB of data):

  hash-wasm (SHA-256, WASM):  ~450 MB/s
  Node.js crypto (SHA-256):    ~400 MB/s
  pure JS sha256:              ~50 MB/s

  hash-wasm (xxHash64, WASM): ~3,000 MB/s
  Node.js crypto (N/A):       —
  pure JS xxhash:             ~200 MB/s

hash-wasm is fastest in browsers (no native crypto).
In Node.js, built-in crypto is comparable for SHA-256.
xxHash/Blake3 via hash-wasm is much faster than any pure JS option.

Available algorithms

import {
  md5, sha1, sha256, sha512,       // Standard
  xxhash32, xxhash64, xxhash128,   // xxHash (non-crypto, ultra-fast)
  blake2b, blake2s, blake3,         // Blake (modern crypto)
  crc32, adler32,                   // Checksums
  argon2id, bcrypt, scrypt,         // Password hashing
  sha3_256, sha3_512,               // SHA-3
  keccak256, keccak512,             // Keccak
} from "hash-wasm"

// 30+ algorithms available — all WASM-accelerated

Feature Comparison

Featureohashobject-hashhash-wasm
Hash JS objects❌ (raw data)
Hash raw data✅ (sha256)
Deterministic
Key order independent✅ (configurable)N/A
Circular referencesN/A
Algorithm choicemurmur, SHA-256SHA-1, SHA-256, MD530+ algorithms
WASM accelerated
Streaming
Object diff
Browser support
Dependencies000
Weekly downloads~10M~10M~3M

When to Use Each

Use ohash if:

  • Need fast cache keys from JavaScript objects
  • Building ETags or content-addressed storage
  • In the UnJS ecosystem (Nuxt, Nitro, H3)
  • Want object diff and equality utilities alongside hashing

Use object-hash if:

  • Need configurable hashing (algorithm, key ordering, exclusions)
  • Objects may have circular references
  • Want SHA-1/SHA-256/MD5 hashes of JavaScript objects
  • Need streaming hash support for large objects

Use hash-wasm if:

  • Hashing raw data (strings, buffers, files) not JS objects
  • Need maximum performance (WASM-accelerated)
  • Want exotic algorithms (xxHash, Blake3, Keccak)
  • Building file integrity checks, checksums, or content addressing

Methodology

Download data from npm registry (weekly average, February 2026). Feature comparison based on ohash v1.x, object-hash v3.x, and hash-wasm v4.x.

Compare hashing and cryptography packages on PkgPulse →

Comments

Stay Updated

Get the latest package insights, npm trends, and tooling tips delivered to your inbox.