imapforward
v1.0.0
Published
Simple IMAP email forwarder for syncing multiple email accounts into one
Maintainers
Readme
📬 imapforward
Simple real-time IMAP email forwarder for syncing multiple email accounts into one. Built to replace deprecated gmailify tool for Gmail.
Features · Installation · Configuration · Docker
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:
{
"target": {
"host": "imap.gmail.com",
"port": 993,
"secure": true,
"auth": {
"user": "[email protected]",
"pass": "your-app-password"
}
},
"sources": [
{
"name": "Work Email",
"host": "imap.work.com",
"port": 993,
"secure": true,
"auth": {
"user": "[email protected]",
"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
# Using default config.json in current directory
imapforward
# Custom config path
imapforward --config /path/to/config.json
# Set log level
imapforward --log-level debugCLI 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
