Zero is a lightweight framework for building bots. It combines adapters, store, middlewares, and sessions into a single orchestration layer. The design is inspired by web frameworks (Express, Koa, Hono) but tailored for event-driven bots.
bun add @nandcomputer/zero
# or
npm install @nandcomputer/zeroimport { createInMemoryStore } from "@nandcomputer/zero/store";
import { createZero } from "@nandcomputer/zero";
import { BaileysAdapter } from "@nandcomputer/zero/baileys";
const store = createInMemoryStore();
const adapter = new BaileysAdapter({});
const zero = createZero({ adapter, store });
zero.on("messages.upsert", async (z, ctx, payload) => {
const chat_id = payload.remoteId;
await z.send(chat_id, { text: "hello world" });
});This minimal bot listens for incoming messages and responds with "hello world".
- Responsible for connecting Zero to external platforms (WhatsApp, Telegram, Discord, etc).
- Each adapter defines:
message_event→ the main message event for that platformsend(roomId, message)→ send messageson(event, handler)→ listen to events
Adapters unify external APIs into a common interface, so the rest of your code is platform-agnostic.
- Provides an in-memory cache with optional persistence (e.g., Redis, database).
- Stores values as atoms: small reactive containers.
- Each atom has the following API:
set(value)→ update in memorypersist()→ save to backend storagefetch()→ retrieve the latest value from backendsubscribe(fn)→ watch for changes
Example:
const atom = ctx.store.set("count", 1);
await atom.persist();
atom.subscribe((v) => {
console.log("count updated:", v);
});
const fresh = await atom.fetch();- Sessions are atoms scoped to the current sender (message origin).
- Useful for storing user state across messages.
- API is similar to store atoms:
get,set,persist,subscribe.
Example:
const session = ctx.session.get();
if (!session) {
ctx.session.set({ user_id: "123", user_name: "alice" });
}
await session?.persist();
session?.subscribe((s) => {
console.log("session updated:", s);
});- Inspired by Express/Hono/Koa middleware.
- Run before event handlers.
- Can be applied globally (
"*") or scoped to specific events. - Common use cases: authentication, logging, metrics, validation.
Example:
zero.use(["messages.upsert"], async (ctx, next) => {
console.log("auth check");
return next();
});Middleware signature:
type Middleware<Message, Context, Events, Session> = (ctx: Context, next: () => Promise<void>) => Promise<void>;- Use
zero.on(event, handler)to register handlers. - Handlers run after all middlewares for that event.
- Each handler receives:
z→ the Zero instance (send,adapter, etc.)ctx→ context object (store,session,platform,message)payload→ raw event data from the adapter
Example:
zero.on("messages.upsert", async (z, ctx, payload) => {
const chat_id = payload.remoteId;
await z.send(chat_id, { ...payload, text: "hello" });
});- Adapter → abstract platform integration (WhatsApp, Telegram, etc.)
- Store → fast in-memory cache with optional backend persistence
- Session → per-user state management built on top of store
- Middleware → pre-handler pipeline, can intercept or modify context/events
- Handlers → business logic, bound to adapter events
- Stronger session typing
- Adapters for Telegram, Discord, Twilio
- Middleware plugin ecosystem
- Testing utilities
- Built-in rate limiting and retries