- Python 56.7%
- Vue 29.2%
- TypeScript 7.1%
- JavaScript 5.6%
- HTML 0.9%
- Other 0.5%
Upload import files in sequential chunks so large archives aren't capped by the web server's request-body limit. Adds a useChunkedUpload composable (matching the framework's chunked upload_file handler) and switches the import UI off frappe-ui's FileUploader to use it. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .github | ||
| docker | ||
| docs/screenshots | ||
| frappe-ui@21e081816b | ||
| frontend | ||
| scripts | ||
| UPGRADING | ||
| .editorconfig | ||
| .git-blame-ignore-revs | ||
| .gitignore | ||
| .gitmodules | ||
| .mergify.yml | ||
| .pre-commit-config.yaml | ||
| .prettierrc.json | ||
| .releaserc | ||
| CLAUDE.md | ||
| CODEOWNERS | ||
| commitlint.config.js | ||
| eslint.config.mjs | ||
| license.txt | ||
| package.json | ||
| pyproject.toml | ||
| README.md | ||
| yarn.lock | ||
Frappe Mail
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.
Contents
- Why Frappe Mail
- System Requirements
- Quick Start
- Development
- Stalwart Setup from UI
- API Quick Reference
- Frontend Overview
- Sign-up Flows
- Contributing
- License
Why Frappe Mail
- 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.
System Requirements
- Python: 3.14
- Frappe Framework: 16+
- Node toolchain: Bun (frontend scripts use Bun)
- Optional for local container setup: Docker + Docker Compose
Quick Start
Option A: Docker
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 -d
Default credentials:
- Username: administrator
- Password: admin
Option B: Manual Bench Setup
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 Administrator
Development
Frontend Commands
Run 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-css
Backend and Tests
Run 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 build
Linting and Formatting
pre-commit run --all-files
ruff check mail/
cd frontend && bun run lint
Stalwart Setup from UI
Use 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:
Credentials Configuration
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.
API Quick Reference
Authentication
- Validate mailbox ownership/permission
- POST /auth/validate
- Frappe method: /api/method/mail.api.auth.validate
Outbound
- 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
Inbound
- 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
Frontend Overview
Frappe Mail frontend is split into two primary surfaces.
Mailbox
- 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:
Admin Dashboard
- Domain management
- Member and access management
- Invite workflows
- Mailing list management
Screenshots:
Sign-up Flows
Two supported onboarding flows:
- Open sign-up (domain whitelist based, enabled in Mail Settings)
- Invite-based sign-up
Invite flow screenshots:
Contributing
Enable pre-commit hooks:
pre-commit install
Pre-commit runs:
- ruff
- eslint
- prettier
- pyupgrade
License
GNU Affero General Public License v3.0


















