Tired of complicated or paid tools for moving your emails? This is a straightforward, open-source script that "just works." It was built out of a desire for a free, reliable way to migrate emails from one IMAP provider to another.
It downloads all emails from a source inbox and securely uploads them to your destination inbox, preserving original metadata like dates and flags.
- Universal IMAP Support: Migrate between any email providers with IMAP access (e.g., Gmail, Outlook, Fastmail, Yahoo, custom servers).
- Simple & Fast: A single command-line script with no complex setup. Uses
uv
for quick installation. - Preserves Metadata: Keeps original email received dates, and flags (e.g.,
\Seen
,\Flagged
). - Real-time Progress: A
tqdm
progress bar shows you migration speed, success/error counts, and estimated time remaining. - Robust Logging: All actions are logged to
migration.log
for easy troubleshooting. - Safe to Re-run: The script doesn't create duplicate emails, so you can safely restart it if the migration is interrupted.
- Dry Run Mode: Test your connection and settings with
--dry-run
before migrating a single email. - Flexible Configuration: Use command-line arguments or environment variables for your credentials.
- Python 3.12 or higher
uv
package manager (recommended for fast dependency management)- IMAP access enabled on both your source and destination email accounts.
-
Install
uv
(if you don't have it):# macOS / Linux curl -LsSf https://astral.sh/uv/install.sh | sh # Windows powershell -c "irm https://astral.sh/uv/install.ps1 | iex" # Or via pip pip install uv
-
Clone this repository:
git clone https://github.com/sebastianlund/imap-migrate.git cd imap-migrate
-
Install dependencies:
uv sync
You can provide your account credentials either directly as command-line arguments or by setting environment variables for better security.
The most basic command requires the host, email, and password for both the source and destination accounts.
uv run imap-migrate \
--source-host imap.your-provider.com \
--source-email [email protected] \
--source-password "your-source-password" \
--dest-host imap.new-provider.com \
--dest-email [email protected] \
--dest-password "your-dest-password"
This is a common use case that requires a special "App Password" for Gmail.
You cannot use your regular Gmail password. You must create a 16-digit App Password.
- Go to your Google Account: myaccount.google.com
- Navigate to Security -> 2-Step Verification.
- Scroll down and click on App passwords.
- Select "Mail" for the app and "Other (Custom name)" for the device.
- Name it something like "IMAP Migration Script" and click Generate.
- Copy the 16-character password. This is what you'll use for
--dest-password
.
- In Gmail, go to Settings β See all settings.
- Click the Forwarding and POP/IMAP tab.
- Under "IMAP access," select Enable IMAP and save changes.
Now, run the script with the correct hosts and your new App Password.
# Using command-line arguments
uv run imap-migrate \
--source-host imap.fastmail.com \
--source-email [email protected] \
--source-password "your-fastmail-password" \
--dest-host imap.gmail.com \
--dest-email [email protected] \
--dest-password "your-16-digit-gmail-app-password" \
--yes
# Or using environment variables
export SOURCE_HOST="imap.fastmail.com"
export SOURCE_EMAIL="[email protected]"
export SOURCE_PASSWORD="your-fastmail-password"
export DEST_HOST="imap.gmail.com"
export DEST_EMAIL="[email protected]"
export DEST_PASSWORD="your-16-digit-gmail-app-password"
uv run imap-migrate --yes
Argument | Environment Variable | Description | Default |
---|---|---|---|
--source-host |
SOURCE_HOST |
Source IMAP server hostname. (Required) | None |
--source-email |
SOURCE_EMAIL |
Source email address. (Required) | None |
--source-password |
SOURCE_PASSWORD |
Source email password. (Required) | None |
--dest-host |
DEST_HOST |
Destination IMAP server hostname. (Required) | None |
--dest-email |
DEST_EMAIL |
Destination email address. (Required) | None |
--dest-password |
DEST_PASSWORD |
Destination email password. (Required) | None |
--source-folder |
SOURCE_FOLDER |
Source folder to migrate from. | INBOX |
--dest-folder |
DEST_FOLDER |
Destination folder to migrate to. | INBOX |
--delay |
None |
Delay in seconds between migrating each email. | 0.1 |
--dry-run |
None |
Perform a test run without migrating. | False |
-v , --verbose |
None |
Enable verbose logging to the console. | False |
-y , --yes |
None |
Skip the confirmation prompt before starting. | False |
-h , --help |
None |
Show the help message and exit. |
Provider | IMAP Hostname |
---|---|
Gmail | imap.gmail.com |
Fastmail | imap.fastmail.com |
Outlook | outlook.office365.com |
Yahoo Mail | imap.mail.yahoo.com |
iCloud Mail | imap.mail.me.com |
$ uv run imap-migrate --source-host ... --dest-host ...
π Email Migration Tool: IMAP to IMAP
==================================================
π§ Source: [email protected] (folder: INBOX)
π§ Destination: [email protected] (folder: INBOX)
π Connecting to source (imap.fastmail.com)...
2025-07-04 08:13:04,019 - INFO - Connecting to server: imap.fastmail.com:993
2025-07-04 08:13:04,687 - INFO - Successfully connected to imap.fastmail.com
β
Connected to source server successfully!
π Connecting to destination (imap.gmail.com)...
2025-07-04 08:13:04,687 - INFO - Connecting to server: imap.gmail.com:993
2025-07-04 08:13:05,701 - INFO - Successfully connected to imap.gmail.com
β
Connected to destination server successfully!
π Analyzing mailbox...
β
Found 13130 emails in INBOX
π§ Ready to migrate 13130 emails
From: [email protected]@imap.fastmail.com/INBOX
To: [email protected]@imap.gmail.com/INBOX
β±οΈ This may take several hours for large inboxes
π Proceed with migration? (y/N): y
π Migrating 13130 emails...
π‘ Tip: You can press Ctrl+C to cancel at any time
2025-07-04 08:13:07,176 - INFO - Found 13130 emails to migrate (processing newest first)
Migrating emails: 100%|βββββββββββββββββββββββββββββββββββββββββββββββββββ| 13130/13130 [5:25:08<00:00, 1.49s/email, Success=13124, Errors=6]
2025-07-04 13:38:15,680 - INFO - Migration complete: 13124 successful, 6 errors
==================================================
β οΈ Migration completed with some errors
β±οΈ Duration: 5:25:08.828429
π Check migration.log for error details
==================================================
- For Gmail, are you using an App Password? Your regular password will not work.
- Double-check your email and password.
- Ensure IMAP is enabled in your account settings.
- Check your internet connection.
- Make sure no firewall is blocking the IMAP port (993).
- The server might be temporarily down; try again later.
If the script stops, you can simply run it again with the same command. It will not create duplicate emails.
- Folder Structure: This script migrates the contents of one folder to another. It does not recreate your entire folder structure.
- Proprietary Features: It does not migrate provider-specific features like Gmail's labels or categories.
This is an open-source project, and contributions are welcome!
- Found a bug? Please open an issue and provide as much detail as possible.
- Have an improvement? Feel free to fork the repository and submit a pull request.
This project is licensed under the MIT License. See the LICENSE
file for details.