Bichon is an open-source email archiving system that synchronizes emails from IMAP servers, indexes them for full-text search, and provides a REST API for programmatic access. Unlike email clients, Bichon is designed for archiving and searching rather than sending/receiving emails. It runs as a standalone server application that continuously synchronizes configured email accounts and maintains a searchable local archive. Built in Rust, it requires no external dependencies and provides fast, efficient email archiving, management, and search through a built-in WebUI. Its name is inspired by the puppy my daughter adopted last month.
Key Differences from Email Clients
Core Comparison
| Feature | Email Clients | Bichon |
|---|---|---|
| Primary Purpose | Send/receive emails, real-time communication | Archive, search, manage historical emails |
| Sending Capability | ✅ Supports sending emails | ❌ No email sending support |
| Runtime Mode | Desktop/mobile applications | Server-side application |
| Data Storage | Local cache + server | Local archive store |
| Search Capability | Basic search | Full-text indexing, advanced search |
| API Interface | Typically not provided | Complete REST API |
| Multi-account Management | Limited | Supports unified search across accounts |
🧠 Intelligent Storage & De-duplication
Bichon implements a Single-Instance Storage philosophy at the account level to maximize storage efficiency and write performance.
- Message-ID Centric: Every email is uniquely identified by its
Message-ID. - High-Performance Writes: Uses an idempotent "Delete-then-Write" strategy to ensure the fastest possible indexing speed.
- Automatic State Updates: Moving an email between folders (e.g., from Inbox to Trash) will update the existing record rather than creating a duplicate.
- Lean Imports: Duplicate emails encountered during
nosyncbulk imports are automatically merged.
👉 Deep Dive: How Bichon handles de-duplication
🚀 Features
- Lightweight & Standalone — Pure Rust, no external database, with built-in WebUI
- Multi-Account Sync — Download and manage emails from multiple accounts
- Flexible Fetching — Sync by date range, email count, or specific mailboxes
- IMAP & OAuth2 Auth — Password or OAuth2 login with automatic token refresh
- Proxy & Auto Config — Supports network proxies and automatic IMAP discovery
- Unified Search — Search across all accounts by sender, subject, body, date, size, attachments, and more
- Tags & Facets — Organize emails using Tantivy facet-based tags
- Compressed Storage — Transparent compression and deduplication for efficient storage
- Email Management — Browse, view threads, bulk clean up, export EML or attachments
- Dashboard & Analytics — Visual insights into email volume, trends, and top senders
- Internationalized WebUI — Frontend available in 18 languages
- OpenAPI Access — OpenAPI docs with access-token authentication
- Multi-User & Role-Based Access Control (RBAC) — Supports multiple users with fine-grained, role-based permissions
- Email Import (EML, MBOX & PST) — Import existing mail archives via the bichonctl CLI
🐾 Why Create Bichon?
A few months ago, I released rustmailer, an email API middleware:
https://github.com/rustmailer/rustmailer
Since then, I’ve received many emails asking whether it could also archive emails, perform unified search, and support full-text indexing—not just querying recipients.
But rustmailer was designed as a middleware focused on providing API services.
Adding archiving and full-text search would complicate its core purpose and go far beyond its original scope.
Meanwhile, I realized that email archiving itself only requires a small portion of rustmailer’s functionality, plus a search engine.
With that combination, building a dedicated, efficient archiver becomes much simpler.
Using the experience gained from rustmailer, I designed and built Bichon in less than two weeks, followed by another two weeks of testing and optimization.
It has now reached a stable, usable state—and I decided to release it publicly.
Bichon is completely free.
You can download and use it however you like.
It’s not perfect, but I hope it brings you value.
📸 Snapshot
Star History
🚀 Quick Start
Docker Deployment (Recommended)
# Pull the image docker pull rustmailer/bichon:latest # Create data directory mkdir -p ./bichon-data # Run container docker run -d \ --name bichon \ -p 15630:15630 \ -v $(pwd)/bichon-data:/data \ --user 1000:1000 \ -e BICHON_LOG_LEVEL=info \ -e BICHON_ROOT_DIR=/data \ rustmailer/bichon:latest
Optional: Custom storage layout
docker run -d \ --name bichon \ -p 15630:15630 \ -v $(pwd)/bichon-data:/data \ -v $(pwd)/envelope:/envelope \ -v $(pwd)/eml:/eml \ --user 1000:1000 \ -e BICHON_ROOT_DIR=/data \ -e BICHON_INDEX_DIR=/envelope \ -e BICHON_DATA_DIR=/eml \ rustmailer/bichon:latest
Recommended docker-compose example
services:
bichon:
image: rustmailer/bichon:latest
container_name: bichon
ports:
- "15630:15630"
volumes:
- ./bichon-data:/data
user: "1000:1000"
environment:
BICHON_ROOT_DIR: /data
BICHON_LOG_LEVEL: info
User and permissions
PUID and PGID are no longer used to create users or groups inside the container.
Please use Docker’s native --user option (or user: in docker-compose) to specify the UID and GID:
docker run --user 1000:1000 ...
This ensures container file permissions match the ownership of host-mounted directories.
CORS Configuration (Important for Browser Access)
Starting from v0.1.4, Bichon changes how BICHON_CORS_ORIGINS works:
🔄 New Behavior in v0.1.4
- If
BICHON_CORS_ORIGINSis not set, Bichon now allows all origins. This makes local testing and simple deployments much easier. - If you do set
BICHON_CORS_ORIGINS, then you must explicitly list each allowed origin. *is not supported and will not work — you must provide exact URLs.
How CORS Matching Works
When a browser accesses Bichon, it will send an Origin header.
- Incoming Origin = the exact address the browser is using
- Configured origins = the list you passed to
BICHON_CORS_ORIGINS
If Configured origins does not contain the Incoming Origin exactly as a full string match, the browser request will be rejected.
Example debug log:
2025-12-06T23:56:30.422+08:00 DEBUG bichon::modules::rest: CORS: Incoming Origin = "http://localhost:15630"
2025-12-06T23:56:30.422+08:00 DEBUG bichon::modules::rest: CORS: Configured origins = ["http://192.168.3.2:15630"]
In this example:
- Browser is using
http://localhost:15630 - But the configured origin is
http://192.168.3.2:15630
→ CORS will fail, and you can immediately see why.
When Should You Configure CORS?
It is strongly recommended to configure CORS in production environments to ensure that only trusted browser origins can access Bichon. If you want to access Bichon from a browser:
- Add the exact IP with port
- Or the exact hostname with port
- Or the domain (port optional if it's 80)
Examples:
http://192.168.1.16:15630
http://myserver.local:15630
http://mydomain.com
If you access Bichon in multiple different ways, list all of them:
-e BICHON_CORS_ORIGINS="http://192.168.1.16:15630,http://myserver.local:15630,http://mydomain.com"
Do not add a trailing slash (
http://192.168.1.16:15630/will not match)Do not use
*, it is not supported.
How to Enable Debug Logs (Highly Recommended for CORS Issues)
Set environment variable:
Or via command-line:
Default is info, so CORS logs will not appear unless debug logging is enabled.
⚠️ Note on Running Bichon in a Container
⚠️ Note: If you are running Bichon in a container (via Docker Compose or docker run), be careful with quotes in environment variable values.
For example, do not write:
-e BICHON_CORS_ORIGINS="http://localhost:15630,http://myserver.local:15630"- The outer quotes (
") will be passed literally into the container and may cause CORS misconfiguration.
Correct way:
-e BICHON_CORS_ORIGINS=http://localhost:15630,http://myserver.local:15630
Or using YAML literal style for Docker Compose:
environment: BICHON_CORS_ORIGINS: | http://localhost:15630,http://myserver.local:15630
This ensures that the configured origins are interpreted correctly inside the container.
⚠️ Note: This fucking problem I actually didn’t know about myself; thanks to gall-1 for pointing it out.
Binary Deployment
Download the appropriate binary for your platform from the Releases page:
- Linux (GNU):
bichon-x.x.x-x86_64-unknown-linux-gnu.tar.gz - Linux (MUSL):
bichon-x.x.x-x86_64-unknown-linux-musl.tar.gz - macOS:
bichon-x.x.x-x86_64-apple-darwin.tar.gz - Windows:
bichon-x.x.x-x86_64-pc-windows-msvc.zip
Extract and run:
# Linux/macOS ./bichon --bichon-root-dir /tmp/bichon-data # Windows .\bichon.exe --bichon-root-dir e:\bichon-data
-
--bichon-root-dir argument is required and must be an absolute path.
-
If you are accessing Bichon from a proxy domain mydomain argument --bichon-cors-origins="https://mydomain" is required.
🔐 Setting the Bichon Encryption Password
Please refer to the following documentation for detailed instructions on how to set the Bichon encryption password:
👉 https://github.com/rustmailer/bichon/wiki/Setting-the-Bichon-Encryption-Password
All configuration methods, including command-line options, environment variables, and password file support (v0.2.0+), are documented there.
🔑 User Authentication & Admin Account
Starting from Bichon v0.2.0, the authentication model has been updated.
Built-in Admin User (v0.2.0+)
-
Bichon no longer uses the legacy single-account
root / rootlogin. -
The system now ships with a built-in admin user by default.
-
Default credentials:
- Username:
admin - Password:
admin@bichon
- Username:
The legacy
rootaccount and theroot / rootdefault credentials no longer exist.
Mandatory Access Token Authentication
- From v0.2.0 onward, access-token–based authentication is always enabled.
- The startup flag and environment variable
--bichon-enable-access-token/BICHON_ENABLE_ACCESS_TOKENare deprecated and no longer used. - No additional configuration is required to enable authentication.
Managing Account Information
After logging in, the admin user can manage their profile directly in the WebUI:
-
Log in to the WebUI using the default admin credentials.
-
Navigate to Settings → Profile.
-
Update:
- Username
- Password
- Avatar and other profile information
📦 Import Existing Mail Archives
If you already have existing emails stored as EML or MBOX files, you can import them into Bichon using the bichonctl CLI.
This allows you to:
- Index historical emails
- Perform full-text search immediately
- Manage imported data just like synced IMAP emails
📖 Full documentation:
👉 https://github.com/rustmailer/bichon/wiki/Using-Bichonctl-For-Email-Import
📖 Documentation
Under construction. Documentation will be available soon. Bichon Wiki.
FAQ
please see the FAQ in the project Wiki:
👉 https://github.com/rustmailer/bichon/wiki/FAQ
💡 User Case Showcase
We have collected a real-world case study from a user processing email data, which demonstrates Bichon's performance and storage efficiency in a live environment. This case involves ingesting and indexing data from 126 email accounts. The total original data volume was 229 GB, comprising 460,000 emails.
📊 Performance Data Overview
A special thank you to @rallisf1 for sharing this usage scenario and the detailed data.
🤝 Open Invitation
This data is provided solely as a reference for real-world usage. We encourage more users to share their Bichon usage screenshots and metrics (e.g., ingestion volume, compression ratio, search speed, etc.) to help the community conduct a more comprehensive assessment of Bichon's suitability and performance.
Roadmap
-
Multi-user support with account/password login
- System-level roles (admin / user)
- Per-mail-account permissions
-
bichonctlcommand-line tool- Import emails from
eml,mbox,pst(Single file)
- Import emails from
-
Manual sync controls
- Sync on demand
- Sync a single folder
- Verify completeness by comparing with the mail server
-
Post-sync server cleanup
- Clean up server-side emails after successful sync
- Free up mailbox space (e.g. Gmail)
-
Email export
- Export by folder
- Export by entire account
-
Account-to-account email sync
- Sync emails to a specified target account
- Support mailbox migration
-
SMTP server / gateway support
- Provide a lightweight SMTP receiving service
- Allow direct forwarding of incoming mail to Bichon at the gateway level
- Achieve more reliable, real-time, complete email archiving & backup
- Optional: support alias / catch-all / domain-level routing
-
MCP Server
- Provide an LLM interface for advanced email search and intelligent processing
- Enable natural language queries to search and understand email content
- Make Bichon capable of smarter email interaction and analysis
🛠️ Tech Stack
- Backend: Rust + Poem
- Frontend: React + TypeScript + Vite + ShadCN UI
- Core Engine (Storage & Search): Tantivy
- Acts as both the primary storage for email content and the full-text search index. This unified approach ensures high performance and eliminates data redundancy.
- Metadata Storage: Native_DB
- Used exclusively for lightweight configuration and account metadata.
- Email Protocols: IMAP (Supports standard Password & OAuth2)
🤝 Contributing
Contributions of all kinds are welcome!
Whether you’d like to submit code, report a bug, or share practical suggestions that can help improve the project, your input is highly appreciated.
Feel free to open an Issue or a Pull Request anytime. You can also reach out on Discord if you’d like to discuss ideas or improvements.
🧑💻 Developer Guide
To build or contribute to Bichon, the following environment is recommended:
Prerequisites
- Rust: Use the latest stable toolchain for best compatibility and performance.
- Node.js: Version 20+ is required.
- pnpm: Recommended package manager for the WebUI.
Steps
1. Clone the repository
git clone https://github.com/rustmailer/bichon.git
cd bichon2. Build the WebUI
cd web
pnpm install
pnpm run buildRun the WebUI in development mode if needed:
3. Build or Run the Backend
After the WebUI is built, return to the project root:
Or run directly:
export BICHON_ENCRYPT_PASSWORD=dummy-password-for-testing cargo run -- --bichon-root-dir e:\bichon-data
--bichon-root-dir specifies the directory where all Bichon data will be stored.
BICHON_ENCRYPT_PASSWORD is the password used to encrypt the sensitive data (see cargo run -- --help for alternative ways to specify this).
WebUI Access
- The WebUI runs on http://localhost:15630 by default.
- HTTPS is not enabled in development or default builds.
📄 License
This project is licensed under AGPLv3.
🔗 Links
💖 Support & Promotion
Bichon is an open-source email platform focused on privacy, local ownership, and long-term stability.
The project is freely available and fully functional for everyone.
Some members of the community choose to support the project financially. This support helps sustain ongoing development and long-term maintenance, while keeping the project independent and user-driven.
Support is always optional. You can also contribute by sharing feedback, reporting issues, or recommending Bichon to others.