SHA-3 Just Quietly Arrived in WebCrypto. Here’s What It Means for Your Hash Generator.

Published on May 22, 2026 by The Kestrel Tools Team ‱ 9 min read

Deno 2.8 shipped today, and tucked into the release notes — between a TypeScript bump and a node:test improvement — is a single line that’s actually a small platform shift: SHA3 variants (SHA3-256, SHA3-384, SHA3-512) supported in crypto.subtle.digest. That’s the first major JavaScript runtime to expose SHA-3 through the WebCrypto API natively. Browsers don’t have it. Node’s crypto.subtle doesn’t have it. For ten years, if you wanted SHA-3 in JavaScript, you shipped a 14 KB polyfill or you lived without it.

So: does this matter? If you’re building a client-side hash generator, an integrity-checking script, or anything that touches crypto.subtle.digest, the answer is a soft yes — and the nuance is worth a few minutes, because the framing in most articles (‘SHA-3 is more secure than SHA-2!’) is wrong in a way that causes real downstream confusion.

This post is the sha-3 webcrypto crypto subtle digest decision guide for 2026: what SHA-3 actually is (it’s not ‘a better SHA-2’), where you can call it today, what changes when you can call it everywhere, and whether you should switch. There’s a runtime-support table at the end that, as of this writing, doesn’t exist anywhere else.

Should you switch your hash generator from SHA-256 to SHA-3?

No, not yet, and probably not for the reason you’re thinking. SHA-3 is not ‘more secure’ than SHA-256 in any practical sense. Both have a 256-bit output, both have a 128-bit collision-resistance level, and neither has any known attack better than brute force in 2026. SHA-3 was designed as a backup in case a structural weakness was ever found in SHA-2 — not as a replacement that fixes a flaw SHA-2 has today.

The practical reasons to stay on SHA-256 in your hash generator for now:

  • Universal support. SHA-256 runs in every browser, every Node version, every Deno version, every runtime that exposes WebCrypto at all. Switch to SHA-3 today and your code only works in Deno 2.8+.
  • Hardware acceleration. Modern x86 (Intel SHA Extensions, since 2016) and ARMv8 (since 2018) ship SHA-256 instructions in silicon. SHA-3 has no equivalent in mainstream consumer CPUs. Pure-software SHA-3 is roughly 2–3× slower than hardware-accelerated SHA-256 on the same machine.
  • Output compatibility. Existing tooling — shasum, sha256sum, package manifests, integrity attributes, blockchain protocols — emits SHA-256 hex strings. Switching to SHA-3 means re-coordinating with everyone who consumes your hashes.

The one case where SHA-3 is the right answer today is if you’re already in a SHA-3 ecosystem (Ethereum’s keccak256, certain post-quantum signature schemes, NIST FIPS-202 compliance requirements) — and in those cases you knew that before you read this post.

What SHA-3 actually is (and why it’s not ‘SHA-256 plus one’)

The naming is genuinely misleading. SHA-3 is not an iteration on SHA-2 the way SHA-2 was an iteration on SHA-1. They’re built on completely different mathematical foundations and were standardized seven years apart for different reasons.

SHA-2 (2001) uses the Merkle–DamgĂ„rd construction — the same internal pattern as MD5 and SHA-1. You break the input into fixed-size blocks, process each one through a compression function that mixes it with the running hash state, and emit the final state as the digest. This works. It’s also the construction behind every hash function that has ever been broken (MD5, SHA-1), and the breaks always exploited some weakness in the compression function or in length-extension attacks the construction enables.

SHA-3 (2015) uses the Keccak sponge construction, which won NIST’s seven-year public competition specifically because it has a structurally different design margin. Instead of compressing input into a small state and emitting it, the sponge ‘absorbs’ input into a large state (1600 bits for SHA3-256) by XOR-ing chunks in and permuting, then ‘squeezes’ the output by reading bytes off the state and permuting again between reads. Length-extension attacks don’t work against sponges. The internal state is much larger than the output, which gives the design a lot of slack.

The upshot: SHA-3 is not a stronger version of SHA-2 against any known attack. It’s a structurally different hash function with similar security properties and a different failure mode. If a flaw were ever found in Merkle–DamgĂ„rd that affected SHA-256, SHA-3 would almost certainly survive — and vice versa. NIST recommended in their 2015 standard that organizations should keep SHA-2 as the default and have SHA-3 available as a drop-in alternative. That recommendation is still current in 2026.

This matters for your hash generator because the user-facing copy on most online tools still says things like ‘SHA-3 is the latest, most secure hash algorithm.’ That’s wrong. The honest framing is: SHA-3 is the alternative-construction hash in case SHA-2 ever needs to be replaced.

Where you can actually call SHA-3 in crypto.subtle.digest today

This is the part of the answer that nobody has written down clearly, so here it is in a single table.

Runtimecrypto.subtle.digest('SHA3-256', ...)crypto.subtle.digest('SHA-256', ...)
Deno 2.8+ (released 2026-05-22)✅ Native✅ Native
Deno 2.7 and earlier❌ Not supported✅ Native
Node.js 22 LTS, 24 LTS❌ Not in subtle.digest✅ Native
Node.js node:crypto.createHash('sha3-256')✅ Available since Node 12✅ Available
Bun 1.x❌ Not in WebCrypto✅ Native
Chrome / Edge / Chromium❌ Not in WebCrypto✅ Native
Firefox❌ Not in WebCrypto✅ Native
Safari / WebKit❌ Not in WebCrypto✅ Native
Cloudflare Workers❌ Not in WebCrypto✅ Native

Deno 2.8 is the first runtime to expose SHA-3 through the WebCrypto API specifically. Node has had SHA-3 in node:crypto.createHash since version 12 (2019), but that’s a different API — Node-specific, callback-style in the legacy form, and not portable to browsers.

If you want SHA-3 to actually work cross-runtime in 2026, the only realistic options are:

  1. Run only on Deno 2.8+. Calling crypto.subtle.digest('SHA3-256', buffer) works natively. Your code is then portable to any future runtime that adds SHA-3 to WebCrypto.
  2. Use a JS library like @noble/hashes or js-sha3. These are audited, ~3 KB minified, and run anywhere JavaScript runs. The cost is a tiny bundle hit and the performance penalty of running the hash in WASM or pure JS instead of native code.
  3. Use the Node-specific API on Node, WebCrypto on Deno, a polyfill in browsers. This is what most real codebases end up doing today, with a thin abstraction layer that picks the right path per runtime.

For a client-side hash generator running in a browser, option 2 is the only one that works at all in 2026. Browsers do not expose SHA-3 in WebCrypto, and that’s not on the W3C spec roadmap as far as we can tell. Cloudflare and other edge runtimes have signaled openness to following Deno but haven’t shipped anything.

What the Deno 2.8 API actually looks like

The call site is identical to any other crypto.subtle.digest call. There’s no new module, no new flag, no permission check. Just a new algorithm string:

const data = new TextEncoder().encode('hello world');

const sha256 = await crypto.subtle.digest('SHA-256', data);
const sha3_256 = await crypto.subtle.digest('SHA3-256', data);
const sha3_384 = await crypto.subtle.digest('SHA3-384', data);
const sha3_512 = await crypto.subtle.digest('SHA3-512', data);

const hex = (buf: ArrayBuffer) =>
  [...new Uint8Array(buf)].map((b) => b.toString(16).padStart(2, '0')).join('');

console.log('SHA-256  :', hex(sha256));
// b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9

console.log('SHA3-256 :', hex(sha3_256));
// 644bcc7e564373040999aac89e7622f3ca71fba1d972fd94a31c3bfbf24e3938

A few things worth noting:

  • Algorithm names use a hyphen. It’s 'SHA3-256', not 'SHA-3-256' or 'sha3-256'. The strings are case-sensitive in the WebCrypto spec. Deno follows the W3C WebCrypto algorithm registry for these names.
  • No Keccak variants are exposed. SHA-3 is the NIST-standardized form (FIPS 202), which differs from the original Keccak in a single padding byte. If you specifically need the original Keccak (e.g. for Ethereum’s keccak256), you still need a library — crypto.subtle.digest('SHA3-256', ...) will give you a different hash than Ethereum tooling expects.
  • It’s a one-shot API. Just like SHA-256 in WebCrypto, you hand it the full input and get a Promise<ArrayBuffer> back. There’s no streaming or incremental hashing in the standard. For large files, the same Blob.stream() + chunking pattern that worked for SHA-256 still applies.
  • Output sizes are exactly what you’d expect. SHA3-256 returns 32 bytes (256 bits), SHA3-384 returns 48 bytes, SHA3-512 returns 64 bytes. Hex strings are 64, 96, and 128 characters long respectively.

For verification: the SHA3-256 hash of 'hello world' (UTF-8, 11 bytes, no trailing newline) is 644bcc7e564373040999aac89e7622f3ca71fba1d972fd94a31c3bfbf24e3938. You can confirm against openssl dgst -sha3-256 (OpenSSL 1.1.1+) or any reference implementation.

How a hash generator UI should expose this in 2026

If you’re building or maintaining a hash generator (web tool, CLI, or library), the practical guidance for 2026 is straightforward:

  • Keep SHA-1, SHA-256, SHA-384, and SHA-512 as the default visible algorithms. They work everywhere, they’re hardware-accelerated, and they cover ~99% of real-world use cases.
  • Offer SHA-3 as an optional, clearly labeled alternative. Not ‘the most secure’ — just ‘SHA-3 (Keccak), for FIPS-202 compliance or post-quantum migration paths.’
  • If you’re running in a browser, you’ll need a small library (e.g. @noble/hashes SHA-3, ~3 KB minified) regardless of what runtime trends look like. Don’t gate SHA-3 on a browser flag — it isn’t coming on the W3C roadmap.
  • If you’re running in Deno or a Deno-compatible edge runtime, you can use crypto.subtle.digest natively for SHA-3 and avoid the bundle entirely. A small runtime-detection wrapper picks the native path when available and falls back to the library otherwise.
  • Don’t deprecate SHA-256. It is not on a path to deprecation. Both NIST and the IETF still recommend SHA-256 as the default cryptographic hash function for general-purpose use. SHA-3 is an alternative, not a successor.

At Kestrel Tools, our Hash Generator currently exposes SHA-1, SHA-256, SHA-384, and SHA-512 — the four algorithms WebCrypto has shipped natively in browsers since 2018. Adding SHA-3 means shipping a small library to every visitor, which we’ll likely do once a clear use case in our analytics shows up. The tool runs entirely client-side regardless of which algorithm you pick: same crypto.subtle.digest pattern, same zero-upload guarantee, same DevTools network-tab verification trick described in our earlier in-browser hashing post.

A minimal cross-runtime SHA-3 wrapper

If you do want to write SHA-3-aware code today that works on Deno 2.8 natively and falls back to a library elsewhere, here’s the pattern:

import { sha3_256 as nobleSha3_256 } from '@noble/hashes/sha3';

async function sha3_256(data: Uint8Array): Promise<Uint8Array> {
  // Prefer native WebCrypto when available (Deno 2.8+, future runtimes).
  if (typeof crypto?.subtle?.digest === 'function') {
    try {
      const buf = await crypto.subtle.digest('SHA3-256', data);
      return new Uint8Array(buf);
    } catch (err) {
      // Algorithm not supported by this runtime — fall through.
      if (!(err instanceof Error && /not supported|unrecognized/i.test(err.message))) {
        throw err;
      }
    }
  }

  return nobleSha3_256(data);
}

A few notes on that wrapper:

  • The feature-detect uses a try/catch because there’s no synchronous way to ask WebCrypto ‘do you support SHA-3?’ before calling it. Deno 2.8 succeeds; Node, browsers, Bun, and earlier Deno throw a NotSupportedError (or similar), and the wrapper falls back.
  • The fallback only loads the library code when needed via static import. If you want true lazy loading (only ship the library when the runtime needs it), use a dynamic import('@noble/hashes/sha3') inside the fallback branch and accept the additional Promise.
  • The error-message regex is fragile across runtimes — Deno, Node, and browsers phrase the ‘unsupported algorithm’ error differently. In production code, treat any non-AbortError as the signal to fall back, on the assumption that a runtime that can’t do SHA-3 won’t get further than the call site.

For production tools, the library-only path is simpler and the bundle cost (~3 KB) is small enough that the runtime detection doesn’t pay for itself. We’d only reach for the wrapper above in code that runs primarily on Deno and only occasionally on other runtimes.

The takeaway

Deno 2.8’s SHA-3 support is a small but interesting platform shift: the first major JavaScript runtime to expose SHA-3 through the standard WebCrypto API. It’s a sign that other runtimes — Node, Bun, the edge platforms — may follow. Browsers probably won’t.

For your hash generator in 2026:

  • Keep SHA-256 as the default. It’s universal, hardware-accelerated, and not deprecated.
  • Offer SHA-3 if you have a use case (FIPS-202 compliance, post-quantum migration, ecosystem compatibility) — but label it accurately as an alternative, not an upgrade.
  • In browsers, you’ll need a library for SHA-3 because WebCrypto doesn’t ship it and isn’t on a path to.
  • In Deno 2.8+, SHA-3 is now a single line of code with no dependencies and full hardware-portable execution.

If you want to drop a file or string into a hash generator and see SHA-256, SHA-384, and SHA-512 outputs side by side right now — all running client-side, no upload, no log — try Kestrel Tools’ Hash Generator. When SHA-3 lands in mainstream browsers (or when our usage data tells us we should ship the polyfill anyway), it’ll show up there too.