Website · Self-host · Documentation · Issues
Xem (formerly Posthoot) is an open-source email platform for teams that want control over their delivery infrastructure. Bring your SMTP provider, create campaigns and templates, manage audiences, and build multi-step automations through a web app or API.
The Xem hosted service runs on Hakopod. Operators who want to deploy Xem on their own Hakopod installation can use the repository's Hakopod configuration and deployment guide.
Choose a provider, create a Linux VPS, and follow its setup guide to run the installer below. Hosting is billed by your provider. These buttons open guided setup instructions; they do not provision a server automatically.
Check email connectivity before choosing a host. DigitalOcean blocks outbound SMTP ports 25, 465 and 587 by default, so its Droplets cannot send through this starter's standard SMTP setup. Hetzner allows port 587 but blocks 25 and 465 by default. See the provider comparison and sending requirements before paying for a server.
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 additional memory or swap, especially while building the Next.js app. Allow room for build caches and growing data; scale with your workload. 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 require additional configuration and are not provisioned by this starter.
Prefer to inspect 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.
| Capability | Use it for |
|---|---|
| Campaigns and templates | Compose email, reuse designs, and send through your chosen provider. |
| Audiences | Organize contacts with lists, tags, segments, and custom data. |
| Automations | Combine email, conditions, waits, splits, webhooks, and subscriber updates. |
| Delivery APIs | Integrate email into your product using REST, Go, or TypeScript. |
| Reporting | Inspect campaign activity and delivery outcomes. |
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's code is GPL-3.0 licensed. Bundled third-party services retain their own licenses, including RustFS's Apache-2.0 license.
