JavaScript-MD5

A zero-dependency JavaScript MD5 and HMAC-MD5 hashing implementation that runs identically in Node.js, browsers, and AMD module loaders.

Library
npm
v2.19.0
4,559stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
40/100Fair
Development Activity0
Maintenance0
Community60
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
72/100Good
Architecture70
Code Quality75
Innovation78
Learning Curve65

blueimp-md5 is a small, self-contained JavaScript implementation of the MD5 message-digest algorithm, based on the classic RSA Data Security reference algorithm and Paul Johnston’s original JS port. It exposes a single md5() function that computes hex or raw MD5 and HMAC-MD5 digests of a string, with correct handling of UTF-8 input via encodeURIComponent/unescape normalization before hashing.

The library ships as a UMD module, so the same js/md5.js file works unmodified whether it’s loaded via require() in Node.js, wired up through an AMD loader like RequireJS, bundled with webpack/Browserify, or dropped in as a plain <script> tag that exposes window.md5. It has zero runtime dependencies, making it a lightweight drop-in for checksum, cache-key, and identicon-style hashing needs where a full crypto library would be overkill.

What You Get

  • A single exported md5(string, key, raw) function covering four modes: hex MD5, hex HMAC-MD5, raw MD5, and raw HMAC-MD5
  • Correct UTF-8 string handling before hashing, verified against Unicode test fixtures
  • Zero runtime dependencies — the entire implementation is one small file
  • Universal module support: Node.js require, AMD/RequireJS define, or a global md5 when loaded via <script>
  • A prebuilt minified build (js/md5.min.js plus source map) alongside the readable source

Common Use Cases

  • Generating cache-busting or dedupe keys from arbitrary string content
  • Computing Gravatar-style avatar hashes (MD5 of a lowercased, trimmed email address)
  • Producing HMAC-MD5 signatures for legacy APIs that still require that scheme
  • Client-side checksums to detect whether form or file content has changed
  • Non-cryptographic fingerprinting where MD5’s speed and ubiquity matter more than collision resistance

Under The Hood

Architecture The entire library lives in one file, js/md5.js, wrapped in a single UMD IIFE that fans out to module.exports, AMD define, or a global $.md5 depending on the host environment. Internally it’s a straight-line functional pipeline with no classes or shared mutable state: str2rstrUTF8 normalizes input encoding, rstr2binl/binl2rstr convert between raw strings and the little-endian word arrays the MD5 round functions (md5ff/md5gg/md5hh/md5ii, all routed through md5cmn) operate on, and binlMD5 runs the four 16-step rounds per RFC 1321 before rstr2hex renders the final hex digest. rstrHMACMD5 layers the HMAC construction (ipad/opad XOR plus a second MD5 pass) on top of the same primitives. Because every function is a pure transform with an unambiguous single responsibility, the only thing that would break from a core-abstraction change is the word-array encoding contract between rstr2binl and binlMD5 — everything else composes around it cleanly.

Tech Stack The runtime has zero dependencies — package.json declares no dependencies block at all, only devDependencies for tooling: mocha 9 and chai 4 for tests, eslint 7 with eslint-config-blueimp, eslint-plugin-jsdoc, and eslint-config-prettier/eslint-plugin-prettier for linting/formatting, and uglify-js 3 to produce the shipped md5.min.js plus its source map via the build npm script. GitHub Actions (.github/workflows/test.yml) runs npm install, the build, and the test suite on Node 14 and 16 for every push and pull request. The published npm package (blueimp-md5) ships only js/*.js and js/*.js.map per the files field in package.json.

Code Quality test/test.js uses Mocha and Chai to assert hex and raw output for both plain MD5 and HMAC-MD5, explicitly covering ASCII and multi-byte UTF-8 (Japanese) input against known digest values — the UTF-8 cases exist specifically to pin down the encoding-normalization step, which is the part most implementations get wrong. Every function in md5.js carries a JSDoc block documenting parameters and return types, enforced by eslint-plugin-jsdoc, and the whole codebase is Prettier-formatted with a project-specific style config (no semicolons, single quotes, always-wrap arrow parens). There’s no TypeScript and no static type checking beyond what JSDoc/ESLint catch, but the combination of a real test suite, CI on two Node versions, and consistent linting is solid for a library of this scope.

API Design The public surface is exactly one function, md5(string, key, raw), with the last two parameters optional and used to select HMAC mode and raw-vs-hex output — there’s no configuration object, no class to instantiate, and no setup step beyond require/import. That minimalism is the whole point: a developer needs zero context to call md5('value') and get a hex digest back, and the same function handles the HMAC and raw-output variants without a second API to learn. The tradeoff is that boolean/positional flags (raw) are slightly less self-documenting than named options would be, but for a four-mode utility with a decade of stable behavior, the terse signature stays easy to hold in your head.

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

Search