js-sha256 vs crypto-js vs sha.js vs sha256
Client-Side SHA-256 Hashing Libraries for Web Applications
js-sha256crypto-jssha.jssha256Similar Packages:

Client-Side SHA-256 Hashing Libraries for Web Applications

crypto-js, js-sha256, sha.js, and sha256 are JavaScript libraries that provide SHA-256 cryptographic hashing functionality for use in browser environments. These packages enable developers to generate secure hashes from strings, typed arrays, or other data sources without relying on native Web Crypto APIs, which may not be available or suitable in all contexts. While all four support the SHA-256 algorithm, they differ significantly in scope, API design, implementation approach, and maintenance status.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
js-sha2563,672,22795739.6 kB9a year agoMIT
crypto-js016,394487 kB2793 years agoMIT
sha.js029766.1 kB1610 months ago(MIT AND BSD-3-Clause)
sha256048-411 years ago-

Client-Side SHA-256 Hashing: crypto-js vs js-sha256 vs sha.js vs sha256

When you need to compute SHA-256 hashes in the browser — for password pre-hashing, integrity checks, or blockchain-related tasks — you’ll likely consider one of these four libraries. They all promise SHA-256, but their design philosophies, APIs, and suitability vary widely. Let’s break them down.

⚠️ Deprecation Warning: Avoid sha256

First, the bad news: sha256 is deprecated. Its npm page explicitly states: "This package is no longer maintained." It hasn’t been updated since 2016 and only accepts strings as input. For any new project, skip this entirely.

// sha256 (deprecated — do not use)
import sha256 from 'sha256';
const hash = sha256('hello'); // works only with strings

Now, let’s compare the three viable options.

🧩 API Style: Functional vs Object-Oriented vs Streaming

js-sha256: Simple Function Calls

This library gives you a direct, stateless function. Pass in data, get a hex string back. No instantiation, no chaining.

// js-sha256
import { sha256 } from 'js-sha256';

const hash1 = sha256('hello');
const hash2 = sha256(new Uint8Array([104, 101, 108, 108, 111])); // also supports typed arrays

It also offers a .create() method if you need incremental updates:

const hasher = sha256.create();
hasher.update('he');
hasher.update('llo');
const final = hasher.hex();

crypto-js: Word Arrays and Method Chaining

crypto-js uses its own WordArray type internally. You typically pass strings or typed arrays, but the output is a WordArray object that you must convert to a string.

// crypto-js
import CryptoJS from 'crypto-js';

const hash = CryptoJS.SHA256('hello').toString(); // toString() gives hex
// Or with explicit encoding
const hash2 = CryptoJS.SHA256(CryptoJS.enc.Utf8.parse('hello')).toString();

It’s more verbose but integrates with other crypto-js features like HMAC:

const hmac = CryptoJS.HmacSHA256('message', 'key').toString();

sha.js: Stream-Like Interface (Node.js Style)

sha.js mimics Node’s crypto.createHash('sha256') API. You create a hasher instance, feed it data, then call .digest().

// sha.js
import { sha256 } from 'sha.js';

const hasher = sha256();
hasher.update('hello');
const hash = hasher.digest('hex'); // specify output format

It also supports piping and works seamlessly in Node.js:

// Same code runs in Node.js and browser
const hash = require('sha.js').sha256().update('hello').digest('hex');

📥 Input Flexibility: What Data Can You Hash?

All three active libraries accept strings, but their support for binary data differs.

  • js-sha256: Accepts string, Array<number>, Uint8Array, and ArrayBuffer. Very flexible for modern web apps dealing with files or crypto keys.
sha256(new Uint8Array([72, 101, 108, 108, 111]));
  • crypto-js: Accepts strings and WordArray. To use Uint8Array, you must first convert it:
const wordArray = CryptoJS.lib.WordArray.create(uint8Array);
const hash = CryptoJS.SHA256(wordArray).toString();
  • sha.js: Accepts string and Buffer (in Node) or Uint8Array (in browser via polyfill). In practice, you’ll often pass strings or convert binary data to buffers.
hasher.update(new Uint8Array([72, 101, 108, 108, 111]));

🧪 Incremental Hashing: Updating Mid-Stream

Need to hash large files in chunks? All three support it, but with different ergonomics.

  • js-sha256:
const hasher = sha256.create();
hasher.update(chunk1);
hasher.update(chunk2);
const result = hasher.hex();
  • crypto-js does not support incremental updates for SHA-256. Each call to SHA256() is stateless. You’d need to concatenate all data first.

  • sha.js:

const hasher = sha256();
hasher.update(chunk1);
hasher.update(chunk2);
const result = hasher.digest('hex');

So if you’re processing file uploads or streams, avoid crypto-js for this use case.

🌐 Browser vs Node.js Compatibility

  • js-sha256: Pure ES modules, works everywhere modern JS runs. No dependencies.
  • crypto-js: Built for browsers, but can run in Node.js with bundlers. Uses its own encoding system.
  • sha.js: Designed to mirror Node’s crypto API, so it’s ideal for isomorphic apps. Works in browsers via bundlers or direct inclusion.

🔒 Security and Implementation

All three use well-reviewed, constant-time(ish) implementations suitable for non-cryptographic secret handling (e.g., client-side proof-of-work). However, never use client-side hashing as a substitute for server-side security — secrets can always be extracted from the browser.

None of these libraries use the native Web Crypto API (window.crypto.subtle.digest), which is faster and more secure but requires async/await and doesn’t support incremental updates. If you only need one-off hashes and can use async, consider Web Crypto instead:

// Native Web Crypto (async, no external deps)
const buffer = new TextEncoder().encode('hello');
const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');

But if you need sync hashing, incremental updates, or IE11 support, stick with one of these libraries.

📊 Summary Table

Featurecrypto-jsjs-sha256sha.jssha256
Maintenance✅ Active✅ Active✅ Active❌ Deprecated
SHA-256 Only?❌ (Many algos)✅ (SHA family)❌ (Multiple algos)
Input TypesString, WordArrayString, Array, TypedArrayString, Buffer, Uint8ArrayString only
Incremental Hashing
API StyleObject-orientedFunctionalStreaming (Node-like)Functional
Bundle ImpactHighVery LowMediumLow (but old)

💡 Final Recommendation

  • For most frontend apps: Use js-sha256. It’s tiny, fast, supports modern data types, and has a dead-simple API.
  • If you already use crypto-js for AES or HMAC: Stick with it for consistency, but know you’re pulling in extra weight.
  • For isomorphic apps sharing code with Node.js: Choose sha.js to keep your hashing logic identical across environments.
  • Never use sha256 — it’s outdated and unmaintained.

Remember: client-side hashing is about convenience or protocol compliance, not security. Always validate and re-hash on the server when it matters.

How to Choose: js-sha256 vs crypto-js vs sha.js vs sha256

  • js-sha256:

    Choose js-sha256 if you want a lightweight, zero-dependency, and modern implementation focused exclusively on SHA-256 (and related variants like SHA3-256). It supports strings, arrays, and typed arrays out of the box, offers a clean functional API, and is actively maintained — ideal for performance-sensitive frontend applications where minimal footprint matters.

  • crypto-js:

    Choose crypto-js if you need a full-featured cryptography library that includes SHA-256 alongside many other algorithms (AES, HMAC, PBKDF2, etc.) and utilities like encoders and word arrays. It’s well-suited for applications requiring multiple cryptographic operations beyond just hashing, though its broader feature set comes with increased bundle size and complexity.

  • sha.js:

    Choose sha.js if you prefer a Node.js-compatible stream-based API that mirrors the standard crypto module and supports multiple hash algorithms including SHA-256. It’s useful when you need consistent hashing logic across both Node.js and browser environments, especially in isomorphic applications, though its streaming model may be overkill for simple one-off hashes.

  • sha256:

    Do not choose sha256 for new projects. The package is deprecated (as noted on its npm page) and unmaintained. While it works for basic string hashing, it lacks support for modern input types like Uint8Array, has no updates since 2016, and offers no advantages over actively maintained alternatives.

README for js-sha256

js-sha256

Build Status Coverage Status CDNJS
NPM
A simple SHA-256 / SHA-224 hash function for JavaScript supports UTF-8 encoding.

Demo

SHA256 Online
SHA224 Online
SHA256 File Online
SHA225 File Online

Download

Compress
Uncompress

Installation

You can also install js-sha256 by using Bower.

bower install js-sha256

For node.js, you can use this command to install:

npm install js-sha256

Usage

You could use like this:

sha256('Message to hash');
sha224('Message to hash');

var hash = sha256.create();
hash.update('Message to hash');
hash.hex();

var hash2 = sha256.update('Message to hash');
hash2.update('Message2 to hash');
hash2.array();

// HMAC
sha256.hmac('key', 'Message to hash');
sha224.hmac('key', 'Message to hash');

var hash = sha256.hmac.create('key');
hash.update('Message to hash');
hash.hex();

var hash2 = sha256.hmac.update('key', 'Message to hash');
hash2.update('Message2 to hash');
hash2.array();

Node.js

If you use node.js, you should require the module first:

var sha256 = require('js-sha256');

or

var sha256 = require('js-sha256').sha256;
var sha224 = require('js-sha256').sha224;

or

const { sha256, sha224 } = require('js-sha256');

TypeScript

If you use TypeScript, you can import like this:

import { sha256, sha224 } from 'js-sha256';

RequireJS

It supports AMD:

require(['your/path/sha256.js'], function(sha256) {
// ...
});

Example

sha256(''); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
sha256('The quick brown fox jumps over the lazy dog'); // d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592
sha256('The quick brown fox jumps over the lazy dog.'); // ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c
sha224(''); // d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f
sha224('The quick brown fox jumps over the lazy dog'); // 730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525
sha224('The quick brown fox jumps over the lazy dog.'); // 619cba8e8e05826e9b8c519c0a5c68f4fb653e8a3d8aa04bb2c8cd4c

// It also supports UTF-8 encoding
sha256('中文'); // 72726d8818f693066ceb69afa364218b692e62ea92b385782363780f47529c21
sha224('中文'); // dfbab71afdf54388af4d55f8bd3de8c9b15e0eb916bf9125f4a959d4

// It also supports byte `Array`, `Uint8Array`, `ArrayBuffer` input
sha256([]); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
sha256(new Uint8Array([211, 212])); // 182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f

// Different output
sha256(''); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
sha256.hex(''); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
sha256.array(''); // [227, 176, 196, 66, 152, 252, 28, 20, 154, 251, 244, 200, 153, 111, 185, 36, 39, 174, 65, 228, 100, 155, 147, 76, 164, 149, 153, 27, 120, 82, 184, 85]
sha256.digest(''); // [227, 176, 196, 66, 152, 252, 28, 20, 154, 251, 244, 200, 153, 111, 185, 36, 39, 174, 65, 228, 100, 155, 147, 76, 164, 149, 153, 27, 120, 82, 184, 85]
sha256.arrayBuffer(''); // ArrayBuffer

Benchmark

jsPerf Benchmark

License

The project is released under the MIT license.

Contact

The project's website is located at https://github.com/emn178/js-sha256
Author: Chen, Yi-Cyuan (emn178@gmail.com)