Export emails from Spark Mail's local cache on macOS — works even when accounts are disabled.
Project description
✉️ Spark Mac Mail Export
Export your emails from Spark Mail's local cache on macOS.
Works even when email accounts are disabled or deleted — as long as Spark still has the data cached locally on your Mac.
⚙️ Compatibility
| Spark Version | Status |
|---|---|
| Spark Classic (v2) | ✅ Tested |
| Spark Desktop (v3, +AI) | ✅ Tested |
Spark Classic stores mail data in the shared Group Container (3L68KQB4HG.group.com.readdle.smartemail/databases). Spark Desktop stores mail data under its own Spark Desktop/core-data directory. The schemas are compatible for the export fields this tool reads, and the tool detects both installed apps so you can choose the source with --app or the interactive selector.
✨ Features
- Zero setup — single Python script, no external dependencies
- Auto-detects Spark Classic (Legacy) and Spark Desktop (New)
- Interactive UI — persistent header, Spark app selection, arrow-key navigation with checkboxes, or use CLI flags for automation
- Multiple formats — export to
.emlfiles,.mboxarchives, or both - Organized output — emails sorted by folder with a searchable CSV index
- Read-only — opens databases in read-only mode, cannot modify Spark's data
- Fully offline — no network access, no telemetry, no cloud
- Attachments included — locally cached attachments are embedded in
.emlfiles
⚡ Quick Start
# Clone or download
git clone https://github.com/batuhangobekli/spark-mac-mail-export.git
cd spark-mac-mail-export
# Run (Python 3.8+ required — included with macOS)
python3 spark_mail_export.py
That's it. The script will auto-detect installed Spark apps, ask which source to export from, show your accounts, and guide you through the export.
📖 Usage
Interactive Mode
Run the script with no arguments to get the full interactive experience:
python3 spark_mail_export.py
You'll get:
- Auto-detection of Spark Classic (Legacy) and Spark Desktop (New)
- A Spark app/source selector when both apps are available
- A list of email accounts from the selected source, sorted by email count
- Arrow-key navigation (↑/↓) with Space to toggle and Enter to confirm
- Selected-account context on folder/date/output prompts
- Step-by-step prompts for format and output directory
Note: The interactive UI uses Python's built-in
cursesmodule. If your terminal doesn't support it, the tool falls back to plain text input automatically.
Command-Line Mode
Pass any argument and the tool runs directly — no interactive UI:
# Export a specific account
python3 spark_mail_export.py --account user@example.com
# Export using Spark Desktop's local cache
python3 spark_mail_export.py --app desktop --account user@example.com
# Export using Spark Classic's local cache
python3 spark_mail_export.py --app classic --account user@example.com
# Export all accounts
python3 spark_mail_export.py --all
# Export to MBOX format with custom output directory
python3 spark_mail_export.py --account user@example.com --format mbox -o ~/Documents/backup
# Export only Inbox emails from a date range
python3 spark_mail_export.py --account user@example.com --folder INBOX --date-from 2024-01-01
# Export everything in both formats
python3 spark_mail_export.py --all --format both
# Preview what would be exported (no files written)
python3 spark_mail_export.py --all --dry-run
# List all accounts
python3 spark_mail_export.py --list-accounts
# List Spark Desktop accounts
python3 spark_mail_export.py --app desktop --list-accounts
# List folders for a specific account
python3 spark_mail_export.py --list-folders user@example.com
All Options
--account EMAIL Export specific account (by email address or display name)
--all Export all accounts without prompting
--app APP Source app: auto, classic, or desktop (default: auto)
--output, -o DIR Output directory (default: ~/Desktop/spark-export)
--format, -f FMT eml, mbox, or both (default: eml)
--folder NAME Filter by folder name (e.g., INBOX, 'Sent Mail')
--date-from DATE Start date filter (YYYY-MM-DD)
--date-to DATE End date filter (YYYY-MM-DD)
--dry-run Show what would be exported without writing files
--list-accounts List all accounts and exit
--list-folders EMAIL List all folders for an account and exit
--include-no-body Include emails even if no body is cached (default: all included)
--quiet, -q Suppress progress output
--version Show version
--help Show help message
Tip: Any argument triggers non-interactive mode. Use
--accountor--allto specify what to export. If you forget, the tool will show an error with the correct usage.
📁 Output Structure
~/Desktop/spark-export/
└── user@example.com/
├── eml/
│ ├── INBOX/
│ │ ├── 2025-10-15_143021_JohnDoe_Project-Update.eml
│ │ └── ...
│ ├── Sent Mail/
│ │ └── ...
│ └── ...
├── mbox/ # Only if --format mbox or both
│ ├── INBOX.mbox
│ └── Sent Mail.mbox
├── email_index.csv # Searchable index of all emails
└── export_summary.txt # Human-readable summary
Accounts are sorted by email count (highest first). Emails are organized into per-folder subdirectories with date-prefixed filenames for easy sorting.
📬 How to View .eml Files
| Method | Instructions |
|---|---|
| macOS Quick Look | Select .eml file → press Space |
| Apple Mail | Drag .eml files into a mailbox |
| Thunderbird | Install "ImportExportTools NG" add-on → Import directory |
| Outlook | Double-click any .eml file |
| Gmail | Import via Thunderbird + IMAP sync |
| Web browser | Open .eml file directly for HTML emails |
For detailed instructions, see docs/viewing_eml_files.md.
Requirements
- macOS (any recent version)
- Python 3.8+ (included with macOS)
- Spark Mail must have been used at least once (to create local data)
⚠️ Limitations
- macOS only — Spark's local storage is macOS-specific
- Only locally cached data — If Spark never synced/opened an email's body, only metadata + a short preview will be available
- Attachments — Only locally downloaded attachments are exported; cloud-only attachments will have metadata but no file content
- Database lock — Spark should be quit before running the export (the tool will warn you if the database is locked)
- Account must exist in Spark — The account entry must still be in Spark's database (not fully removed from the app)
⚖️ Legal Notice
This tool reads your own email data from standard SQLite database files stored on your own filesystem by the Spark Mail application.
This tool does not reverse engineer, decompile, or disassemble any application binary. It does not bypass any encryption or security measures. It does not access any remote servers. It does not modify Spark's data in any way (read-only access).
This project is not affiliated with Readdle Inc. or Spark Mail Limited.
You are solely responsible for ensuring your use of this tool complies with applicable laws and Terms of Service.
For the full disclaimer, see DISCLAIMER.md.
🔒 Security
- Read-only database access (
?mode=ro) - Zero network requests
- Zero external dependencies
- No passwords or credentials are accessed
- No telemetry or data collection
You can audit the entire tool — it's a single Python file. See SECURITY.md for details.
📦 Installation
Using pipx (Recommended)
pipx is the best way to safely install Python CLI tools.
pipx install spark-mail-export
spark-mail-export
Using pip
pip install spark-mail-export
spark-mail-export
Direct Download
curl -sLO https://raw.githubusercontent.com/batuhangobekli/spark-mail-export/master/spark_mail_export.py
python3 spark_mail_export.py
🤝 Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Running Tests
python3 tests/test_sanitize.py
python3 tests/test_address_parser.py
python3 tests/test_utils.py
python3 tests/test_db_reader.py
python3 tests/test_detector.py
Technical Documentation
- Database Schema — How Spark stores emails locally
- Viewing EML Files — Guide to opening exported emails
📄 License
MIT — Copyright (c) 2026 Batuhan Göbekli
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file spark_mail_export-0.0.2.tar.gz.
File metadata
- Download URL: spark_mail_export-0.0.2.tar.gz
- Upload date:
- Size: 25.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f2e2ab3787e64211edbdfe25b9155d60d322ca0b51605288839bed54c06c0e3c
|
|
| MD5 |
ed1ffe4a188a86d60c0d9082b3273bf1
|
|
| BLAKE2b-256 |
9402ee6fddf840da7b0e0a35abd867c4fffc8b790f628fe72c5e91ce0fc8fb41
|
Provenance
The following attestation bundles were made for spark_mail_export-0.0.2.tar.gz:
Publisher:
python-publish.yml on batuhangobekli/spark-mail-export
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
spark_mail_export-0.0.2.tar.gz -
Subject digest:
f2e2ab3787e64211edbdfe25b9155d60d322ca0b51605288839bed54c06c0e3c - Sigstore transparency entry: 1706464330
- Sigstore integration time:
-
Permalink:
batuhangobekli/spark-mail-export@6febe17160390b46722f662b315e019bf9715105 -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/batuhangobekli
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@6febe17160390b46722f662b315e019bf9715105 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file spark_mail_export-0.0.2-py3-none-any.whl.
File metadata
- Download URL: spark_mail_export-0.0.2-py3-none-any.whl
- Upload date:
- Size: 21.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f17dc42a9af9b49969c89160ee30518dc16468aa3a801463e9c671c56aeb027f
|
|
| MD5 |
68bcc108c48c6849afefcbc06fbdf179
|
|
| BLAKE2b-256 |
5175030ede71dd787adfd6667477d613b98c202d3e5640614ba9eea476d4ba86
|
Provenance
The following attestation bundles were made for spark_mail_export-0.0.2-py3-none-any.whl:
Publisher:
python-publish.yml on batuhangobekli/spark-mail-export
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
spark_mail_export-0.0.2-py3-none-any.whl -
Subject digest:
f17dc42a9af9b49969c89160ee30518dc16468aa3a801463e9c671c56aeb027f - Sigstore transparency entry: 1706464394
- Sigstore integration time:
-
Permalink:
batuhangobekli/spark-mail-export@6febe17160390b46722f662b315e019bf9715105 -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/batuhangobekli
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@6febe17160390b46722f662b315e019bf9715105 -
Trigger Event:
workflow_dispatch
-
Statement type: