A self-hosted alternative to Mailchimp.
Campaigns, newsletters, visual automations, signup forms, a contact CRM and a shared inbox, sending through your own Amazon SES or SMTP.
Try Xem Cloud free · Self-host · Compare · Docs · Issues
![]() Inbox |
![]() Automations |
![]() Templates |
![]() Outbox |
![]() Overview |
![]() Ask Xem |
- Campaigns and newsletters: send once or on a schedule, with a public archive and RSS for each newsletter.
- Automations: a visual builder with emails, waits, splits, percentage tests, tags, list moves, contact updates and webhooks.
- Templates: 238 editable starting points built from native editor blocks, plus AI drafting if you turn it on.
- Audience: lists, tags, segments, signup forms and a small CRM with lead stages.
- Inbox: read and reply to mail from IMAP, Gmail or Cloudflare mailboxes alongside your campaigns.
- Analytics: delivery, opens, clicks and audience growth, with honest notes on what open rates can and can't tell you.
- Ask Xem and MCP: an in-app assistant that shows each change for approval, and an MCP server with 44 tools for Claude and other agents.
- Sending: Amazon SES or any SMTP server. One-click unsubscribe headers (RFC 8058), bounce and complaint processing into a suppression list, and guided DKIM setup. Xem doesn't own sending IPs; your reputation stays with your provider.
- Moving in: reads Mailchimp, Substack, beehiiv, Kit and Ghost exports directly and keeps unsubscribed people unsubscribed. Any CSV with an email column works too.
- Stack: Go API and workers, Next.js app, PostgreSQL, Redis and S3-compatible storage (RustFS by default).
- APIs: REST API, webhooks, and SDKs for TypeScript and Go.
- Hosting: Docker Swarm on any Linux server, or Xem Cloud.
Running Xem yourself is free; you pay your server and your email provider.
- Sending through Amazon SES costs about $0.10 per 1,000 emails. A weekly newsletter to 10,000 people is roughly $4 a month in sending. New SES accounts start in a sandbox, so ask AWS for production access first.
- Any other SMTP provider works at whatever it charges.
- Xem Cloud is priced per email sent, not per contact: 3,000 a month free, then from $9 for 20,000. Every plan has every feature. See pricing and how that compares.
Prices change, so check Amazon SES pricing before you plan around it.
On a Linux host with Docker Engine, Git, Python 3 and OpenSSL, run:
curl -fsSL https://raw.githubusercontent.com/mailxem/mail/undefined/scripts/install.sh | bashThe wizard asks for the app, API and storage addresses. It builds the app and backend from the same repository revision, generates credentials, initializes Swarm when needed, and starts Next.js + Go + PostgreSQL + Redis + RustFS. No cloud storage account is required.
Basic runtime target: 2 CPU cores, 2 GB RAM and 20 GB free disk for a small installation. Source builds can need more memory or swap while building the Next.js app. See the requirements before installing.
Use a host IP or DNS name reachable from both browsers and containers. The default ports are 3000 (app), 9001 (API) and 9000 (object storage). HTTP is intended for a trusted local network; configure HTTPS before exposing the installation publicly.
Open the printed /auth/register URL, create your account, and connect your own SMTP provider. Managed SES sending, hosted billing, Google OAuth and the AI assistant need extra configuration and aren't provisioned by this starter.
Prefer to read the script first?
curl -fsSLo install-xem.sh https://raw.githubusercontent.com/mailxem/mail/undefined/scripts/install.sh
less install-xem.sh
bash install-xem.shSee the Swarm guide for unattended setup, HTTPS, updates, backups, troubleshooting and removal. This is a single-node starter, not a high-availability deployment.
Paste this into an AI agent that has terminal access to your server (Claude Code, Codex, Cursor and similar):
Install Xem for me on this Linux server from https://github.com/mailxem/mail.
1. Read README.md and devops/swarm/README.md first.
2. Check that Docker Engine, Git, Python 3 and OpenSSL are installed, and that the
server has at least 2 CPU cores, 2 GB RAM and 20 GB free disk. Tell me what's
missing instead of installing system packages without asking.
3. Ask me for the address people will use to reach the app (an IP or DNS name).
4. Download scripts/install.sh to install-xem.sh and show me a short summary of
what it does before running it.
5. Copy devops/swarm/config.example.json to config.json, replace its example IP
with my address (keep ports 3000, 9001 and 9000 unless I say otherwise), then run:
bash install-xem.sh --config ./config.json --state "$HOME/.local/share/xem"
6. Never print, commit or paste the generated credentials. They stay in the state
directory; never delete that directory.
7. When it finishes, give me the /auth/register URL and remind me to connect an
SMTP provider and set up SPF, DKIM and DMARC before sending.
These open setup guides; they don't provision a server for you. Check email ports before choosing a host: DigitalOcean blocks outbound SMTP ports 25, 465 and 587 by default, and Hetzner allows 587 but blocks 25 and 465. See the provider comparison.
The Xem hosted service runs on Hakopod. To deploy Xem on your own Hakopod installation, use the Hakopod configuration and deployment guide.
An opt-in custom-domain Xem inbox for operators using managed Amazon SES sending is under development; see the managed receiving operations guide. Repository support and local validation don't mean the hosted service or an AWS deployment is available.
flowchart LR
Browser[Browser] --> App[Next.js app]
Browser --> API[Go API and workers]
App --> API
API --> Postgres[(PostgreSQL)]
API --> Redis[(Redis / task queue)]
API --> Storage[(RustFS / S3)]
Browser --> Storage
API --> SMTP[Your SMTP provider]
git clone https://github.com/mailxem/mail.git
cd mail
make help
# Run the same Swarm installer from the checkout:
python3 devops/swarm/install.pyFor frontend development, point the app at a running backend and follow client setup. Backend configuration and API documentation live in server/ and docs/. Components keep their own dependency files; component CI and releases live together in .github/workflows/. A single PR can change both sides of an API.
| Component | Source |
|---|---|
| Go API and workers | server/ |
| Next.js application | client/ |
| Deployment infrastructure | devops/ |
| MCP integration | mcp/ |
| Payments | payments.go/ |
| TypeScript SDK | sdk/ |
| Go SDK | sdk-go/ |
| Marketing website | website/ |
This is a monorepo: all eight components above are normal directories. No submodule initialization or second repository checkout is required. The starter deploys the app, backend, and their data services.
- Frontend changes run TypeScript, Jest, and Next.js build checks.
- Backend changes run Go vet, race tests, builds, and the relevant PostgreSQL/SMTP integration checks.
- Changes to either side run the full Docker Swarm smoke test.
- Default-branch changes publish the affected component's amd64/arm64 images independently, then assemble the combined image and create a component-scoped release.
- Published backend, frontend, MCP, and payments images can be deployed automatically to Hakopod using the release deployment workflow.
- Website, infrastructure, MCP, payments, and Go SDK workflows also run from the root, with checks scoped to their component paths.
- Images keep
theboringhumane/xemappandtheboringhumane/xemgo; Git tags usefrontend-v*andbackend-v*to avoid collisions.
See the migration and CI guide for source provenance, configuration, and the cutover from the original repositories.
Working on inboxes or provider integrations? See the connected-mail setup and implementation notes for Gmail, Workspace, IMAP, and Cloudflare, including current limitations and release checks. The customer-owned inbound Worker has a separate Cloudflare mailbox setup guide. The commercial roadmap describes planned hosted and self-hosted offers; existing free features remain available.
Report bugs with reproduction steps, open a focused PR, or improve the docs. Keep credentials and local .env files out of commits. Make component changes directly in this repository and include related frontend/backend updates in the same PR.
Xem was previously called Posthoot. Its code is GPL-3.0 licensed. Bundled third-party services retain their own licenses, including RustFS's Apache-2.0 license.






