I built an open-source WhatsApp Business inbox for teams — here's how
Source: Dev.to
The Problem
If you’ve ever tried integrating the WhatsApp Business API for customer support, you know the pain: Meta’s verification process, webhook configuration, message‑template management, media handling, real‑time updates… and then you still need a UI for your team to actually use it.
Existing options are either expensive SaaS platforms or closed‑source tools you can’t customize. I wanted something self‑hosted, open‑source, and easy to deploy.
So I built Tercela.
What is Tercela?
Tercela is an open‑source omnichannel platform for customer communication. Right now it supports WhatsApp — you connect your WhatsApp Business account and get a shared inbox where your team can manage all conversations.
Features
- Shared inbox – all WhatsApp conversations in one place
- Real‑time messaging – messages appear instantly via WebSocket
- Message templates – create, edit, and sync templates with Meta
- Contact management – centralized contact database
- Agent assignment – route conversations to team members
- Media support – images, audio, video, documents via S3‑compatible storage
- Multi‑language UI – English, Spanish, Arabic, Hindi, Indonesian, Turkish
Tech Stack
| Layer | Technology | Why? |
|---|---|---|
| Backend | Hono + Bun | Hono is lightweight and fast; Bun gives native performance |
| Frontend | Nuxt 4 + Nuxt UI | File‑based routing, auto‑imports, great component library |
| Database | PostgreSQL + Drizzle ORM | Type‑safe queries, automatic migrations on boot |
| Real‑time | Bun native WebSocket | No Socket.io overhead, pub/sub built‑in |
| Auth | JWT (HS256) | Simple, stateless |
| API docs | OpenAPI + Scalar | Interactive docs auto‑generated from route definitions |
Monorepo Structure
tercela/
├── apps/
│ ├── api/ # Hono + Bun (port 3333)
│ └── web/ # Nuxt 4 (port 3000)
├── packages/
│ └── shared/ # Shared types & utilities
└── docker-compose.yml
Architecture Decisions
Channel‑Adapter Pattern
Instead of hard‑coding WhatsApp everywhere, I built an adapter interface. WhatsApp is just one implementation. Adding a new channel (email, web‑chat, Telegram, …) only requires implementing that interface, while the inbox, contacts, and routing stay unchanged.
Drizzle ORM with Named Schemas
Tables are organized into PostgreSQL schemas rather than dumping everything into public:
| Schema | Contents |
|---|---|
auth | Users |
channels | Channels, templates |
contacts | Contacts |
inbox | Conversations, messages |
config | Settings |
storage | Media files |
This keeps the database tidy as it grows.
Bun Native WebSocket
No extra socket.io or ws packages. Bun’s built‑in WebSocket support provides pub/sub out of the box. When a webhook delivers a new message, the API publishes to the relevant topic and every connected client receives the update instantly.
Auto‑Migrations on Boot
Drizzle migrations run automatically when the API starts. No manual db:migrate step in production – just deploy and it works.
What’s Next
- AI / chatbot support
- Web‑chat widget (embed on any website)
- Email channel
- Analytics dashboard
Looking for Feedback
This is early stage and I’d love to hear from the community:
- Does this solve a real problem for you?
- What channels would you want to see next?
- Architecture feedback — what would you do differently?
Contributions are welcome — even if it’s just opening an issue with a feature idea.
Open‑source omnichannel platform for customer communication
Tercela
Open‑source omnichannel platform for customer communication
Connect channels like WhatsApp, manage conversations in real time, and organize contacts — all in a unified interface.
Badges
Screenshot
Quick links
Features
Messaging
- Omnichannel inbox – Manage all conversations from a single dashboard
- WhatsApp integration – Send and receive messages via WhatsApp Cloud API
- Real‑time updates – WebSocket‑powered live messaging
- Message templates – Create, edit, and sync WhatsApp message templates with Meta
- Media support – S3‑compatible storage for images, audio, video, and documents
Management
- Contact management – Centralized contact database with metadata
- Agent assignment – Route conversations to team members
- Channel adapter pattern – Extensible architecture to add new channels
Developer Experience
- REST API with OpenAPI docs – Interactive API reference via Scalar
- Automatic migrations – Versioned database migrations applied on boot
- Docker‑ready – One command to run the entire stack
- Monorepo – Clean separation of concerns

