DEV Community

Cover image for I built an open-source WhatsApp Business inbox for teams — here's how
Terglos
Terglos

Posted on

I built an open-source WhatsApp Business inbox for teams — here's how

The problem

If you've ever tried integrating 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 need a UI for your team to actually use it.

The 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.

Tercela inbox

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

The tech stack

I made some deliberate choices here that I'm happy with:

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

This is probably the most important design choice. Instead of hardcoding WhatsApp everywhere, I built an adapter interface. WhatsApp is just one implementation.

Adding a new channel (email, webchat, Telegram) means implementing that interface — the inbox, contacts, and routing all work the same regardless of the channel.

Drizzle ORM with named schemas

Instead of dumping everything in the public schema, I organized tables into PostgreSQL schemas:

  • auth → users
  • channels → channels, templates
  • contacts → contacts
  • inbox → conversations, messages
  • config → settings
  • storage → media

This keeps things clean as the database grows.

Bun native WebSocket

No Socket.io, no ws package. Bun has built-in WebSocket support with pub/sub. When a new message comes in via webhook, the API publishes to the relevant topic and every connected client gets
the update instantly.

Auto-migrations on boot

Drizzle migrations run automatically when the API starts. No manual db:migrate step in production — deploy and it just works.

What's next

  • AI / Chatbot support
  • Webchat 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.

GitHub logo tags-dev / tercela

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.

License: AGPL v3 GitHub Stars Bun Hono Nuxt PostgreSQL Drizzle ORM

Tercela Inbox

Features · Quick Start · API Docs · Contributing · Roadmap


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…

Top comments (0)