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

@reallyme/crypto

v0.3.9

Published

ReallyMe crypto SDK for TypeScript/JavaScript with an explicit, pinned provider set.

Readme

@reallyme/crypto

npm License

@reallyme/crypto is the TypeScript SDK for ReallyMe Crypto. It provides typed, synchronous APIs for Node.js and browsers, with explicit JavaScript and package-owned WASM providers.

The package shares algorithm identifiers, byte formats, typed failures, and conformance vectors with the Rust, Swift, Kotlin, and Android SDKs. Availability is provider-specific; unsupported routes fail closed.

Installation

npm install @reallyme/crypto

Example

import { ReallyMeCrypto } from "@reallyme/crypto";

const digest = ReallyMeCrypto.hash(
  "SHA2-256",
  new TextEncoder().encode("hello"),
);

The API is synchronous. Signature verification throws ReallyMeCryptoError on invalid input rather than returning a boolean that can be accidentally ignored.

KDF facade selectors are family-specific: deriveKey accepts only PBKDF2, deriveHkdf accepts only HKDF, and the JWA Concat KDF and KMAC methods accept their exact selectors. Argon2id uses the dedicated deriveArgon2id route with an immutable profile version rather than an iteration count.

Post-Quantum and WASM

Classical primitives are backed by pinned @noble packages. The primitives that must stay identical to Rust — ML-KEM, ML-DSA, SLH-DSA, X-Wing, Argon2id, HPKE, and others — are backed by a WASM module that ships prebuilt with the package.

Applications may either install the WASM provider once for the package-level ReallyMeCrypto convenience API, or build isolated facade instances with an explicit provider object. Missing WASM providers fail closed with provider-failure. JWK/JWKS helpers delegate base64url and JCS canonicalization to the published @reallyme/codec package, so applications that use those helpers should also install the Codec WASM provider.

JSON and protobuf JWKS ingress routes accept at most 1,024 keys. Encoded JWK and JWKS protobuf inputs are capped at one mebibyte before decoding, and an embedded canonical JCS value is capped at 8 KiB. These limits apply equally to the direct message adapters and byte-oriented helpers.

import { readFileSync } from "node:fs";
import { installReallyMeCodecWasmProvider } from "@reallyme/codec";
import { initSync as initCodecWasm } from "@reallyme/codec/wasm/reallyme_codec_wasm.js";
import {
  createReallyMeCrypto,
  createReallyMeWasmProvider,
  installReallyMeWasmProvider,
  ReallyMeCrypto,
} from "@reallyme/crypto";
import { initSync as initCryptoWasm } from "@reallyme/crypto/wasm/reallyme_crypto_wasm.js";

// Provider constructors validate the dynamically imported module as `unknown`
// against the package's explicit required-export list.
const wasmProvider: unknown = await import(
  "@reallyme/crypto/wasm/reallyme_crypto_wasm.js"
);
const codecWasmProvider: unknown = await import(
  "@reallyme/codec/wasm/reallyme_codec_wasm.js"
);

const wasmUrl = import.meta.resolve(
  "@reallyme/crypto/wasm/reallyme_crypto_wasm_bg.wasm",
);
initCryptoWasm({ module: readFileSync(new URL(wasmUrl)) });
installReallyMeWasmProvider(wasmProvider);
const isolatedCrypto = createReallyMeCrypto({
  wasmProvider: createReallyMeWasmProvider(wasmProvider),
});

const codecWasmUrl = import.meta.resolve(
  "@reallyme/codec/wasm/reallyme_codec_wasm_bg.wasm",
);
initCodecWasm({ module: readFileSync(new URL(codecWasmUrl)) });
installReallyMeCodecWasmProvider(codecWasmProvider);

const keyPair = ReallyMeCrypto.generateKemKeyPair("X-Wing-768");
const isolatedKeyPair = isolatedCrypto.generateKemKeyPair("X-Wing-768");

The explicit facade form is preferred for Workers, SSR, tests, and multi-bundle applications because each instance owns its provider routing and does not depend on package-global mutable state.

The package-owned WASM provider derives ML-DSA, ML-KEM, and X-Wing seed-based keypairs inside Rust and returns the public key produced by that implementation. Custom provider objects are trusted providers: if an application supplies its own seed-derived keypair provider, it is responsible for public-key correspondence and must be covered by its own conformance evidence.

Raw WASM Module Contract

The raw @reallyme/crypto/wasm/reallyme_crypto_wasm.js export is an internal provider artifact for installing or constructing ReallyMeWasmProvider instances. Direct raw WASM calls are unsupported for application logic. Use the typed TypeScript facades, which validate caller inputs, numeric ranges, provider outputs, aliasing, and cleanup before invoking the raw module.

This distinction matters for numeric parameters: JavaScript-to-WASM glue can coerce raw number arguments before Rust receives them. The supported facades reject out-of-range Argon2id, KMAC, HPKE, and RSA selector or length values before provider dispatch. Package checks verify that the README, package exports, TypeScript declarations, and generated WASM glue continue to agree on this support boundary and that no ambient global crypto-provider functions are used.

Variable-length direct primitive inputs are capped at one mebibyte before any WASM copy or provider dispatch. Authenticated ciphertext may additionally carry the 16-byte tag. HPKE info is capped at 65,530 bytes so the fixed five-byte key-schedule label remains within RFC 9180's two-byte context-length limit.

Browser WASM Lifecycle

Argon2id V1 and V2 require 256 MiB and 512 MiB of working memory respectively. WebAssembly linear memory does not shrink, so an instance can retain that resident allocation after derivation. Browser applications should run Argon2id in a short-lived dedicated Worker and terminate the Worker after use, especially on memory-constrained devices.

Treat a WebAssembly trap as fatal for that provider instance. The SDK maps the trap to provider-failure, but does not guarantee that an instance interrupted mid-operation remains reusable; discard its Worker or provider context before performing another operation.

The generated loader resolves its .wasm file by relative URL and does not embed a content hash. The npm tarball protects the installed package artifact, but applications that separately host WASM bytes should use immutable asset URLs and verify those bytes against a deployment-controlled digest before initialization.

Memory Hygiene

Rust-owned secret buffers are zeroized by the Rust implementation and WASM adapters. JavaScript Uint8Array values are best-effort only: engines, WASM marshalling, providers, protobuf codecs, debuggers, and crash reporters can create copies outside the SDK's control. Clear caller-owned byte arrays as soon as practical:

bestEffortClear(secretBytes);

Explicit provider results must be independently owned Uint8Array values that do not overlap caller inputs or sibling result fields. The facade rejects aliases as provider-failure without modifying caller storage. Malformed provider-owned secret outputs are cleared before the same typed failure is returned.

AES-KW provider results must have the exact RFC 3394 plaintext + 8 or wrapped - 8 length. The facade wipes and rejects a returned typed array whose length violates that contract. KMAC keys and customization strings are capped at 4 KiB, contexts at 64 KiB, and outputs at 64 KiB before WASM copies are created.

Do not move private keys, passwords, plaintext, shared secrets, or derived keys through strings or JSON paths.

Protobuf Process Boundary

processOperationResponse(request) accepts one generated binary CryptoOperationRequest. processOperationResponseJson(requestJson) accepts the strict generated ProtoJSON view only for non-secret hash, verification, key-generation, encapsulation, and sender-export requests. Both return binary CryptoOperationResponse bytes, so malformed input, unsupported algorithms, and resource-limit failures preserve their structured protobuf branch and reason. This is the single executable structured response contract.

ProtoJSON is request-only. Decode returned binary protobuf with the generated exports from @reallyme/crypto/proto. Secret-bearing operation selectors are rejected before JSON value deserialization and must use protobuf bytes. Clear caller-owned Uint8Array values after use.

Documentation

The complete documentation, provider matrix, protocol contracts, and conformance specifications are available in the main repository:

https://github.com/reallyme/crypto

License

Licensed under either the MIT License or the Apache License, Version 2.0, at your option. See LICENSE. Third-party components retain their own licenses and notices.