Home  ›  Open source  ›  MailMigrator
Open source · Email migration

Move a mailbox without losing a thing.

MailMigrator copies a mailbox from one IMAP server to another, keeping every folder, date and read state exactly where it was, and never deleting from the source. The kind of job companies overpay for, done for the cost of a small server, or free on your own computer.

Apache-2.0 · Self hosted · PHP 8.5

The maths

One is a bill. The other is a coffee.

Pay a provider to migrate a mailbox for you and it runs into the hundreds. MailMigrator does the same job on a small server you switch off when it is done, and it is free if you run it on your own computer.

A provider doing it for you
$100 to $175
per mailbox, done for you
MailMigrator
$5
a small server you switch off when it is done
or free on your own computer

The same 10,000 mails. A provider bills you by the mailbox. With MailMigrator the only cost is a small server, or nothing at all on your own machine.

No per mailbox fee

One server. Every mailbox you own.

There is no seat count and no licence for each inbox. The same small server, or your own computer, moves one mailbox or five hundred. Migrate a single account or a whole company and the cost does not change.

How it actually works

A true copy, engineered to be safe to re run.

MailMigrator is not a forwarder and it never touches your source. It writes each message into the destination exactly as it was, keeps a ledger so it can always pick up where it stopped, and skips anything already there.

01

A true copy, not a forward.

Every message is written with IMAP APPEND, preserving its original internal date. A mail that arrived two years ago still reads as two years old on the other side, so nothing shows up as freshly received.

02

A ledger that lets it resume.

Every message is recorded in a ledger before and after it is copied. If the connection drops, or a shared hosting cron tick runs out of time, the next run reads the ledger and continues from the last recorded position. It never starts over.

03

No duplicates, ever.

Before copying, it checks the destination by Message-ID, falling back to a SHA-256 content hash when a server strips that header. Anything already there is skipped, which makes it completely safe to run a second time.

04

Read only source, append only destination.

The source mailbox is only ever read from and the destination is only ever appended to. Nothing is deleted on either side, at any point, so the original stays exactly as you left it.

Preserves everything

It arrives looking exactly like it left.

Folders and labels, read and unread state, flags and stars, attachments and the exact folder layout all come across intact. Special folders are mapped intelligently, and both sides of the mapping are configurable.

Folders and labels Read and unread state Flags and stars Every attachment Exact folder layout Smart folder mapping
200,000

Built for big mailboxes. Messages are streamed one at a time with batching and throttling, so a mailbox of two hundred thousand messages will not exhaust memory or trip a provider's rate limits.

How a migration runs

Test small, then let it run.

The workflow is deliberately cautious. You prove it works on a handful of messages before you ever commit the whole mailbox, following four steps in order.

bash · migrate
1
# Test the connection: prove both accounts log in over IMAP.
$php migrate.php --test-connection
2
# Dry run: see exactly what would copy, without writing a single message.
$php migrate.php --dry-run
3
# Pilot a few: copy a small batch from one folder and confirm it lands right.
$php migrate.php --folder="INBOX" --limit=5
4
# Full run: work through the whole mailbox, resuming safely if interrupted.
$php migrate.php

Each step is a real command. Nothing is written to the destination until you ask it to.

Works with any IMAP host

If it speaks IMAP, it moves.

There is no special integration to wait for. If an email client can log in to the account, MailMigrator can move the mailbox.

Gmail & Workspace
Turn IMAP on and use a 16 character app password. Labels are handled as folders.
Microsoft 365
Standard IMAP, with an app password for modern authentication.
Zoho Mail
Works with an application specific password.
Yahoo Mail
Requires a generated app password.
cPanel & Dovecot
The common case for shared hosting and small business email.
Hostinger
Any cPanel style mailbox is supported.
Namecheap
Any cPanel style mailbox is supported.
Any IMAP host
If an email client can log in, so can MailMigrator.
Two ways to run it

One engine, your choice of front.

The migration engine has no idea whether a person or a script is driving it. The same framework agnostic code powers a scriptable command line tool and a full multi user dashboard.

Command line

scriptable, cron friendly

A scriptable CLI with clear flags for testing, dry runs, folder scoping and limits. Perfect for a one off move or a job you leave to a cron worker.

Ideal for one or two accounts Config lives in a single file Driven by one cron worker

Web dashboard

multi user, live status

A multi user web app for running and watching migrations. A live job dashboard shows per message copy status and progress bars as work goes through.

Multi user accounts with isolated jobs Background worker claims one job per tick Optional paywall, off by default

The same framework agnostic engine runs under both.

Under the hood

Boring, current, and easy to host.

Plain PHP on well chosen libraries, with no framework to learn and nothing exotic to provision. It runs on ordinary shared hosting with one cron job, no VPS or Docker required.

Language
PHP 8.5No framework
Data
PDOMySQLSQLite
Mail & crypto
webklex/php-imapdefuse/php-encryption
Routing & env
nikic/fast-routevlucas/phpdotenv
Interface
TailwindAlpine.js
Tests
PHPUnit
Runs on ordinary shared hosting with one cron job. No VPS, no Docker, nothing to provision beyond a mailbox and a database.
Safe with real passwords

Cautious by default, because it has to be.

You may be holding other people's live email passwords, so MailMigrator is built to protect them. Credentials are encrypted, the source is never touched, and nothing is ever deleted on either side.

Encrypted at rest

Stored credentials are encrypted with defuse/php-encryption. The key lives only in your environment file, never in the database.

Modern hashing and CSRF

Argon2id password hashing with a bcrypt fallback, CSRF protection on every form, and per user job isolation so people only ever see their own work.

Verified billing webhooks

Billing webhooks are signature verified before anything is trusted, and you serve over HTTPS with the environment file kept out of the web root.

Read only, append only

The source is only ever read from and the destination only ever appended to. Nothing is deleted anywhere, on either side.

Run it as a business

Turn it into a migration service and earn.

Leave the built in paywall off and everything stays free and unlimited. Switch it on and MailMigrator becomes something you sell: give each customer a free quota, then charge past it, in whichever way suits you. You host it, you set the prices, you keep the revenue.

One time

Charge a single payment for permanent access. Simple to explain and simple to buy, ideal for a one off move.

Per mailbox

Sell credit packs measured in mailboxes or emails, so a customer pays for exactly the volume they move, no more.

Recurring

Charge a monthly subscription for ongoing access, the model that fits agencies migrating for clients month after month.

PayPal Razorpay Both gateways are built in, so between them you can take payment from customers almost anywhere, in their own currency.

Rather have it handled for you?

MailMigrator is free to run yourself. If you would prefer we move the mail without the fuss, that starts with a short call.