A blazingly fast, modern webmail client built with Rust, featuring a Roundcube-inspired UI and optimized IMAP/SMTP operations.
π Open Source | β‘ High Performance | π‘οΈ Secure | π± Responsive
- β‘ Ultra-Fast Performance: Batch IMAP fetching with UID-based lookups
- π¨ Modern UI: Roundcube-inspired responsive design
- π¦ Batch Operations: Fetch headers and bodies in single connection
- π Smart Caching: PostgreSQL-backed email storage with intelligent updates
- π± Responsive Design: Works seamlessly on desktop and mobile
- π‘οΈ Secure: TLS/SSL encryption for all email operations
- π Real-time Updates: Auto-refresh with new email notifications
- π§ Full CRUD: Read, compose, send, and manage emails
- Framework: Actix-web for high-performance HTTP server
- Email:
async-imap
for IMAP,lettre
for SMTP - Database: PostgreSQL with SQLx for async operations
- Security: TLS encryption with
rustls
andwebpki-roots
- Pure Web: Vanilla JavaScript with modern ES6+ features
- Styling: Custom CSS with responsive design
- Architecture: Class-based component system
- Real-time: WebSocket-like polling for updates
-- Core email storage
CREATE TABLE emails (
id SERIAL PRIMARY KEY,
message_id VARCHAR(255) UNIQUE,
from_address TEXT NOT NULL,
to_address TEXT NOT NULL,
subject TEXT,
body TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
fetched_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
imap_uid INTEGER,
is_seen BOOLEAN DEFAULT FALSE,
is_recent BOOLEAN DEFAULT FALSE,
body_preview TEXT
);
-- Sent email tracking
CREATE TABLE sent_emails (
id SERIAL PRIMARY KEY,
to_address TEXT NOT NULL,
subject TEXT,
body TEXT,
sent_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
status VARCHAR(50) DEFAULT 'sent'
);
- Rust (1.70+): Install Rust
- PostgreSQL (12+): Install PostgreSQL
- Gmail App Password: Setup Guide
git clone <your-repo-url>
cd webmail
# Create database and user
createdb webmail_db
psql webmail_db < database_schema.sql
# Copy and configure environment
cp .env.example .env
Edit .env
with your credentials:
DATABASE_URL=postgresql://webmail_user:your_password@localhost:5432/webmail_db
SMTP_USER=your_email@gmail.com
SMTP_PASS=your_16_character_app_password
IMAP_USER=your_email@gmail.com
IMAP_PASS=your_16_character_app_password
# Install dependencies and build
cargo build --release
# Run the server
cargo run
# Server starts on http://127.0.0.1:3001
# Build WebAssembly frontend (optional - HTML version included)
cd frontend
wasm-pack build --target web --out-dir pkg
Open frontend/index.html
in your browser or serve it via a web server.
Method | Endpoint | Description |
---|---|---|
GET |
/emails?limit=50 |
Fetch email list |
GET |
/emails?refresh=true |
Force refresh from IMAP |
GET |
/email/{id} |
Get specific email details |
GET |
/emails/new?since=timestamp |
Check for new emails |
POST |
/send |
Send new email |
GET |
/health |
Health check endpoint |
curl "http://127.0.0.1:3001/emails?limit=20"
Response:
[
{
"id": "uid_12345",
"from": "sender@example.com",
"subject": "Important Update",
"date": "2024-01-15 10:30:00",
"is_seen": false,
"is_recent": true
}
]
curl -X POST "http://127.0.0.1:3001/send" \
-H "Content-Type: application/json" \
-d '{
"to": "recipient@example.com",
"subject": "Hello World",
"body": "This is a test email."
}'
- Single Connection: One IMAP connection per request
- Bulk Operations: Fetch headers and bodies together
- UID-based Indexing: Fast lookups using IMAP UIDs
- Smart Caching: Database-backed with intelligent updates
- Debounced Requests: Prevent duplicate API calls
- Smart Polling: Check for new emails every 30 seconds
- Local Caching: Store email list in memory
- Progressive Loading: Load email bodies on demand
- Indexed Queries: Fast lookups on message_id and UID
- Prepared Statements: SQLx with compile-time query verification
- Connection Pooling: Efficient database connection management
SMTP_SERVER=smtp.gmail.com:587
IMAP_SERVER=imap.gmail.com:993
SMTP_SERVER=smtp-mail.outlook.com:587
IMAP_SERVER=outlook.office365.com:993
Modify src/main.rs
to use different servers:
let mailer = SmtpTransport::starttls_relay("your-smtp-server.com")
.unwrap()
.port(587)
.credentials(creds)
.build();
# Increase connection pool size
DATABASE_MAX_CONNECTIONS=20
# Enable query logging
SQLX_LOGGING=true
// Adjust batch size in src/main.rs
let fetch_limit = limit.min(25); // Increase for faster bulk operations
# Run all tests
cargo test
# Run with output
cargo test -- --nocapture
# Test specific module
cargo test lib::tests
# Install wrk
brew install wrk # macOS
# or
sudo apt-get install wrk # Ubuntu
# Test email fetching
wrk -t4 -c100 -d30s http://127.0.0.1:3001/emails
# Test health endpoint
wrk -t4 -c100 -d10s http://127.0.0.1:3001/health
Error: IMAP login failed
Solutions:
- Enable "Less secure app access" or use App Passwords
- Check firewall settings for port 993
- Verify IMAP credentials in
.env
Error: Database connection failed
Solutions:
- Ensure PostgreSQL is running:
sudo service postgresql start
- Check DATABASE_URL format
- Verify database exists:
psql -l
Error: Email send failed
Solutions:
- Use Gmail App Password (not account password)
- Check SMTP credentials in
.env
- Verify port 587 is accessible
Enable detailed logging:
RUST_LOG=debug cargo run
Verify all systems:
curl http://127.0.0.1:3001/health
Expected response:
{
"status": "ok",
"database": "healthy",
"timestamp": "2024-01-15T10:30:00Z"
}
FROM rust:1.70-slim as builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM debian:bookworm-slim
WORKDIR /app
COPY --from=builder /app/target/release/webmail .
COPY frontend/ ./frontend/
EXPOSE 3001
CMD ["./webmail"]
Build and run:
docker build -t webmail .
docker run -p 3001:3001 --env-file .env webmail
- Reverse Proxy (nginx):
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://127.0.0.1:3001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
- SSL Certificate:
# Using Let's Encrypt
certbot --nginx -d your-domain.com
- Systemd Service:
[Unit]
Description=Webmail Server
After=network.target
[Service]
Type=simple
User=webmail
WorkingDirectory=/opt/webmail
ExecStart=/opt/webmail/target/release/webmail
Restart=always
[Install]
WantedBy=multi-user.target
This is an open source project - contributions are welcome!
We encourage contributions from developers of all skill levels. Whether you're fixing bugs, adding features, improving documentation, or suggesting ideas, your help makes this project better for everyone.
- Fork the repository
- Create a feature branch:
git checkout -b feature-name
- Make your changes following our coding standards
- Test your changes:
cargo test
- Submit a Pull Request
For detailed information about contributing, including:
- π οΈ Development setup
- π Coding standards
- π§ͺ Testing guidelines
- π Pull request process
- π Issue reporting
Please see our CONTRIBUTING.md file.
- π Bug fixes and stability improvements
- β‘ Performance optimizations
- π¨ UI/UX enhancements
- π Documentation improvements
- π§ͺ Tests and quality assurance
- π Internationalization (i18n)
- π± Mobile responsiveness improvements
- π Security enhancements
# Install development dependencies
cargo install cargo-watch
# Auto-rebuild on changes
cargo watch -x run
# Format code
cargo fmt
# Run lints
cargo clippy
For detailed development setup and guidelines, see CONTRIBUTING.md.
This project is open source and available under the MIT License.
- β Free to use for personal and commercial projects
- β Modify and distribute as you wish
- β No warranty - use at your own risk
- β Attribution required - keep the license notice
See the LICENSE file for the full license text.
- Roundcube for UI inspiration
- Rust Community for excellent async ecosystem
- Actix-web for high-performance web framework
- SQLx for type-safe database operations
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Telegram: https://t.me/d_serg
- Email: drobit.github@gmail.com
β Star this repo if you find it useful!
Built with β€οΈ and β‘ by Serhii Drobot