zapo is an independent implementation of the WhatsApp Web protocol — not a fork of Baileys. The concepts overlap (companion pairing, Signal sessions, an event stream), but the API is different and it is not a drop-in replacement. This page maps the patterns you already know.
Auth state, message shapes, and method names differ. Plan to rewrite your socket setup and handlers — but the mental model (pair → listen → send) carries over directly.
Move existing sessions over (no re-pair)
Switching libraries doesn’t have to mean re-pairing every session.wa-store-migrate converts Baileys auth state directly into zapo’s store layout — same device identity, same Signal sessions with every peer, no QR scan.
BaileysAuthSnapshot (the same { creds, keys } shape useMultiFileAuthState holds in memory), it returns a ZapoStoreSnapshot, and you write that into a fresh zapo store.
WaClient({ store, sessionId: 'default' }) at the resulting store and call connect() — it comes up as the existing device, with every peer Signal session intact.
Auth state in a database, not files? The
BaileysAuthSnapshot shape is just { creds, keys: { 'pre-key': {...}, 'session': {...}, 'sender-key': {...}, ... } }. If your Baileys storage is custom (one MySQL table per session, Postgres rows, Redis hashes, …), point your reader at that store and produce the same object — the migrate() call and the zapo write side stay identical. For multiple sessions, run the pipeline once per sessionId.Loss expectations. Migrating to zapo has no drops — every Signal domain transfers. Expect a few
warn-severity entries in losses: skipped HKDF message keys are dropped (sessions self-heal on the next message), only the latest sender-key state is kept (libsignal stores up to 5), and privacy-token timestamps lose sub-second precision. Full table on wa-store-migrate.Creating the socket
Baileys gives you a socket from a factory; zapo gives you aWaClient plus an explicit store.
creds.update to save by hand — the store persists credentials automatically. Pick any backend (SQLite, Postgres, MySQL, Redis, Mongo) on Installation.
Events
Baileys multiplexes everything throughsock.ev; zapo exposes a typed event per concern on client.
The full map is in Events. Each event is strongly typed via
WaClientEventMap.
Sending messages
{ type: 'image' | 'video' | 'audio' | 'document' | 'poll' | 'reaction' | … }) instead of Baileys’ shape-by-key object. Quoting/mentions move from the content object into the options argument ({ quote, mentions }).
API mapping
Key differences to keep in mind
- LID-first. zapo prefers the privacy-preserving LID identity over the phone-number JID. Reply to
event.key.remoteJid, and prefer LIDs when you have them. - Coordinator API. Features are grouped on getters (
client.message,client.group,client.privacy, …) instead of flat socket methods — see Architecture. - Pluggable, typed stores. Persistence is a first-class layer with official backends, not a JSON folder. See Stores.
- No auto-reconnect. Like Baileys, you drive reconnection — but read Errors & disconnects for the reason codes.
- No number registration. zapo connects with already-paired/registered credentials; it does not register new numbers.
