Skip to main content
This guide walks you through the minimal steps to get CoreCrypto running on your platform. By the end you will have:
  1. Opened an encrypted database.
  2. Initialized an MLS session.
  3. Created a conversation.
  4. Encrypted and decrypted a message.

Installation

1

Install the npm package

CoreCrypto is published as @wireapp/core-crypto. Install it with your package manager:
npm install @wireapp/core-crypto
The package ships two entry points:
  • @wireapp/core-crypto/browser — WASM binary for browsers and bundlers.
  • @wireapp/core-crypto/native — N-API binary for Node.js.
The browser entry point includes a .wasm binary that must be served as a static asset. See your bundler’s documentation for how to handle .wasm files.
2

Initialize the WASM module

Before using any CoreCrypto APIs in a browser context, initialize the WASM module once at startup:
import { initWasmModule } from "@wireapp/core-crypto/browser";

// Pass the path to the directory containing `index_bg.wasm`.
// Omit the argument if the file is served from the package root.
await initWasmModule("/assets/core-crypto/");
3

Open a database

CoreCrypto stores all keying material in an encrypted database. On WASM, this is backed by IndexedDB.
import {
  CoreCrypto,
  Database,
  DatabaseKey,
} from "@wireapp/core-crypto/browser";

// Generate or load a 32-byte database key.
const keyBytes = new Uint8Array(32);
crypto.getRandomValues(keyBytes);
const dbKey = new DatabaseKey(keyBytes.buffer);

// Open (or create) the database. The first argument is the database name.
const database = await Database.open("my-app-db", dbKey);
4

Create a CoreCrypto instance

Construct a CoreCrypto instance from the opened database:
const cc = CoreCrypto.new(database);
5

Initialize MLS in a transaction

All state-mutating operations run inside a transaction. Initialize MLS and register a credential within a single transaction:
import {
  ClientId,
  Credential,
  Ciphersuite,
} from "@wireapp/core-crypto/browser";

// Your MLS transport implementation — sends commits and messages
// to your delivery service.
const transport = {
  async sendCommitBundle(commitBundle) {
    // POST commitBundle to your delivery service
    return MlsTransportResponse.Success.new();
  },
  async sendMessage(message) {
    // POST message to your delivery service
    return MlsTransportResponse.Success.new();
  },
  async prepareForTransport(historySecret) {
    return historySecret.clientId.copyBytes();
  },
};

const encoder = new TextEncoder();
const clientId = new ClientId(encoder.encode("alice@device1").buffer);
const ciphersuite = Ciphersuite.Mls128Dhkemx25519Aes128gcmSha256Ed25519;

await cc.newTransaction(async (ctx) => {
  await ctx.mlsInit(clientId, transport);
  await ctx.addCredential(
    Credential.basic(ciphersuite, clientId)
  );
});
newTransaction commits all changes to the keystore if the callback returns successfully. If the callback throws, all changes are discarded.
6

Create a conversation

import { ConversationId } from "@wireapp/core-crypto/browser";

const conversationId = new ConversationId(
  encoder.encode("my-conversation-id").buffer
);

await cc.newTransaction(async (ctx) => {
  // Retrieve the credential registered during mlsInit.
  const [credentialRef] = await ctx.getCredentials();
  await ctx.createConversation(conversationId, credentialRef);
});
7

Encrypt and decrypt a message

// Encrypt a message as the conversation creator.
const plaintext = encoder.encode("Hello, MLS!");
const ciphertext = await cc.newTransaction(async (ctx) => {
  return await ctx.encryptMessage(conversationId, plaintext.buffer);
});

// On the receiving end, decrypt the message.
const decryptResult = await cc.newTransaction(async (ctx) => {
  return await ctx.decryptMessage(conversationId, ciphertext);
});

const decoder = new TextDecoder();
const decryptedText = decoder.decode(decryptResult.message);
console.log(decryptedText); // "Hello, MLS!"

Architecture

Understand the keystore, MLS provider, and FFI layers.

MLS protocol

Deep dive into MLS groups, epochs, and key schedules.

TypeScript guide

Full integration guide for the browser and Node.js.

API reference

Complete reference for all CoreCrypto types and methods.

Build docs developers (and LLMs) love