imapforward
Simple real-time IMAP email forwarder for syncing multiple email accounts into one.
Built to replace deprecated gmailify tool for Gmail.
Features
- Real-time sync — Uses IMAP IDLE for instant email forwarding
- Multiple sources — Forward from multiple email accounts to a single Gmail
- Original headers preserved — Emails arrive with their original From, Reply-To, and other headers intact
- Selective folders — Choose which folders to sync (e.g. only INBOX)
- Auto cleanup — Optionally delete messages after successful forwarding
- Production-grade — Auto reconnect with exponential backoff, health check endpoint
- Minimal footprint — Only 1 runtime dependency (
imapflow) - Docker ready — Alpine-based image with built-in health checks
Installation
npm
npm install -g imapforwardDocker
docker pull ghcr.io/sinedied/imapforward:latestConfiguration
Create a config.json file. You can use the online configuration generator to build it interactively.
{
"target": {
"host": "imap.gmail.com",
"port": 993,
"secure": true,
"auth": {
"user": "your-email@gmail.com",
"pass": "your-app-password"
}
},
"sources": [
{
"name": "Work Email",
"host": "imap.work.com",
"port": 993,
"secure": true,
"auth": {
"user": "user@work.com",
"pass": "password"
},
"folders": ["INBOX"],
"deleteAfterForward": false
}
],
}Configuration Reference
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
target.host |
string | yes | — | Target IMAP server hostname |
target.port |
number | yes | — | Target IMAP server port |
target.secure |
boolean | no | port-based | Use TLS (defaults to true for ports 465/993) |
target.auth.user |
string | yes | — | Target IMAP username |
target.auth.pass |
string | yes | — | Target IMAP password or app password |
target.folder |
string | no | "INBOX" |
Target mailbox folder to append messages to |
sources[].name |
string | yes | — | Display name for the source |
sources[].host |
string | yes | — | IMAP server hostname |
sources[].port |
number | yes | — | IMAP server port |
sources[].secure |
boolean | yes | — | Use TLS |
sources[].auth.user |
string | yes | — | IMAP username |
sources[].auth.pass |
string | yes | — | IMAP password |
sources[].folders |
string[] | no | ["INBOX"] |
Folders to monitor |
sources[].deleteAfterForward |
boolean | no | false |
Delete messages after forwarding |
healthCheck.port |
number | no | 8080 |
HTTP health check server port |
Tip
For Gmail, you need to have 2FA enabled and use an App Password instead of your regular password.
Usage
CLI
# Run with default config.json in current directory
imapforward
# Set log level
imapforward --log-level debug
# Custom config path
imapforward --config /path/to/config.jsonCLI Options
| Option | Short | Description |
|---|---|---|
--config <path> |
-c |
Config file path (default: config.json) |
--log-level <level> |
-l |
Log level: debug, info, warn, error (default: info) |
--version |
-v |
Show version |
--help |
-h |
Show help |
Environment Variables
| Variable | Description |
|---|---|
IMAPFORWARD_CONFIG |
Override config file path |
LOG_LEVEL |
Override log level |
Docker
Run with Docker
docker run -d \
--name imapforward \
-v $(pwd)/config.json:/app/config.json:ro \
ghcr.io/sinedied/imapforward:latestDocker Compose
services:
imapforward:
image: ghcr.io/sinedied/imapforward:latest
restart: unless-stopped
volumes:
- ./config.json:/app/config.json:roHealth Check
The health check server is always enabled (default port 8080). You can customize the port in your config:
{
"healthCheck": {
"port": 9090
}
}The HTTP health endpoint is available at:
curl http://localhost:8080/healthResponse:
{
"status": "ok",
"sources": [
{
"name": "Work Email",
"connected": true,
"lastSync": "2026-02-25T10:30:00.000Z",
"error": null
}
]
}Status values: ok (all connected), degraded (some connected), error (none connected).
How It Works
- Connects to each configured IMAP source account
- Scans for unseen messages that haven't been forwarded yet
- Appends each message to the target mailbox via IMAP preserving all original headers (raw RFC822)
- Marks forwarded messages with a
$ForwardedIMAP flag - Enters IMAP IDLE mode to watch for new messages in real-time
- Automatically reconnects with exponential backoff on connection loss
On this page
Languages
TypeScript91.3%CSS3.4%JavaScript3.3%HTML1.1%Dockerfile0.9%
Latest Release
1.0.0February 26, 2026MIT License
Created February 25, 2026
Updated March 19, 2026