Forward Email specific themes and plugins for SnappyMail webmail. This repository bridges the gap between the upstream SnappyMail clone (forwardemail/mail) and Forward Email's custom branding needs.
┌─────────────────────────────────────────────────────────┐
│ forwardemail.net (main monorepo) │
│ https://github.com/forwardemail/forwardemail.net │
│ - All Forward Email processes │
│ - Ansible deployment configurations │
│ - Shared security & cert management │
│ │
│ └─> mail-overrides/ (git submodule) │
│ https://github.com/forwardemail/mail-overrides │
│ - Forward Email specific themes & plugins │
│ │
│ └─> mail/ (git submodule) │
│ https://github.com/forwardemail/mail │
│ - SnappyMail clone (stays in sync with upstream) │
│ │
│ └─> upstream: the-djmaze/snappymail │
└─────────────────────────────────────────────────────────┘
This repository contains only Forward Email customizations:
plugins/forwardemail/- Custom login page with Forward Email brandingthemes/ForwardEmail/- Custom CSS styling and designconfigs/- Pre-configured application settingsscripts/- Build automation to sync overrides into mail/
The forwardemail/mail repo stays clean and in sync with upstream SnappyMail, while this repo adds Forward Email branding on top.
git clone https://github.com/forwardemail/mail-overrides.git
cd mail-overrides
# Initialize the mail submodule (forwardemail/mail)
git submodule update --init --recursiveBefore you can use the overrides, SnappyMail needs to be built once:
cd mail
npm ci # Use npm ci for locked dependencies (recommended)
npx gulp
cd ..This compiles the CSS/JS assets. You only need to do this once (or when updating the mail submodule).
Note: We use npm ci instead of npm install to ensure reproducible builds using the locked dependencies in package-lock.json.
# Make scripts executable
chmod +x scripts/*.sh
# Build: Copy mail/ → dist/ and apply overrides
./scripts/build.shThis creates dist/ with SnappyMail + Forward Email customizations.
Option A: Docker (Recommended)
docker-compose -f docker/docker-compose.yml upVisit http://localhost:8080 to see Forward Email branding with Redis support.
Option B: PHP Built-in Server
cd dist
php -S localhost:8000Visit http://localhost:8000 (Note: Redis won't be available with this method).
mail-overrides/
├── mail/ # Submodule → forwardemail/mail (clean, for building)
│ # (tracks upstream SnappyMail)
├── dist/ # Build output (gitignored)
│ # Contains final SnappyMail with overrides applied
├── plugins/
│ ├── forwardemail/ # Forward Email branding plugin
│ ├── client-ip-passthrough/ # Client IP forwarding plugin
│ └── redis-ephemeral-sessions/ # Redis session storage plugin
├── themes/
│ └── ForwardEmail/ # Forward Email theme
├── configs/
│ ├── application.ini # Pre-configured with plugin enabled
│ └── include.php # Custom PHP configuration
├── scripts/
│ ├── build.sh # Build: mail/ → dist/ + apply overrides
│ ├── clean.sh # Remove dist/ directory
│ └── update-snappymail.sh # Update mail submodule
└── docker/ # Local development only
mail/ or dist/ - these are build artifacts
- Edit files in
plugins/orthemes/directories (at root level) - Run
./scripts/build.shto rebuilddist/with your changes - Test locally with Docker
- Commit and push
# Example: Update Redis plugin
vim plugins/redis-ephemeral-sessions/index.php
# Rebuild dist/ with your changes
./scripts/build.sh
# Test with Docker
docker-compose -f docker/docker-compose.yml restart
# Commit your changes (dist/ is gitignored)
git add plugins/redis-ephemeral-sessions/
git commit -m "Update Redis session plugin"
git pushThe mail/ submodule (forwardemail/mail) tracks upstream SnappyMail. To update:
# Update the mail submodule to latest
cd mail
git pull origin master
cd ..
# Commit the submodule update
git add mail
git commit -m "Update mail submodule to latest SnappyMail"
# Rebuild and test
./scripts/build.sh
cd dist && php -S localhost:8000
# Push
git pushProduction deployment is managed by Ansible from the main forwardemail.net monorepo.
# In forwardemail.net monorepo
cd /path/to/forwardemail.net
# Add mail-overrides as submodule (if not already added)
git submodule add https://github.com/forwardemail/mail-overrides.git mail-overrides
# Initialize all submodules (including nested mail/ submodule)
git submodule update --init --recursive1. Make changes in mail-overrides
→ git push to forwardemail/mail-overrides
2. Update in forwardemail.net monorepo
→ cd forwardemail.net/mail-overrides && git pull
→ git add mail-overrides && git commit
3. Deploy with Ansible (from forwardemail.net)
→ ansible-playbook playbooks/deploy-snappymail.yml
→ Ansible runs build.sh and deploys dist/
The Ansible playbook in forwardemail.net will:
- Run
mail-overrides/scripts/build.shto produce thedist/build output with customizations applied - Deploy
mail-overrides/dist/to production servers - Configure web server, permissions, SSL (using shared configs)
Docker is provided for local testing. Production uses Ansible from the main monorepo.
# Start
docker-compose -f docker/docker-compose.yml up
# Stop
docker-compose -f docker/docker-compose.yml downGenerates the deployable dist/ artefacts while leaving the mail/ submodule pristine:
- Copies the clean SnappyMail tree from
mail/intodist/ - Overlays
plugins/forwardemail/andthemes/ForwardEmail/intodist/snappymail/v/0.0.0/ - Copies configuration files into
dist/data/_data_/_default_/
Run this after any changes to plugins or themes.
Local development helper. Production deployment uses Ansible from forwardemail.net.
Helper to update the mail/ submodule to a specific SnappyMail version.
- Located in
plugins/forwardemail/ - Overrides login template with Forward Email branding
- Auto-enabled via
configs/application.ini
- Located in
themes/ForwardEmail/ - Custom CSS matching Forward Email brand
- Login page styles, responsive design
git submodule update --init --recursive./scripts/build.sh
ls -la mail/snappymail/v/0.0.0/plugins/forwardemail/cd mail && git pull && cd ..
git add mail && git commit -m "Update mail submodule"- Fork this repository
- Create feature branch:
git checkout -b feature/my-feature - Make changes to
plugins/orthemes/(NOT inmail/) - Run
./scripts/build.shand test - Commit and create Pull Request
- Forward Email customizations (plugins/themes): BUSL-1.1
- SnappyMail (via mail submodule): AGPL-3.0
- forwardemail/mail - SnappyMail clone
- forwardemail/forwardemail.net - Main monorepo
- the-djmaze/snappymail - Upstream
- Issues: https://github.com/forwardemail/mail-overrides/issues
- Forward Email: https://forwardemail.net/en/faq