Frappe Mail is an end-to-end mail platform with two core responsibilities:
- A generic JMAP client for mailbox operations (read, send, manage identities, contacts, settings).
- A control plane for deploying and managing one or more Stalwart Mail clusters.
It is built as a Frappe app with a Vue 3 + TypeScript frontend.
- Why Frappe Mail
- System Requirements
- Quick Start
- Development
- Stalwart Setup from UI
- API Quick Reference
- Frontend Overview
- Sign-up Flows
- Contributing
- License
- JMAP-first architecture for modern mail workflows.
- Unified UI and APIs for mailbox users and platform admins.
- Multi-cluster Stalwart operations from one control plane.
- Built-in support for provisioning, DNS records, sync, and lifecycle management.
Good fit for:
- Teams self-hosting email infrastructure.
- Integrators building on a JMAP-compatible mailbox backend.
- Operators managing multiple Stalwart clusters with centralized workflows.
- Python: 3.14
- Frappe Framework: 16+
- Node toolchain: Bun (frontend scripts use Bun)
- Optional for local container setup: Docker + Docker Compose
wget -O docker-compose.yml https://raw.githubusercontent.com/frappe/mail/develop/docker/docker-compose.yml
wget -O init.sh https://raw.githubusercontent.com/frappe/mail/develop/docker/init.sh
docker compose up -dDefault credentials:
- Username: administrator
- Password: admin
Prerequisite: Bench installed and working. See the Frappe installation guide: https://docs.frappe.io/framework/user/en/installation
From your bench root (not from apps/mail):
bench get-app mail
bench new-site mail.localhost --install-app mail
bench browse mail.localhost --user AdministratorRun from repository root unless noted otherwise.
# install frontend dependencies (runs after npm install via postinstall)
npm install
# start Vite dev server
npm run dev
# build frontend + email css
npm run build
# build frontend only
npm run build-app
# build email css only
npm run build-email-cssRun from bench root:
bench --site <site> install-app mail
bench --site <site> run-tests --app mail
bench --site <site> run-tests --app mail --module mail.tests.test_foo
bench buildpre-commit run --all-files
ruff check mail/
cd frontend && bun run lintUse the Admin Dashboard to configure and deploy Stalwart.
- Configure Mail Settings
- Create a Mail Cluster
- Create a Mail Server
- Verify SSH connection
- Run install actions (Ansible, Docker, Stalwart)
- Regenerate and redeploy after config changes
- Add domains and publish DNS records
Reference screenshots:
Set Stalwart credentials in Mail Settings (recommended) or in site_config.json:
{
"mail": {
"server_url": "https://mail.example.com",
"username": "admin",
"password": "your-password"
}
}stalwart-cli is auto-downloaded after migrate. You can pin the CLI version via mail.stalwart_cli_version in site_config.json.
- Validate mailbox ownership/permission
- POST /auth/validate
- Frappe method: /api/method/mail.api.auth.validate
- Send structured message
- POST /outbound/send
- Frappe method: /api/method/mail.api.outbound.send
- Send raw MIME message
- POST /outbound/send-raw
- Frappe method: /api/method/mail.api.outbound.send_raw
- Pull parsed messages
- GET /inbound/pull
- Frappe method: /api/method/mail.api.inbound.pull
- Pull raw MIME messages
- GET /inbound/pull-raw
- Frappe method: /api/method/mail.api.inbound.pull_raw
For request payload details, inspect implementation in:
- mail/api/auth.py
- mail/api/outbound.py
- mail/api/inbound.py
Frappe Mail frontend is split into two primary surfaces.
- Folder and thread navigation
- Compose, reply, forward
- Search and filtering
- Keyboard shortcuts
- Address books and contacts
- Account/identity/vacation settings
- Mail exchange (import/export)
- PWA support
Screenshots:
- Domain management
- Member and access management
- Invite workflows
- Mailing list management
Screenshots:
Two supported onboarding flows:
- Open sign-up (domain whitelist based, enabled in Mail Settings)
- Invite-based sign-up
Invite flow screenshots:
Enable pre-commit hooks:
pre-commit installPre-commit runs:
- ruff
- eslint
- prettier
- pyupgrade
GNU Affero General Public License v3.0


















