An open-source support inbox: live chat, email, and social channels in one place, with canned replies, teams and a help centre.
Build me the support inbox I actually need instead of a hosted Chatwoot: live chat and email in one place, with canned replies and a help centre. Read this first: the product you are replacing is open source, and self-hosting it is a real answer. What you pay for is the hosted instance and the social channel integrations — WhatsApp and Instagram each need an approved application, and that is the part you cannot build around. If chat and email are enough, build this. STACK - Node 20+ with Fastify, server-rendered HTML with a little vanilla JS - SQLite through better-sqlite3, WAL mode - A chat widget under 20KB gzipped, from my own domain - Caddy in front THE DATA MODEL - contacts: id, email, name, phone, external_id, traits_json, first_seen_at, last_seen_at - conversations: id, contact_id, channel, subject, status, assignee_id, team_id, priority, first_response_at, resolved_at, created_at - messages: id, conversation_id, direction, author_kind, author_id, body_md, body_html, is_private, delivered_at, read_at, created_at - attachments: id, message_id, path, sha256, mime, bytes - email_threads: conversation_id, message_id_header, references_json — how a reply finds its conversation - canned_replies: id, shortcut, title, body_md, team_id - labels, teams, agents, and a mapping between them - sla_targets: id, priority, first_response_minutes, resolution_minutes - events: id, conversation_id, kind, actor, meta_json, at — append-only, and the whole history of a conversation EMAIL, WHICH IS HARDER THAN CHAT - Inbound by a provider webhook or by IMAP, parsed properly: MIME, HTML and text alternatives, inline images, attachments, and the quoted history stripped for display but kept in full - Threading by Message-ID, In-Reply-To and References, with a subject-plus-participant fallback. Never by subject alone — 'Re: your order' from two customers must not become one conversation - Outbound sets the headers that keep the thread intact, and comes from an address on a domain with SPF, DKIM and DMARC configured. The README lists the records - Automatic replies and bounces detected and not turned into a customer conversation, which is how a support inbox starts talking to itself - A per-recipient send cap, so a loop cannot mail somebody four hundred times THE CHAT WIDGET - One script, one init call, optionally with a signed identity token from my backend - Shadow DOM, my accent, dark and light, keyboard navigable, focus trapped while open, Escape closes - Messages delivered by polling a small endpoint with a backoff, faster while the conversation is active and slower when it is idle. Sockets are the obvious answer and the wrong first one: polling is far simpler and enough for any volume a small team handles. Say where that stops being true - Offline: when nobody is available, the widget says so honestly and takes an email address instead of pretending - The full conversation history for an identified visitor, so they do not start again on every page - Typing indicators and read receipts only if they are real. A fake typing indicator is a small lie that people notice THE INBOX - One list with filters: unassigned, mine, by team, by label, by status, by priority - Keyboard driven — a support inbox is used all day and the mouse is the slow part - Private notes alongside replies, visibly different, never sendable by accident - Canned replies by shortcut with variable substitution, inserted at the cursor - Assignment manually or round-robin within a team, with availability respected - Merge two conversations from the same person, keeping both histories THE HELP CENTRE - Collections and articles in Markdown, public, searchable, with its own sitemap and canonical URLs - Search the articles from inside the widget and send one into the conversation - Failed searches recorded — an empty result is a request for an article - Was this helpful, counted per article MEASURING - First response time, resolution time, conversations per agent, by day and by hour - Computed at query time from the events table, never stored as totals - SLA breaches visible before they happen, not reported afterwards OPERATIONS - .env: DATABASE_PATH, STORAGE_PATH, BASE_URL, SMTP_URL, IMAP_URL, WIDGET_JWT_SECRET, SESSION_SECRET, HASH_SALT - Migrations on boot, each once - Attachments scanned for type by content, stored outside the web root, served through a signed URL - Nightly backup off the machine, restore script - Health endpoint that checks both mail directions WHAT MATTERS MOST Email threading and the bounce filter. Build those first and point a real address at it for a week — chat is a straightforward append-only list, but an inbox that splits a customer's thread in three, or that replies to its own bounces, is unusable from the first day. Give me the repository, the widget script, migrations, .env.example, a seed inbox, and a README with deploy steps behind Caddy and the DNS records for mail.
What you lose
- Channel integrations for WhatsApp, Instagram and the rest, each with its own approval process
- A hosted instance with upgrades and backups
- A live chat widget maintained against browser changes
If you would rather not build
- Zammad, a mature open help desk
What it costs
read from their page 15 Aug 2026
| Plan | Billed monthly | Billed yearly | Last read |
|---|---|---|---|
| — | $19/mo | — | 15 Aug 2026 |
Their pricing page is where these came from. Seeing a different price? Tell us.
The escape hatch
open source · no votes, no paid placement
FreeScout
$0A light PHP help desk that runs on ordinary shared hosting.
freescout-help-desk/freescoutfree · open source
Why this verdict
our own opinion · changed only by a person
84/100
Verdict yes at 84. The code is free, so this is Docker. Threading email by References rather than subject is the detail worth copying.
History
tracked since 10 Aug 2026 · nothing is ever overwritten
Questions about Chatwoot
answered from the record above
Is Chatwoot free?
No — the plan we track is $19 a month. Startups at around $19 per agent per month billed monthly on the cloud; the community edition is free to self-host.
Can you replace Chatwoot by building your own?
YES. Replaceable in one session with an AI coding agent. Replacement score 84 out of 100, build time one session. Read what you lose before you decide.
How much does Chatwoot cost?
$19 a month on Startups — $228 a year. Recorded 10 Aug 2026.
What do you lose by replacing Chatwoot?
Channel integrations for WhatsApp, Instagram and the rest, each with its own approval process; A hosted instance with upgrades and backups; A live chat widget maintained against browser changes. If any of those carry weight for you, keep paying.
Is there an open-source alternative to Chatwoot?
Yes: Chatwoot, FreeScout. The prompt on this page is for when you want it your way instead.
Related entries
same category first, most replaced first
Every week, something stops being worth paying for.
New verdicts, prices that moved, entries added. One email a week. Unsubscribe in one click. Nothing is being sent yet — your address is kept here, and the first issue is the first thing it is used for.
free forever · no tracking pixel · stored here, never passed to anyone

