Skip to content

Getting Started ​

Requirements ​

  • Node.js 22+ (download)
  • pnpm (recommended) or npm/yarn
  • A phone with WhatsApp (for the Baileys transport)

Don't have pnpm?

Install it with:

bash
npm install -g pnpm

ESM-only packages

@botmesh/core and the transport packages ship as pure ESM — there is no CommonJS build. Your project needs "type": "module" in its package.json (or a .mjs file extension). On Node >= 22.12 you can also require() them via Node's experimental require(esm) support, but the examples below use plain import.

Alpha — published under the alpha tag

botmesh is in alpha: every package is on npm, but only under the alpha dist-tag (changeset publish does not create latest). An install without a tag will not resolve, so always write pnpm add @botmesh/core@alpha. Once a stable version ships, the tag can be dropped.

Scaffold a project with create-botmesh ​

The fastest start is the create-botmesh CLI, which generates a runnable project. To run it from a checkout of this monorepo instead, point it outside the repo (pnpm --filter create-botmesh build && node packages/create-botmesh/lib/cli.js ../my-bot; a target inside the botmesh monorepo is refused unless you pass --force):

bash
npm create botmesh@alpha my-bot
npm create botmesh@alpha my-bot -- --template telegram --yes
TemplateWhat you get
baileys (default)WhatsApp via Baileys: scan a QR to link
metaWhatsApp Cloud API (webhook; needs Meta credentials and a public URL)
telegramTelegram Bot API (long-polling; needs a @BotFather token)
aiBaileys + @botmesh/ai business-scoped support autoresponder (ANTHROPIC_API_KEY)
gamesGuess the number, hangman, trivia, tic-tac-toe, rock-paper-scissors; scores in ctx.user
supportTickets per user, FAQ menu and human handoff
storeCatalog, per-user cart with a 7-day TTL and a checkout flow
restaurantMenu, delivery/pickup orders, "repeat my last order", table reservations
clinicAppointment booking (specialty, day, time), list/cancel appointments
ai-fullBusiness-scoped AI + keyword/regex intents + SQLite store + scheduler + slash commands + handoff (ANTHROPIC_API_KEY)

The use-case templates (games to ai-full) run on Baileys. The transport templates (baileys, meta, telegram, ai) install the built-in slash commands (/help, /reset, /cancel, /id, /ping), so /reset or /cancel escapes their sample menu flow.

FlagMeaning
-t, --template <name>One of the templates above (baileys when non-interactive)
--name <name>Package name (default: derived from the directory)
-y, --yesSkip prompts and use defaults
--overwriteAllow scaffolding into a non-empty directory
--forceAllow a directory inside the botmesh monorepo itself (refused by default)
-h, --helpShow help

Every project gets package.json (with npm start and npm run dev, the terminal simulator), src/bot.js, .env.example, .gitignore, README.md and an AGENTS.md with instructions for AI coding agents: the current v2 API, what does not exist (addAnswer, capture...) and the commands to run.

npm run dev needs no credentials. npm start in the meta, telegram, ai and ai-full projects checks the variables it cannot run without and, when .env is missing or incomplete, stops with one line naming them (Missing TELEGRAM_TOKEN: copy .env.example to .env ...) before connecting anything.

The generated package.json depends on the published @botmesh/* packages under the alpha dist-tag (^2.0.0-alpha.2 for the core, ^0.2.0-alpha.0 for the rest; the exact ranges come from create-botmesh/src/versions.ts, generated at build time). There is no latest yet, so installing them by hand needs @alpha. To point those dependencies at your local checkout of the monorepo instead, use workspace: ranges.

To set everything up by hand instead, follow the steps below.

Step 1 — Install the framework ​

The engine (@botmesh/core) is transport-agnostic: you pair it with a provider package. For WhatsApp over Baileys 7 (unofficial, QR login):

bash
mkdir my-bot
cd my-bot
pnpm init
pnpm add @botmesh/core@alpha @botmesh/baileys@alpha

Other transports behind the same IProvider contract:

TransportPackageStatusNotes
WhatsApp (Baileys 7)@botmesh/baileysAlphaUnofficial, QR login — what this guide uses
WhatsApp Cloud API@botmesh/metaAlphaOfficial Meta API, webhook-based, no ban risk
Telegram@botmesh/telegramAlphaBot API, long-poll or webhook
Facebook Messenger@botmesh/messengerExperimentalMeta Graph Send API, webhook-based
Instagram DM@botmesh/instagramExperimentalMeta Graph, webhook-based
Discord@botmesh/discordExperimentalGateway websocket + REST

Alpha packages are published on npm under the alpha dist-tag (install with @alpha). Experimental ones are real, tested implementations that stay private (unpublished) for now and may change. More experimental providers (Evolution API, WPPConnect, Twilio, HighLevel, Gupshup, Email and TikTok) and a capability matrix are in Channels.

Then add "type": "module" to the generated package.json so Node treats your files as ESM:

json
{
  "type": "module"
}

Step 2 — Create your bot ​

Create a bot.js file. In v2, constructing a bot requires a provider — WhatsApp session/auth options live on the provider, not on the bot:

ts
import { Bot } from '@botmesh/core'
import { BaileysProvider } from '@botmesh/baileys'

const bot = new Bot({
  provider: new BaileysProvider({
    session: 'my-bot',
    qr: { terminal: true, small: true },
  }),
})

bot.on('ready', () => console.log('✅ Bot connected!'))

bot.when('hola', async (ctx) => {
  await ctx.reply('👋 Hello! I am your bot.')
})

await bot.start()

Step 3 — Run and scan the QR ​

bash
node bot.js

You'll see a QR code in your terminal. Open it on your phone:

  1. Open WhatsApp
  2. Go to Settings → Linked Devices
  3. Tap Link a Device
  4. Scan the QR code

Done! Your bot is connected. Send "hola" (exactly, that's the default matching mode) from another phone and you'll get a reply.

Don't scan with the same phone

The QR is scanned with the phone that will be the bot, not the one sending messages.

Other transports, same bot code ​

Only the provider changes — when/flow/hooks/plugins are identical on every transport. For the official WhatsApp Cloud API:

ts
import { Bot } from '@botmesh/core'
import { CloudAPIProvider } from '@botmesh/meta'

const bot = new Bot({
  provider: new CloudAPIProvider({
    accessToken: process.env.META_TOKEN ?? '',
    phoneNumberId: process.env.META_PHONE_ID ?? '',
    verifyToken: process.env.META_VERIFY_TOKEN ?? '',
    appSecret: process.env.META_APP_SECRET, // required: verifies X-Hub-Signature-256
  }),
})

(The Cloud API is webhook-based: pass the raw request body of each inbound POST to provider.ingest(rawBody, headers) from your HTTP server — the signature is computed over the exact bytes Meta sent. Without appSecret the constructor throws; allowUnsignedWebhooks: true exists only for isolated local development.) See Channels for every other transport and Webhook server to mount webhook providers.

Next steps ​

Released under the MIT License.