npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fuzdev/blake3_wasm

v0.1.1

Published

BLAKE3 hashing compiled to WASM

Readme

@fuzdev/blake3_wasm

BLAKE3 hashing for TypeScript/JS, compiled to WASM from the blake3 Rust crate, @BLAKE3-team/BLAKE3.

Install

Two builds with the same API:

npm i @fuzdev/blake3_wasm        # SIMD — faster, 45 KB
npm i @fuzdev/blake3_wasm_small  # no SIMD — smaller, 32 KB

Use @fuzdev/blake3_wasm unless optimizing bundle size (or using Bun with its current SIMD issue). It enables blake3's WASM SIMD optimizations and is 2-3x faster at 64KB+ inputs on Deno and Node. @fuzdev/blake3_wasm_small is ~30% smaller but loses the 2-3x SIMD gains (but it's up to ~2.5x faster on Bun, which has a WASM SIMD problem). See benchmarks for details (includes a comparison to the SIMD-lacking @connor4312/blake3, blake3-wasm on npm).

Also available via npm: specifier in Deno (jsr coming soon, user requests will speed it up):

import { hash } from 'npm:@fuzdev/blake3_wasm';

Only import one — importing both loads two separate WASM modules. To swap builds without changing imports, use a bundler alias:

// vite.config.ts — use the small build everywhere
export default {
	resolve: {
		alias: { '@fuzdev/blake3_wasm': '@fuzdev/blake3_wasm_small' },
	},
};

Usage

import { Blake3Hasher, derive_key, hash, keyed_hash } from '@fuzdev/blake3_wasm';

// one-shot hash — returns 32-byte Uint8Array
const digest = hash(new TextEncoder().encode('hello'));
console.log(digest.length); // 32

// keyed hash (MAC) — key must be 32 bytes
const key = new Uint8Array(32);
const mac = keyed_hash(key, new TextEncoder().encode('hello'));

// key derivation
const derived = derive_key('my-app', new TextEncoder().encode('secret'));

// streaming hasher — same result as one-shot above
const hasher = new Blake3Hasher();
hasher.update(new TextEncoder().encode('hel'));
hasher.update(new TextEncoder().encode('lo'));
const result = hasher.finalize(); // same bytes as `digest`
hasher.free(); // release WASM memory, or use `using` — see API below

Browser

In browsers, call init() once before using any hash functions. It's a no-op if already initialized, so calling it unconditionally is safe.

import { hash, init } from '@fuzdev/blake3_wasm';

await init();

const digest = hash(new TextEncoder().encode('hello'));

Node and Deno initialize automatically — init() is only needed in browsers. The browser entry uses new URL('./blake3_wasm_bg.wasm', import.meta.url) internally, which Vite and webpack handle automatically. Other bundlers may need a plugin for WASM assets.

Vite: Exclude from dependency pre-bundling so the .wasm file resolves correctly:

// vite.config.ts
export default {
	optimizeDeps: {
		exclude: ['@fuzdev/blake3_wasm'],
	},
};

Without this, Vite pre-bundles the JS into .vite/deps/ but doesn't copy the WASM binary alongside it, causing a 404 at runtime. This is a common Vite issue with WASM packages.

For synchronous initialization in Web Workers, use init_sync:

import { init_sync } from '@fuzdev/blake3_wasm';

const wasm = await fetch('/blake3_wasm_bg.wasm').then((r) => r.arrayBuffer());
init_sync({ module: wasm });

Hashing a ReadableStream

import { derive_key_stream, hash_stream, keyed_hash_stream } from '@fuzdev/blake3_wasm';

// file: File from <input>, drop event, or fetch Response
const digest = await hash_stream(file.stream());
const mac = await keyed_hash_stream(key, file.stream());
const derived = await derive_key_stream('my-app', file.stream());

API

All functions return 32-byte (256-bit) digests. BLAKE3 supports variable-length output (XOF) but this API does not currently expose it — 32 bytes covers most use cases and XOF may be added in the future (open a discussion if you'd like it).

One-shot functions

hash(data: Uint8Array): Uint8Array

Returns 32-byte digest.

keyed_hash(key: Uint8Array, data: Uint8Array): Uint8Array

Keyed hash (MAC). Throws if key is not exactly 32 bytes.

derive_key(context: string, key_material: Uint8Array): Uint8Array

Key derivation. Returns 32 bytes.

Streaming hasher

const hasher = new Blake3Hasher();

Create a hasher for plain hashing.

Blake3Hasher.new_keyed(key: Uint8Array): Blake3Hasher

Keyed hasher (MAC). Throws if key is not exactly 32 bytes.

Blake3Hasher.new_derive_key(context: string): Blake3Hasher

Hasher in key derivation mode.

hasher.update(data: Uint8Array): void

Feed data incrementally.

hasher.finalize(): Uint8Array

Returns 32-byte digest. Non-destructive — can call repeatedly.

hasher.finalize_and_reset(): Uint8Array

Finalize and reset in one call.

hasher.reset(): void

Reset to initial state. Preserves keyed/derive mode.

hasher.free(): void

Release WASM memory. Supports using for automatic cleanup:

using hasher = new Blake3Hasher();
hasher.update(data);
return hasher.finalize();
// hasher.free() called automatically

Stream functions

hash_stream(stream: ReadableStream<Uint8Array>): Promise<Uint8Array>

Hash a stream. Returns 32-byte digest.

keyed_hash_stream(key: Uint8Array, stream: ReadableStream<Uint8Array>): Promise<Uint8Array>

Keyed hash a stream. Key must be exactly 32 bytes. Returns 32-byte digest.

derive_key_stream(context: string, stream: ReadableStream<Uint8Array>): Promise<Uint8Array>

Derive-key hash a stream. Returns 32-byte digest.

Stream functions handle hasher cleanup automatically, even if the stream throws mid-read.

Benchmarks

Cross-runtime results (Deno, Node.js, Bun, Wasmtime) are available in the GitHub repository.

License

MIT