js-sha1
A dependency-free, cross-environment SHA-1 hash function for JavaScript with full UTF-8 and HMAC support.
Repository Health
Technical Analysis
js-sha1 is a compact, standalone implementation of the SHA-1 hashing algorithm for JavaScript. It runs identically across Node.js, browsers, Web Workers, and AMD module loaders, computing digests from strings, byte arrays, typed arrays, and ArrayBuffers without requiring any external dependencies.
In Node.js it automatically delegates to the built-in crypto module for speed while falling back to a pure-JavaScript implementation everywhere else, so the same API produces identical results regardless of runtime. It also ships an HMAC-SHA1 implementation built on the same core, along with hex, byte-array, digest, and ArrayBuffer output formats.
The library has shipped as a single small file since 2014 and is widely used as a lightweight hashing primitive in front-end bundles, build tooling, and Node.js utilities where pulling in a larger crypto library would be overkill.
What You Get
- A single-file SHA-1 implementation with no runtime dependencies
- Automatic detection of Node.js, browser, Web Worker, CommonJS, and AMD environments
- Multiple output formats: hex string, byte array, digest array, and ArrayBuffer
- Built-in HMAC-SHA1 support via
sha1.hmac - UTF-8 string encoding handled internally, including surrogate pairs
- Support for hashing strings, plain arrays, typed arrays, and ArrayBuffers
Common Use Cases
- Generating quick checksums or fingerprints for cache keys and asset hashing in build tools
- Computing HMAC-SHA1 signatures for legacy API authentication schemes
- Client-side hashing in the browser where importing Node’s
cryptomodule isn’t an option - Hashing binary payloads (typed arrays/ArrayBuffers) in Web Workers without blocking the main thread
- Lightweight integrity checks in front-end bundles where a full crypto library would add unnecessary weight
Under The Hood
Architecture
js-sha1 is a single self-contained IIFE (src/sha1.js) that detects its host environment (Node.js, browser window, Web Worker self, CommonJS, or AMD) at load time and wires up the appropriate export path, with createMethod/createHmacMethod factory functions generating the callable sha1(...) function plus its .create(), .update(), and per-output-type (hex/array/digest/arrayBuffer) variants. Two constructor functions, Sha1 and HmacSha1 (which prototypally extends Sha1), hold all mutable hashing state (block buffer, running hash words, byte counters) as instance properties, and a sharedMemory flag lets the top-level convenience functions reuse a single static blocks array across calls to avoid repeated allocation. There is no external dependency graph to speak of — the entire library is one file with no imports beyond Node’s built-in crypto/buffer modules, used only as an optional fast path.
Tech Stack
The library itself has zero runtime dependencies and targets plain ES5 JavaScript for maximum compatibility across old and new engines alike. Its devDependencies are limited to a small, dated tooling chain: mocha and expect.js for tests, nyc for coverage, tiny-worker to simulate Web Worker environments under Node, uglify-js to produce the minified browser build in build/, and requirejs for AMD-loader test coverage. There is no bundler-driven build pipeline for the library source itself — npm run build is a single uglifyjs invocation, and TypeScript consumers get types from a hand-written index.d.ts rather than a generated declaration file.
Code Quality
The test suite (tests/node-test.js driving tests/test.js and tests/hmac-test.js) is thorough in environment coverage — it exercises the same hashing logic under Node.js CommonJS, simulated Webpack/browser globals, AMD, and real Web Worker execution via tiny-worker, toggling internal JS_SHA1_NO_* feature-detection flags to force each code path. Error handling is minimal but intentional: invalid input types throw a plain Error with a fixed message, and calling update() after finalize() throws rather than silently producing wrong output. The core hashing code favors terse, highly-optimized variable names (a, b, t, f) typical of hand-tuned cryptographic hot loops, which trades readability for performance — there’s no linter or type-checking configured for the source itself, though the shipped index.d.ts gives TypeScript consumers accurate types.
API Design
The public API is deliberately small: calling sha1(message) directly returns a hex digest, sha1.create() returns a chainable, incrementally-updatable hasher instance, and sha1.hex/array/digest/arrayBuffer expose alternate output encodings without any extra configuration objects. HMAC support mirrors this shape exactly under sha1.hmac, so anyone already familiar with the base API can pick up HMAC usage with no additional learning curve. There is essentially zero boilerplate to get started — require/import and call — which is a large part of why the package remains popular for one-off hashing needs despite Node’s built-in crypto module being able to do the same thing.