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

@whi/argon2-wasm

v0.5.1

Published

Argon2 wasm bindings with all inputs exposed

Readme

Argon2 Wasm

Wasm bindings for Argon2 with all inputs exposed — password, salt, secret (the keyed input K, e.g. a pepper), and associated_data (X). Backed by the RustCrypto argon2 crate.

Output is a raw Argon2 hash, version 0x13 (v=19), fixed at 64 bytes. Inputs are byte arrays (Buffer / Uint8Array).

Install

npm install @whi/argon2-wasm

Usage

Node (CommonJS)

const crypto = require('crypto');
const { argon2, verify, HashType } = require('@whi/argon2-wasm');

const password        = Buffer.from("password");
const salt            = crypto.randomBytes( 16 );
const secret          = crypto.randomBytes( 8 );   // keyed input (K); [] for none
const associated_data = new Uint8Array();

const hash = Buffer.from( argon2(
    password,
    salt,
    secret,
    associated_data,
    2,                  // iterations
    4,                  // parallelism
    1 << 8,             // memory_size (KiB), must be >= 8 * parallelism
    HashType.Argon2id,  // Argon2d | Argon2i | Argon2id
));

console.log( hash.toString('base64') );

verify(
    hash,
    password,
    salt,
    secret,
    associated_data,
    2, 4, 1 << 8, HashType.Argon2id,
);
// returns true

Cloudflare Workers

import { argon2, verify, HashType } from '@whi/argon2-wasm';

Works as-is in a Worker bundled by Wrangler: the package's exports map has a workerd condition pointing at a Workers-specific entry, so no manual wasm instantiation is needed. This is tested on every build (tests/e2e) by installing the packed package into a fixture Worker, bundling it with Wrangler, and running it in workerd.

Bundlers and Node (ESM)

import { argon2, verify, HashType } from '@whi/argon2-wasm';

Outside Workers, import resolves to wasm-pack's bundler build, which imports the wasm as an ES module. In Node that relies on Node's experimental wasm-module support (Node prints an ExperimentalWarning); use require to avoid it.

API

  • argon2(password, salt, secret, associated_data, iterations, parallelism, memory_size, hash_type) → Uint8Array

    The raw 64-byte Argon2 hash.

  • verify(hash, password, salt, secret, associated_data, iterations, parallelism, memory_size, hash_type) → boolean

    Recomputes the hash from the given inputs and compares it to hash.

  • HashType — enum: Argon2d, Argon2i, Argon2id.

secret is Argon2's keyed input K; pass an empty array for none. memory_size is in KiB and must be at least 8 * parallelism.

Development

Requirements: rustup (the channel and wasm32 target are pinned in rust-toolchain.toml), wasm-pack, node + npm, and jq.

make test     # build the package and run the test suite
make pkg      # build the publishable package into ./pkg

make test runs two layers, which can also be run on their own against an existing build:

npm run test:integration  # the built ./pkg in Node, incl. the reference vectors
npm run test:e2e          # the packed tarball in a Wrangler-bundled Worker (workerd)

Crypto invariant — read before changing the hashing dependency or parameters

The output bytes of argon2() are a frozen contract. Stored credentials are verified by recomputing the hash and comparing (verify() in src/lib.rs), so if the output for a given input ever changes, every existing stored credential stops validating — a silent, account-wide breakage.

tests/vectors/reference-vectors.json pins that contract: a corpus of known-answer vectors that tests/unit/test_vectors.js asserts the build reproduces byte-for-byte. These are the canonical bytes stored credentials were created with — originally produced by the argon2min crate that this package used before, and reproduced exactly by the current RustCrypto argon2 backend (verified by a differential test during the migration).

Practical rules for a future change:

  • Bumping the argon2 crate, or any change to hashing: keep make test green. If the vectors still pass, output is unchanged and the change is safe.
  • Never regenerate reference-vectors.json to make a failing suite pass — that rewrites the answers instead of the code and destroys the guarantee. The generator (tests/vectors/generate.cjs) refuses to overwrite the file without --force for exactly this reason.
  • --force regeneration is only for a deliberate migration that re-hashes every stored credential (e.g. moving to stronger Argon2 parameters) — not a routine bump.