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

@open-e2ee/signal-protocol-sdk

v0.1.0

Published

Signal Protocol E2EE SDK for TypeScript — Expo, React Native, browser, and Node. Post-quantum PQXDH and Double Ratchet.

Readme

OpenE2EE Signal Protocol SDK

End-to-end encrypted messaging for TypeScript apps. Signal Protocol, post-quantum by default, runs in Expo.

License: AGPL-3.0-or-later Types: TypeScript npm version native modules: 0 npm provenance Checks OpenSSF Scorecard

Website · Docs · Quick Start · Architecture · Security Model · Protocol Policy · Deviations


  • Pure TypeScript. No native modules, no prebuild step, no platform binaries to ship.
  • Runs where your app runs. Expo, React Native, modern browsers, and Node from one package.
  • Post-quantum by default. PQXDH and ML-KEM session establishment are on without configuration, and fail closed.
  • Real messaging features. Multi-device, groups, sealed sender, encrypted attachments, safety numbers.
  • Pluggable storage and relay. Device-local storage is required and yours; the relay is an interface, not a hosted service.
  • AGPL-3.0-or-later, or a commercial license. Building something closed-source? See COMMERCIAL.

Not affiliated with Signal Messenger. This is an independent implementation of the public Signal Protocol specifications — full notice in NOTICE. It is not wire-compatible with Signal Messenger or libsignal: messages, identities, and safety numbers do not interoperate, and every deliberate difference is documented in DEVIATIONS.

0.1.x — public APIs and persisted formats may change before 1.0.

See it run

Linking a second device on the demo page: the scenario runs, then reports what each device can read — the device that was already there holds both messages, and the newly linked device holds only the one sent after it existed.

A second device is linked to an account over the real QR handshake. The message sent before that device existed is not on it — not withheld by a policy, but unreadable because the device's keys did not exist when that message was encrypted.

Recorded from open-e2ee.dev/demo, which runs this package in the browser against the in-memory store and the in-memory relay: real protocol and cryptography, simulated in-memory infrastructure. Every scenario there prints the receiving device's own log, unedited.

Install

npm install @open-e2ee/signal-protocol-sdk

Installing straight from the repository also works — the package compiles itself during install, so TypeScript is the only build requirement:

npm install github:open-e2ee/signal-protocol-js

Adapters declare their runtime requirements as optional peer dependencies, so install the ones your chosen adapters need (for example expo-sqlite and expo-secure-store, or convex).

Quick Start

Two clients, one process, no account and no server. The relay holds the envelope; only Bob's device turns it back into text.

// Real protocol and cryptography; simulated in-memory infrastructure.
import { createSignalProtocolClient } from "@open-e2ee/signal-protocol-sdk";
import { inMemoryStore } from "@open-e2ee/signal-protocol-sdk/local/store/memory";
import { inMemoryRelay } from "@open-e2ee/signal-protocol-sdk/remote/relay/memory";

const relay = inMemoryRelay();
await relay.registerDevice("alice", { encryptedDeviceName: new ArrayBuffer(0) });
await relay.registerDevice("bob", { encryptedDeviceName: new ArrayBuffer(0) });

const alice = await createSignalProtocolClient({
  identity: { userId: "alice" },
  adapters: { storage: inMemoryStore(), relay },
});
const bob = await createSignalProtocolClient({
  identity: { userId: "bob" },
  adapters: { storage: inMemoryStore(), relay },
});

await alice.syncToServer();
await bob.syncToServer();

// Decrypted content reaches your app here, and nowhere else.
bob.registerHook("onMessageDecrypted", async (message) => {
  console.log(`${message.senderId}: ${message.content}`); // alice: hello
});

await alice.send("bob", "hello");   // the relay now holds ciphertext and metadata
bob.startRelaySubscription();       // delivery and local decryption start here

Every identifier above is a real export. This exact block is extracted from this README and executed against the packed package by this repository's CI on every change, and the same sequence runs in the engineering repository's automated checks.

Next: inspect what the relay actually stored, then compose the Expo + Convex production client.

How it compares

Measured from the GitHub API, the npm registry API, and the published package tarballs on 2026-08-03. Every alternative is a real project doing a real job; the axes below are the ones this SDK was built to change, not a general quality ranking.

| | Expo / React Native | Browser | Maintained | Post-quantum | TypeScript-native | Commercial license | |---|---|---|---|---|---|---| | @open-e2ee/signal-protocol-sdk | Yes | Yes | Yes — 0.1.x, active | Key agreement yes — PQXDH + ML-KEM, default and fails closed. Signatures no — identities are classical Ed25519 | Yes | Yes | | @signalapp/libsignal-client | No — Node native addon; the 0.99.3 tarball ships binaries for macOS, Linux, and Windows only | No | Yes — very active; repo push 2026-07-31 | Key agreement yes | No — Rust core with TypeScript bindings | No (AGPL-3.0 only) | | libsignal-protocol-javascript | No | Yes | No — archived, last push 2021-08-04 | No | No — JavaScript | No (GPL-3.0) | | @privacyresearch/libsignal-protocol-typescript | No documented React Native path | Yes | No — last npm publish 2023-05-06, last repo push 2023-07-18 | No | Yes | No (GPL-3.0) | | ts-mls | Not stated — browsers, Node, and serverless are the documented targets | Yes | Yes — very active; repo push 2026-08-03 | Key agreement and signatures — ML-KEM and ML-DSA-87 ciphersuites | Yes | Not needed (MIT) |

ts-mls implements MLS (RFC 9420), a different protocol with different properties — if MLS suits your product, it is a good library and this table is not an argument against it, and its post-quantum coverage reaches further than this SDK's. @signalapp/libsignal-client is the implementation Signal Messenger itself uses; its README states that use outside Signal Messenger is unsupported. If you are shipping a desktop or server application on Node, reach for it first.

The longer version of this table, with a paragraph on each project, is at open-e2ee.dev/compare.

Trust and verification

Cryptography deserves evidence rather than adjectives, so here is what there is and what there is not.

Audit status. Reviewed continuously by adversarial AI agents; not audited by any independent firm. Every change passes an adversarial AI review before it merges, and recurring whole-codebase AI audit passes run against the engineering repository. What that covers — and what it does not — is stated in the assurance summary. No independent firm has audited the SDK, and none is engaged. Nothing here should be read as a third-party assurance claim.

Security model and protocol policy. The security model states the threat model, what is in and out of scope, the storage boundary, and the resource limits. The protocol policy states which protocol modes are supported and which fail closed.

Specifications, pinned by revision. The implementation follows its own versioned profile based on these published specifications:

| Specification | Revision | |---|---| | X3DH | Revision 1, 2016-11-04 | | PQXDH | Revision 3, 2023-05-24 (last updated 2024-01-23) | | Double Ratchet | Revision 4, 2025-11-04 | | Sesame | Revision 2, 2017-04-14 | | ML-KEM Braid | Revision 1, 2025-02-21 (last updated 2025-09-26) | | FIPS 203 (ML-KEM) | Final, 2024-08-13 | | RFC 8032 (Ed25519) | — |

Not wire-compatible, and specific about why. This SDK cannot exchange messages with Signal Messenger or libsignal, cannot exchange identities with them, and its safety numbers will never match the ones a Signal Messenger client displays for the same two users. The cryptographic core is the same; the wire profile is deliberately its own. Identities are a versioned composite of separate X25519 and Ed25519 keys rather than one Curve25519 key, so signatures are ordinary RFC 8032 Ed25519 rather than XEdDSA; ML-KEM-1024 keys and ciphertexts are tagged 0x0A, distinct from the round-3 Kyber1024 0x08 tag. DEVIATIONS is the complete account — every difference from the specifications and from libsignal, with the reason, the cost, and the file that implements it. The threat model boundary is in the security model.

Dependencies: 6. Six direct production dependencies — @noble/ciphers, @noble/curves, @noble/hashes, @noble/post-quantum, async-lock, unique-names-generator — resolving to 6 packages in total: the only transitive edges are the @noble packages depending on one another, so the resolved tree adds nothing the list above does not already name. Everything else in the tree is a development or optional peer dependency.

Automated checks. The published repository is a mechanized export of a private engineering repository, filtered by an allowlist; the automated checks live there and have to pass before an export is cut. The assurance summary carries the current run figures — regenerated from a real run as part of every release, never hand-edited — and explains what the checks cover, what is not published, and why. The published repository runs its own build, typecheck, and production dependency audit in CI on every change.

Constant-time posture, honestly. JavaScript engines offer no machine-level constant-time contract, and this SDK cannot invent one. What exists is best-effort source-level work on selected paths: full-scan comparison for equal-length MACs and identity bytes, fixed-work derivation of both decapsulation candidates before masked selection, and equal-work rejection padding on selected replay and authentication paths. These are not timing-equivalence proofs. Secret-influenced remainder and compression arithmetic remains, and JIT compilation, allocation, garbage collection, and cache effects stay observable. secureZeroBytes() overwrites the exact typed array it is handed and nothing more — not copies, not strings, not engine temporaries. The threat model does not cover hostile same-process code or a high-assurance co-resident timing adversary, and it says so.

Reporting a vulnerability. Email [email protected] rather than opening an issue. Acknowledgment within 72 hours, initial assessment within 7 days; the full policy is in SECURITY.md.

Documentation

Hosted guides, quickstarts per runtime, and concept docs live at docs.open-e2ee.dev. The in-repo references below are versioned with the code:

License and warranty

Licensed under AGPL-3.0-or-later; see LICENSE. For proprietary products that cannot meet AGPL obligations, a commercial license is available — see COMMERCIAL or email [email protected].

The software is provided as is, without warranties or conditions of any kind. To the extent permitted by applicable law, copyright holders and contributors are not liable for damages arising from its use. Applications remain responsible for evaluating this SDK against their own requirements and for securing their deployment, storage, authentication, authorization, and operations. This summary does not modify the license; the complete warranty disclaimer and limitation of liability are in sections 15 and 16 of the GNU Affero General Public License.