The packages crypto, crypto-js, hash.js, and jssha all address the need for cryptographic hashing in JavaScript, but they serve fundamentally different roles depending on the runtime environment. crypto is the built-in Node.js module and cannot be used directly in browsers without heavy bundler shims, making it unsuitable for pure frontend logic. crypto-js is a comprehensive library offering a wide range of algorithms (hashing, encryption, encoding) designed specifically for browser compatibility. hash.js is a minimalist, dependency-free implementation focused strictly on hashing algorithms like SHA and MD5, prioritizing small bundle size. jssha is a specialized, rigorously tested library dedicated solely to SHA variants, often preferred for compliance-heavy applications requiring FIPS validation or specific HMAC implementations.
When building secure frontend applications, developers often need to generate hashes for data integrity, password verification, or digital signatures. While the concept is simple, the choice of library significantly impacts bundle size, security posture, and runtime compatibility. The packages crypto, crypto-js, hash.js, and jssha represent four distinct approaches to solving this problem in the JavaScript ecosystem.
cryptoThe crypto module is built directly into Node.js. It is highly performant and secure on the server, but it does not exist in the browser.
If you try to import crypto in a frontend project, your bundler (Webpack, Vite, etc.) must inject a polyfill. This often leads to massive bundle sizes and potential security inconsistencies because the polyfill may not match the Node implementation exactly.
Do not use crypto for pure browser logic. It is only viable if your code runs on the server or if you accept the overhead of shimming Node internals.
// crypto (Node.js only)
// This will FAIL in a standard browser environment without polyfills
const crypto = require('crypto');
const hash = crypto.createHash('sha256');
hash.update('sensitive-data');
const result = hash.digest('hex');
// Output: "7d38..." (Only works in Node)
crypto-jscrypto-js was built specifically to bring cryptographic functionality to the browser. It is a comprehensive library that includes hashing, encryption, and encoding utilities. It is the "batteries-included" option.
If your app needs to hash data and encrypt it (e.g., AES) or encode it (e.g., Base64), this library keeps your dependency tree flat by providing everything in one package. The trade-off is size; you are importing algorithms you might not use unless you configure your bundler to tree-shake effectively.
// crypto-js
import CryptoJS from 'crypto-js';
// Hashing SHA-256
const hash = CryptoJS.SHA256("sensitive-data").toString();
// Encryption (Bonus feature not available in hash-only libs)
const encrypted = CryptoJS.AES.encrypt("my message", "secret key").toString();
// Output: Hash is a hex string; Encrypted is a cipher string
hash.jshash.js takes a different philosophy. It provides only hashing algorithms. It does not do encryption, and it does not do encoding beyond what is necessary for the hash output.
This makes it incredibly lightweight. If you only need to calculate a checksum or a hash for a file upload, hash.js is often the most efficient choice. It supports streaming, allowing you to feed data in chunks, which is useful for hashing large files in the browser without running out of memory.
// hash.js
import hash from 'hash.js';
// Hashing SHA-256
const result = hash.sha256().update('sensitive-data').digest('hex');
// Streaming support (useful for large files)
const sha256 = hash.sha256();
sha256.update('part1');
sha256.update('part2');
const streamResult = sha256.digest('hex');
// Output: Hex string of the hash
jsshajssha is a specialist library focused entirely on Secure Hash Algorithms (SHA). It is known for its rigorous testing and compliance with federal standards (FIPS).
Unlike crypto-js which tries to do everything, or hash.js which is minimal, jssha focuses on correctness and robustness for SHA variants (SHA-1, SHA-224, SHA-256, SHA-384, SHA-512). It also has excellent support for HMAC (Hash-based Message Authentication Code), making it a strong candidate for authentication flows where you need to sign messages with a secret key.
// jssha
import JSSHA from 'jssha';
// Hashing SHA-256
const shaObj = new JSSHA("SHA-256", "TEXT");
shaObj.update("sensitive-data");
const hash = shaObj.getHash("HEX");
// HMAC Support (Signing with a key)
const hmacObj = new JSSHA("SHA-256", "TEXT");
hmacObj.setHMACKey("secret-key", "TEXT");
hmacObj.update("message-to-sign");
const hmac = hmacObj.getHMAC("HEX");
// Output: Hex string for both hash and HMAC
The way you interact with these libraries varies from static method calls to class instantiation.
crypto-js uses a static, chainable style that feels very modern but hides the internal state.hash.js uses a functional, chainable approach that exposes the streaming nature of hashing clearly.jssha uses a class-based constructor pattern, which is more verbose but explicit about the algorithm and input format.// Comparison of API Styles for SHA-256
// 1. crypto-js: Static method
const r1 = CryptoJS.SHA256("data").toString();
// 2. hash.js: Functional chain
const r2 = hash.sha256().update("data").digest('hex');
// 3. jssha: Class instantiation
const shaObj = new JSSHA("SHA-256", "TEXT");
shaObj.update("data");
const r3 = shaObj.getHash("HEX");
You need to hash a password in the browser before sending it over the network to reduce exposure.
jssha or hash.jsjssha offers high assurance, while hash.js offers speed and small size. Avoid crypto-js if you want to save bandwidth.// Using jssha for high-assurance password hashing
const shaObj = new JSSHA("SHA-256", "TEXT");
shaObj.update(userPassword);
const payload = { hash: shaObj.getHash("HEX") };
You need to encrypt sensitive user data before saving it to localStorage.
crypto-jshash.js and jssha cannot do this.// Using crypto-js for AES encryption
const encrypted = CryptoJS.AES.encrypt(secretData, passphrase).toString();
localStorage.setItem('secureData', encrypted);
You are uploading a 500MB video file and need to calculate its SHA-256 hash in the browser to verify integrity on the server.
hash.js// Using hash.js for streaming large files
const hasher = hash.sha256();
// Inside file reader chunk callback:
hasher.update(chunkArray);
// After file read complete:
const finalHash = hasher.digest('hex');
crypto in the browser unless you have a very specific build setup that guarantees the polyfill is secure and optimized. It is generally an anti-pattern in modern frontend architecture.bcrypt or argon2 for storing passwords in a database.crypto-js if you are building a micro-frontend or a widget where every kilobyte counts and you only need a single hash algorithm. The extra code for AES, RC4, and encoders is dead weight in that context.| Feature | crypto | crypto-js | hash.js | jssha |
|---|---|---|---|---|
| Environment | Node.js Only | Browser & Node | Browser & Node | Browser & Node |
| Primary Focus | General Crypto | All-in-One Toolkit | Minimal Hashing | SHA & HMAC Specialist |
| Encryption | â Yes | â Yes | â No | â No |
| Hashing | â Yes | â Yes | â Yes | â Yes (SHA only) |
| Bundle Size | N/A (Polyfill heavy) | Large | Very Small | Small/Medium |
| API Style | Stream/Static | Static Chain | Functional Chain | Class Instance |
| Compliance | High (Node) | Community Tested | Community Tested | FIPS Validated Options |
Your choice depends entirely on your constraints:
crypto-js. It is the only frontend-ready option here that handles AES and other ciphers.hash.js. It is perfect for simple checksums and integrity checks.jssha. Its focus on SHA correctness and HMAC makes it ideal for auth tokens and financial data.crypto module. Do not install external packages for Node.js backends unless you have a specific compatibility requirement.For most modern frontend applications that require only hashing, hash.js or jssha provides the best balance of performance and security without the bloat of unused encryption algorithms.
Do not choose crypto for frontend-only projects; it is a Node.js core module that requires polyfills to run in browsers, adding unnecessary complexity and bundle weight. Only consider this if you are writing isomorphic code that runs primarily on the server or if your build system automatically handles Node core shims seamlessly.
Choose crypto-js if you need a versatile toolkit that handles not just hashing (SHA, MD5) but also encryption (AES, Rabbit) and encoding (Base64, Hex) within a single dependency. It is ideal for general-purpose frontend security tasks where developer convenience and a broad algorithm selection outweigh the need for the absolute smallest file size.
Choose hash.js if your requirement is strictly limited to hashing algorithms and you prioritize a minimal footprint with zero dependencies. It is an excellent choice for performance-sensitive frontend applications where you need standard hashes like SHA-256 or MD5 without the overhead of encryption modules you won't use.
Choose jssha if your project demands high assurance, extensive test coverage, or specific compliance features like FIPS-180/197 validation for SHA algorithms. It is the best fit for enterprise-grade applications, financial tools, or scenarios where you need robust HMAC support and a library maintained with a focus on cryptographic correctness over feature breadth.
This package is no longer supported and has been deprecated. To avoid malicious use, npm is hanging on to the package name.
It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in.
Please contact support@npmjs.com if you have questions about this package.