Chatwoot is a Rails support desk whose widget bundle is capped at 300 KB, and whose branching note still says v1.x.x
Open-source live-chat, email support, omni-channel desk. An alternative to Intercom, Zendesk, Salesforce Service Cloud etc. 🔥💬
At a glance
- What is it?
- Chatwoot is a MIT licensed, self-hosted customer support platform that pulls live chat, email, and messaging channels into one inbox, with a help center, campaigns, and a Captain AI agent on top. It is a serious piece of Rails engineering with real size budgets and a real back end queue, and its documentation has drifted in small ways that will cost you an afternoon if you do not read it first.
- Who is it for?
- Chatwoot suits a support team that wants its conversation data on infrastructure it controls and its own domain rather than a vendor inbox, and that can afford to run Rails, Sidekiq, Postgres, Redis, and a Vite build as one system.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The dev stack is Rails, Sidekiq, Vite, Postgres, Redis, and Mailhog
The docker-compose.yaml file shows the architecture without any abstraction. A single service runs the Rails server on port 3000 with an entrypoint script and a bind address of 0.0.0.0. A second service runs the background worker, and its command line is where the queue configuration lives:
command: ["bundle", "exec", "sidekiq", "-C", "config/sidekiq.yml"]A third service is Vite, with VITE_DEV_SERVER_HOST pointed at the service name, which is how the Rails app reaches the asset dev server inside the compose network. Postgres, Redis, and Mailhog are listed as dependencies, and Mailhog is there to catch outbound mail locally so you do not send real email to real customers. Every service mounts the working tree at /app with a delegated volume plus named volumes for node_modules, the packs output, the Rails cache, and the bundle, so a container rebuild does not lose your installed gems.
The widget bundle is capped at 300 KB and the SDK at 40 KB
The most concrete engineering constraint in the repository is a size budget, and it is enforced by a script rather than a guideline. The package manifest carries a size-limit configuration with two entries:
"size-limit": [
{
"path": "public/vite/assets/widget-*.js",
"limit": "300 KB"
},
{
"path": "public/packs/js/sdk.js",
"limit": "40 KB"
}
],A size script runs the check, and separate analysis builds exist for the SDK and the widget. The reason to care is that the widget is the JavaScript your customer loads on every page of your own site, so its weight is your reputation to spend, not the vendor's. The 40 KB SDK budget is the tighter of the two, and any change that pulls a new dependency into either bundle has to fit inside those numbers or the build fails.
Overmind refuses to start twice, and force_run kills port 3000 outright
Local development is driven by Overmind reading a Procfile, and the Makefile has an opinionated guard around it. The run target checks for an existing socket file and refuses to start a second instance:
echo "Overmind is already running. Use 'make force_run' to start a new instance."; \The escape hatch is blunt. force_run echoes a cleaning message, then pipes whatever is listening on port 3036 and port 3000 into xargs kill with signal 9, suppressing errors, then deletes the Overmind socket and every file in tmp/pids, and starts again. There is a second variant, force_run_tunnel, which does the same cleanup but starts from Procfile.tunnel instead of Procfile.dev. Two debug targets attach to the named processes, overmind connect backend and overmind connect worker. The consequence of the blunt cleanup is worth knowing before you run it on a busy machine, because anything else you have listening on 3000 or 3036 will be terminated rather than asked.
Two version files at the root, because the CLI ships separately
Look at the root of the repository and two version markers sit side by side, VERSION_CW and VERSION_CWCTL. That pairing is a design statement: the application and the command line tool are versioned independently, because they are consumed on different schedules by different people. The JavaScript manifest, @chatwoot/chatwoot, tracks the application at 4.18.0, matching the most recent release tag, so the Ruby on Rails side and the front end are moving together. The rest of the front end tooling is conventional and modern rather than incidental: Vite for the SDK build, Vitest for tests pinned to UTC, ESLint over the app directory targeting both JavaScript and Vue files, RuboCop for the Ruby side, Husky for git hooks, and a French tool called Histoire for component stories, wired through a dedicated histoire.config.ts at the root.
The branching note still says tags are labelled v1.x.x
The project uses the git-flow branching model, and the base branch is develop, which is also the default branch on GitHub. The note goes on to say that if you are looking for a stable version you should use master or tags labelled as v1.x.x. That instruction is out of date, and it is the kind of drift that produces a bad afternoon. The current tags are in the 4.x range, with v4.18.0, v4.17.1, and v4.17.0 in the recent set, so someone following the documented advice literally would be looking for a tag convention that has not been used for several major versions. The fix is simple and worth stating plainly: treat develop as unstable, deploy from master or from a numbered 4.x tag, and do not take the v1.x.x wording literally.
Environment variables are load bearing, and two of them break security features
The deployment section is unusually blunt about this: follow the environment variable documentation to set the correct values for the app to work with all the features, because there might be breakages if you do not. The example file shows the two that matter most. SECRET_KEY_BASE verifies the integrity of signed cookies, is expected to be alphanumeric with no symbols, and is generated with `rake secret`. Three Active Record encryption keys are required for multi-factor authentication, generated with `rails db:encryption:init`, and the file insists you use different keys for development, staging, and production. That second one is the one people skip. Without those three variables the app still boots, and multi-factor authentication is simply unavailable, which is the kind of failure that does not announce itself until an audit.
Enterprise conversation monitors get their model key from the admin UI
One feature in the example environment file breaks the pattern that everything else follows. The enterprise conversation monitors are described as requiring the account feature to be enabled separately, and their model configuration, a limit, an allowlist of custom attribute keys to send as customer context, and a daily token limit, are all in the environment file. The API key is not. The instructions say to set CAPTAIN_OPENROUTER_API_KEY and the optional decision model endpoint in Super Admin, then Settings, then Captain, described as shared installation settings, with the endpoint being the API base URL. So the same feature is configured from two different places depending on whether it is a secret or a setting. If you are automating a deployment, that split is the thing that will break first.
Translations run through Crowdin, and there is a script that syncs them
Localisation is a maintained process rather than an accident, and it has three moving parts. The web and mobile translations are managed on translate.chatwoot.com using Crowdin, and the repository holds a crowdin.yml at the root that drives the sync. On the JavaScript side there is a dedicated script, sync_i18n, that runs a file named bin/sync_i18n_file_change, so adding a translatable string in the code is not enough on its own. The third part is the written guide, which the project links for anyone contributing a translation, and the site itself carries a multi-lingual support feature in the product list alongside realtime message translation through Google Translate. For an operator the practical point is that the interface language and the translation of inbound messages are two separate mechanisms, and only the first is a Crowdin pipeline you can influence.
Editorial conclusion
Chatwoot suits a support team that wants its conversation data on infrastructure it controls and its own domain rather than a vendor inbox, and that can afford to run Rails, Sidekiq, Postgres, Redis, and a Vite build as one system. It does not suit a solo operator who wants a hosted tool in an afternoon, because the environment variables are load bearing and the project says outright that omitting them causes breakages, and it does not suit a team that needs the enterprise conversation monitoring features without a second conversation about licensing. Before deploying, read the environment variable documentation end to end and generate your own secret key and Active Record encryption keys per environment, work from the master branch or a version tag rather than develop, and check the current size-limit budgets if you plan to extend the widget.
Frequently asked questions
What does Chatwoot do?
Chatwoot is an open-source, self-hosted customer support platform that pulls conversations from many channels into a single inbox. It supports live chat on your website, email, Facebook, Instagram, Twitter, WhatsApp, Telegram, Line, and SMS, and adds a help center portal, campaigns, and the Captain AI agent.
how to install chatwoot docker
The repository ships a docker-compose.yaml for development that runs the Rails app, Sidekiq, Vite, Postgres, Redis, and Mailhog together, alongside docker-compose.production.yaml for production. For hosted installs there are one-click deployment options for Heroku and for DigitalOcean as a Kubernetes app.
is chatwoot open source
Yes. The project states it is released under the MIT License, with Chatwoot Inc holding copyright from 2017 to 2026, and positions itself as an open-source alternative to Intercom, Zendesk, and Salesforce Service Cloud.
what is chatwoot used for
Managing customer conversations from one inbox rather than several, publishing a self-service help center, and distributing work among agents. That includes auto-assignment based on availability, labels, custom views and filters, business hours, canned responses, and agent capacity management.
how to setup chatwoot
The Makefile has a setup target that runs gem install bundler, bundle install, and pnpm install, followed by database targets named db_create, db_migrate, db_seed, and db_reset. Local development then starts through Overmind using the Procfile.dev process file, with a run target that refuses to start if an instance is already running.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/chatwoot-chatwoot)