OpenE2EE

Signal Protocol SDK

The Signal Protocol in pure TypeScript, for Expo, browser, and Node applications — with explicit storage, transport, and trust boundaries.

This SDK implements the Signal Protocol in pure TypeScript. It has no native modules, prebuild step, or platform binaries to ship. These properties let it run in Expo, where the alternatives do not.

The SDK generates and stores keys on the device, establishes sessions, ratchets, and hands your infrastructure ciphertext. It does not require a hosted service, and there is no configuration in which private keys or plaintext leave the device.

For production delivery, choose one of two separate paths. OpenE2EE Relay supplies managed encrypted delivery infrastructure. A self-hosted adapter keeps delivery in infrastructure that you operate. Both use the same device-side protocol boundary. Neither receives plaintext or device private keys.

Start on your runtime

Pick one here. Every page with runtime-specific instructions remembers the choice, so you will not have to pick again.

The runtime this SDK exists for, and the one with the most mature adapter. Protocol state lives in a SQLCipher-encrypted database. Its key lives in the iOS Keychain or Android Keystore.

npm install @open-e2ee/signal-protocol-sdk@1.0.0 expo-secure-store expo-sqlite drizzle-orm
import { expoStore } from '@open-e2ee/signal-protocol-sdk/local/store/expo';

Requires a development build: SQLCipher does not run in Expo Go. Expo setup has the full bootstrap and the seven integration questions answered.

What the SDK owns

Identity and prekey generation. Session establishment and ratcheting: X3DH, PQXDH, and the Double Ratchet, with post-quantum key agreement required by default. Multi-device state via Sesame, and group messaging via sender keys. Safety-number generation and comparison. Validation at every storage, relay, and serialized-state boundary.

What your application owns

User identity and account policy. The runtime storage adapter, which is the only required adapter and the one place private keys exist. Delivery and public-key distribution infrastructure. Encrypted attachment persistence. Trust verification and the user experience around it: including what you show a user when a contact's identity key changes.

That split is deliberate and it is not going to move. The SDK will not silently choose a backup strategy, an escrow mechanism, or a trust policy on your behalf.

Where to start

If you want to see it work, go to the quickstart: two identities and a real ciphertext, with no infrastructure.

If you evaluate the SDK, read what E2EE actually protects and what the relay can still see first. Both pages let you compare the implementation with its claims. The second page identifies limits that can invalidate product promises.

If you integrate the SDK, start with choosing adapters. This decision shapes everything else.

If you want managed delivery, start with the OpenE2EE Relay quickstart. It starts with device-owned development identity and one acknowledged message. Production identity, push, retention, and billing come afterward.

If you migrate from libsignal-protocol-javascript or @privacyresearch/libsignal-protocol-typescript, read the migration guide before you plan the work. There is no wire compatibility. The change requires a new architecture, and the guide states this fact in its first section.

Status

Independent implementation profile

This project is not affiliated with Signal Messenger LLC or Signal Technology Foundation. Compatibility with the published specifications is a design direction and a correctness oracle, not a promise of interoperability with the Signal Messenger service. The ML-KEM Braid tag differs from Signal Messenger's, so there is no wire compatibility with Signal Messenger either.

Licensed AGPLv3, with a commercial option: see licensing.

On this page