object-hash

Deterministic SHA1/MD5 hashing for any JavaScript value or object, in Node.js and the browser.

Library
npm
v3.0.0
1,475 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
35 /100 Needs Attention
Development Activity 0
Maintenance 0
Community 52
Maturity 60
Momentum 28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
51 /100 Fair
Architecture 60
Code Quality 68
Innovation 40
Learning Curve 35

object-hash walks any JavaScript value — objects, arrays, Maps, Sets, Buffers, typed arrays, dates, functions, even circular references — and produces a stable hash of its contents rather than its reference. It ships as a single dependency-free module built on Node’s crypto module, with a browser build for client-side use, and exposes sugar methods (sha1, MD5, keys, keysMD5) plus a streaming API (writeToStream) for wiring the serialization into custom pipelines.

The library is commonly reached for wherever two structurally-equal-but-differently-ordered objects need to compare equal: cache keys derived from function arguments, change detection between two states of a config or Redux-style store, deduplicating similar-but-not-identical records, or grouping objects by their keys while ignoring values via excludeValues. Options like unorderedArrays, unorderedSets, and unorderedObjects (on by default) let callers decide whether ordering is semantically meaningful for their data before it factors into the hash.

Since v1.1.8 the project treats its exact hash output as part of its semver contract — any change that alters a produced hash for the same input is a major version bump — which matters for consumers who persist these hashes (as cache keys or stored fingerprints) across upgrades.

What You Get

  • A single hash(value, options) entry point covering objects, arrays, Maps, Sets, Buffers, typed arrays, dates, regexes, errors, and functions, plus explicit circular-reference detection.
  • Sugar methods hash.sha1(), hash.MD5(), hash.keys() (values-ignored, keys-only hashing for grouping), and hash.keysMD5() for the common cases without assembling an options object.
  • Fine-grained control over what counts toward the hash: excludeValues, excludeKeys(fn), replacer(fn), ignoreUnknown, and respectType/respectFunctionNames/respectFunctionProperties toggles.
  • Order-insensitivity switches — unorderedArrays, unorderedSets (on by default), unorderedObjects (on by default) — so structurally equal but differently-ordered collections can be made to hash the same.
  • A writeToStream(value, options, stream) API for piping the same internal serialization into a custom writable stream instead of only returning a digest.
  • Both a Node.js build (index.js, using the crypto module) and a bundled browser build (dist/object_hash.js) shipped in the same package.

Common Use Cases

  • Cache key generation - deriving a stable cache key from a function’s arguments or a request’s parameters so structurally identical calls hit the same cache entry.
  • Change/diff detection - hashing two snapshots of application state (e.g. a config object or store slice) to cheaply detect whether anything meaningful changed.
  • Deduplication - hashing incoming records to identify duplicates that differ only in key order or in fields the caller doesn’t care about (via excludeKeys/excludeValues).
  • Grouping by shape - using hash.keys() to group objects that share the same set of keys regardless of their values.

Under The Hood

Architecture

The library is a single dependency-free module (index.js) built around one dispatch-based type visitor: typeHasher(options, writeTo, context) returns an object whose dispatch() method inspects a value’s runtime type (via Object.prototype.toString and typeof) and routes it to a matching _<type> handler (_object, _array, _map, _set, _date, _function, _buffer, and roughly two dozen Node-native-object handlers such as _tcp/_zlib/_httpparser). Circular references are handled by tracking visited objects in a context array and substituting a [CIRCULAR:n] marker; unordered collections are handled by re-serializing each entry through an isolated PassThrough-backed sub-hasher, sorting the resulting strings, then re-dispatching the sorted list. Writing itself is abstracted behind a small hand-rolled PassThrough shim so the same typeHasher code can target either a real crypto.Hash stream or an in-memory buffer used internally for the unordered-array sort. There is no layering beyond this one file — applyDefaults() normalizes options and validates the requested algorithm/encoding against crypto.getHashes(), and the exported sugar functions are thin wrappers that call objectHash() with preset options.

Tech Stack

The runtime dependency footprint is zero — the Node build relies solely on the built-in crypto module (crypto.createHash, crypto.getHashes()) with no third-party packages. Everything else is dev tooling: browserify plus gulp (with gulp-uglify, gulp-rename, gulp-replace) to produce the browser bundle in dist/, karma with karma-chrome-launcher/karma-mocha to run the same test suite against a real browser, mocha for the Node test runner, and eslint (extending eslint:recommended, with curly/eqeqeq/no-caller tightened) for linting. CI (.github/workflows) runs the linter and browser build once, then re-runs the Mocha suite across a matrix of Node versions 8 through 21, reflecting the package’s long-lived commitment to old-runtime compatibility (engines.node >= 6).

Code Quality

Test coverage is organized by concern across test/index.js (general API + options), test/types.js, test/object-classes.js, test/blob.js, test/replacer.js, test/old-crypto.js, and test/writeToStream.js, together exercising the majority of the type-dispatch branches and option combinations with plain Mocha describe/it blocks and Node’s assert. Error handling is explicit rather than swallowed: unsupported algorithms/encodings, a missing object argument, and unsupported Blob hashing all throw descriptive Errors rather than failing silently. There is no TypeScript and no type declarations shipped, naming is plain and consistent (_<type> handler convention), and ESLint plus a Node-version CI matrix act as the only quality gates beyond the test suite itself.

API Design The public surface is intentionally small: one primary hash(value, options) call plus four sugar wrappers (sha1, MD5, keys, keysMD5) that cover the most common option combinations without requiring callers to assemble an options object, and a writeToStream escape hatch for streaming consumers. Options are well-documented inline via JSDoc-style comments in index.js and default to sensible, conservative behavior (SHA1/hex, ordered arrays, keys respected) so the zero-argument case does the intuitive thing. The tradeoff is that the API leans on stringly-typed option flags (excludeValues, unorderedArrays, etc.) rather than separate composable functions, keeping the surface area minimal at the cost of some discoverability — a reader has to consult the README’s options table rather than infer behavior from distinct method names.

Used by 17 apps in this directory

TypeScript
66%
MIT

Jitsu

Data Engineering

5,110

Open-source, fully-scriptable data ingestion engine that streams events from web, apps, and APIs to any data warehouse in real time.

View details
89
Repo Health
79
Technical
66
Dependency
Built with
TypeScript 66%
Go 32%
Updated 6 days ago
TypeScript
98%
Other

Kibana

Analytics · Monitoring

21,338

Your open source window into the Elastic Stack — query, visualize, and act on data stored in Elasticsearch with real-time dashboards, AI-assisted search, and automated alerting.

View details
98
Repo Health
87
Technical
63
Dependency
Built with
TypeScript 98%
Updated 5 days ago
TypeScript
88%
Apache 2.0

Medplum

Authentication · Databases · Developer Tools

2,760

An open-source, FHIR-native healthcare platform that gives developers a compliant backend, authentication, a React component library, and serverless bots to build clinical applications in weeks instead of years.

View details
93
Repo Health
90
Technical
71
Dependency
Built with
TypeScript 88%
Updated 5 days ago
TypeScript
65%
Other

NocoDB

Databases · Low Code Platforms · No Code Platforms

65,340

Turn any SQL database into a collaborative no-code spreadsheet with automatic REST APIs and real-time views.

View details
91
Repo Health
77
Technical
63
Dependency
Built with
TypeScript 65%
Vue 30%
Updated 5 days ago
TypeScript
96%
Other

Refly

AI Development · Automation · No Code Platforms

7,537

Build deterministic, versioned agent skills from natural language—run them anywhere from Claude Code to Slack.

View details
68
Repo Health
76
Technical
63
Dependency
Built with
TypeScript 96%
Updated 1 weeks ago
Rust
93%
Other

Tabby

AI Code Assistants

33,924

Self-hosted AI coding assistant — run GitHub Copilot-grade code completion on your own hardware with no cloud dependency.

View details
55
Repo Health
78
Technical
61
Dependency
Built with
Rust 93%
Updated 4 months ago
TypeScript
99%
Apache 2.0

Trigger.dev

AI Development · Automation · Developer Tools

16,606

Build and deploy fully-managed AI agents and background jobs in TypeScript — with no timeouts, durable retries, real-time observability, and elastic scaling built in.

View details
90
Repo Health
9
Technical
63
Dependency
Built with
TypeScript 99%
Updated 5 days ago
TypeScript
87%
Other

Webiny JS

Blogging · CMS · Ecommerce

8,047

Open-source, self-hosted CMS on AWS serverless — a TypeScript framework you extend with code, not a product you configure through a UI.

View details
90
Repo Health
86
Technical
61
Dependency
Built with
TypeScript 87%
JavaScript 12%
Updated 6 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers