Native Mailer is a beautiful, cross-platform desktop application that provides a local SMTP server for catching and viewing emails during development. Built with Laravel, NativePHP, and Filament, it offers a modern, elegant solution for email testing without the need for external services.
- Local SMTP Server - Full-featured SMTP server running on
127.0.0.1:1025 - Zero Configuration - Works out of the box, no external dependencies
- Native Desktop App - True native application for Windows, macOS, and Linux
- Automatic Email Capture - Catches all emails sent to the SMTP server
- Beautiful Admin Panel - Powered by Filament 4.0 with a modern, intuitive interface
- Rich Email Preview - View HTML emails in a sandboxed iframe with full styling
- Advanced Search - Search emails by sender, recipient, or subject
- Bulk Operations - Delete multiple emails at once
- Email Details - View complete email metadata including headers and timestamps
- Modern Design - Built with Tailwind CSS 4.0 for a clean, professional look
- Responsive Layout - Works seamlessly on any screen size
- Dark Mode Ready - Filament's built-in dark mode support
- Real-time Updates - Instant email display as they arrive
- High Performance - Non-blocking socket implementation for handling multiple connections
- SQLite Database - Lightweight, serverless database for email storage
- Multipart Support - Handles plain text and HTML emails with attachments
- Content Decoding - Supports base64 and quoted-printable encoding
- Cross-platform - Single codebase runs natively on all platforms
| Technology | Version | Purpose |
|---|---|---|
| PHP | 8.2+ | Core language |
| Laravel | 12.0 | Application framework |
| Filament | 4.0 | Admin panel framework |
| NativePHP Desktop | 2.0 | Native application wrapper |
| Livewire | 3.6 | Reactive components |
| Tailwind CSS | 4.0 | Styling framework |
| Vite | 7.0 | Frontend build tool |
| SQLite | - | Database |
| php-mime-mail-parser | 9.0 | Email parsing |
Before you begin, ensure your system meets these requirements:
- PHP 8.2 or higher
- Composer (latest version recommended)
- Node.js 18+ and npm
- SQLite (usually included with PHP)
- Windows 10 or later (64-bit)
- Visual C++ Redistributable (automatically handled by NativePHP)
- macOS 10.15 (Catalina) or later
- Xcode Command Line Tools (for building)
- Modern Linux distribution (Ubuntu 20.04+, Fedora 35+, etc.)
- GTK 3.0+ libraries
# Clone the repository
git clone https://github.com/projecthanif/nativemailer.git
cd nativemailer
# Run the automated setup
composer setupThe composer setup command will:
- Install PHP dependencies via Composer
- Create
.envfile from.env.example - Generate application key
- Run database migrations
- Install Node.js dependencies
- Build frontend assets
If you prefer manual installation:
# 1. Clone the repository
git clone https://github.com/projecthanif/nativemailer.git
cd nativemailer
# 2. Install PHP dependencies
composer install
# 3. Set up environment
cp .env.example .env
php artisan key:generate
# 4. Create and migrate database
touch database/database.sqlite
php artisan migrate
# 5. Install Node dependencies
npm install
# 6. Build assets
npm run buildStart the application in development mode with hot-reload:
# Start the native application with auto-reload
php artisan native:serveOr use the composer script for concurrent development:
# Runs app and watches for changes
composer native:devWhat happens when you start the app:
- 🚀 NativePHP launches the native desktop window
- 📡 SMTP server starts automatically on
127.0.0.1:1025 - 🎨 Filament admin panel opens at
/admin/emails - 📬 Application is ready to receive emails
Build native executables for distribution:
# Build for your current platform
php artisan native:build
# Builds will be available in: builds/Build Output:
- Windows:
.exeinstaller - macOS:
.dmgdisk image - Linux:
.AppImageexecutable
To send emails from your Laravel application (or any app) to Native Mailer:
Update your .env file:
MAIL_MAILER=smtp
MAIL_HOST=127.0.0.1
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="test@example.com"
MAIL_FROM_NAME="${APP_NAME}"// PHPMailer
$mail = new PHPMailer();
$mail->isSMTP();
$mail->Host = '127.0.0.1';
$mail->Port = 1025;
$mail->SMTPAuth = false;
// Symfony Mailer
$transport = (new Smtp())
->setHost('127.0.0.1')
->setPort(1025);Send a test email:
php artisan tinkerMail::raw('Test email from Native Mailer', function ($message) {
$message->to('test@example.com')
->subject('Test Email');
});Check the Native Mailer app to see your email!
native-mailer/
├── app/
│ ├── Console/
│ │ └── Commands/
│ │ └── StartSmtpCatcher.php # Artisan command to start SMTP
│ ├── Filament/
│ │ └── Resources/
│ │ └── Emails/
│ │ ├── EmailResource.php # Filament resource definition
│ │ ├── Pages/
│ │ │ ├── ListEmails.php # Email list page
│ │ │ └── ViewEmail.php # Email detail page
│ │ ├── Schemas/
│ │ │ └── EmailInfolist.php # Email display schema
│ │ └── Tables/
│ │ └── EmailsTable.php # Table configuration
│ ├── Models/
│ │ └── Email.php # Email Eloquent model
│ ├── Providers/
│ │ └── NativeAppServiceProvider.php # NativePHP config
│ └── Services/
│ ├── SmtpCatcher.php # Core SMTP server implementation
│ └── SmtpServiceManager.php # Service lifecycle management
├── database/
│ └── migrations/
│ └── 2025_10_25_020118_create_emails_table.php
├── resources/
│ ├── css/
│ │ └── app.css # Tailwind styles
│ ├── js/
│ │ └── app.js # Frontend JavaScript
│ └── views/
│ └── filament/
│ └── email-html-view.blade.php # Email HTML renderer
├── routes/
│ └── web.php # Route definitions
├── config/
│ └── nativephp.php # NativePHP configuration
└── composer.json # PHP dependencies
The SMTP server is implemented in SmtpCatcher.php using PHP's socket functions:
┌─────────────────────────────────────────────────────┐
│ SMTP Catcher │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Socket │───▶│ Client │ │
│ │ Listener │ │ Handler │ │
│ │ (Port 1025) │ │ (Non-block) │ │
│ └──────────────┘ └──────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Accept │ │ Parse │ │
│ │ Connection │ │ SMTP │ │
│ └──────────────┘ └──────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ Store in │ │
│ │ Database │ │
│ └──────────────┘ │
└─────────────────────────────────────────────────────┘
Key Features:
- Non-blocking I/O - Handles multiple simultaneous connections
- State Machine - Implements SMTP protocol states (HELO, MAIL, RCPT, DATA)
- Multi-part Parsing - Separates HTML and plain text content
- Content Decoding - Handles quoted-printable and base64 encoding
Email Sent ──▶ SMTP Server ──▶ Parse Headers ──▶ Extract Content
│ │
▼ ▼
Store Raw Data ──────────────▶ Save to Database
│
▼
Trigger Event ──▶ UI Update
emails table:
| Column | Type | Description |
|---|---|---|
id |
bigint | Primary key |
from |
string | Sender email address |
to |
string | Recipient email address(es) |
subject |
string | Email subject line |
body_text |
longtext | Plain text content |
body_html |
longtext | HTML content |
attachments |
json | Array of attachment metadata |
raw |
longtext | Complete raw email for debugging |
received_at |
timestamp | When email was received |
created_at |
timestamp | Database creation time |
updated_at |
timestamp | Last update time |
Native Mailer uses Filament 4.0 for its admin interface, providing:
- Email List View: Sortable, searchable table with pagination
- Email Detail View: Full email preview with HTML rendering
- Bulk Actions: Delete multiple emails at once
- Search Filters: Find emails by sender, recipient, or subject
- Date Sorting: Sort emails by received date
HTML emails are rendered in a sandboxed iframe for security:
<iframe
srcdoc="{{ $email->body_html }}"
sandbox="allow-same-origin"
class="email-iframe"
/>Security Features:
- Sandboxed iframe prevents JavaScript execution
- No external resource loading
- Isolated from parent document
The SMTP server implements essential SMTP commands:
| Command | Description | Example |
|---|---|---|
HELO/EHLO |
Initiate connection | EHLO client.example.com |
MAIL FROM |
Specify sender | MAIL FROM:<sender@example.com> |
RCPT TO |
Specify recipient | RCPT TO:<recipient@example.com> |
DATA |
Begin message content | DATA |
QUIT |
Close connection | QUIT |
# Run all tests
php artisan test
# Run with Pest
./vendor/bin/pest
# Run specific test file
php artisan test --filter=EmailTestFormat code using Laravel Pint:
# Fix code style
./vendor/bin/pint
# Preview changes without fixing
./vendor/bin/pint --testFor active development with hot-reload:
# Terminal 1: Run the native app
php artisan native:serve
# Terminal 2: Watch assets (in separate terminal)
npm run devOr use the convenience script:
# Runs everything concurrently
composer native:devTest the SMTP server directly using telnet:
telnet 127.0.0.1 1025EHLO localhost
MAIL FROM:<test@example.com>
RCPT TO:<recipient@example.com>
DATA
Subject: Test Email
From: test@example.com
To: recipient@example.com
This is a test email body.
.
QUIT
Enable detailed logging in config/nativephp.php:
'phpIni' => [
'display_errors' => '1',
'error_reporting' => 'E_ALL',
'log_errors' => '1',
],Logs are stored in:
storage/logs/laravel.log- Application logsstorage/logs/smtp.log- SMTP-specific logs
If port 1025 is already occupied:
# Windows - Find process using port 1025
netstat -ano | findstr :1025
taskkill /F /PID <PID>
# macOS/Linux
lsof -ti:1025 | xargs kill -9Reset the database:
rm database/database.sqlite
touch database/database.sqlite
php artisan migrate:freshClear caches and rebuild:
php artisan config:clear
php artisan cache:clear
php artisan view:clear
npm run buildContributions are welcome and appreciated! Here's how you can help:
- Check if the issue already exists
- Include detailed reproduction steps
- Provide system information (OS, PHP version, etc.)
- Include relevant logs or screenshots
- Describe the feature and its benefits
- Provide use cases
- Consider implementation complexity
- Fork the repository
- Create a feature branch
git checkout -b feature/amazing-feature
- Commit your changes
git commit -m 'Add amazing feature' - Push to your branch
git push origin feature/amazing-feature
- Open a Pull Request
- Follow PSR-12 coding standards
- Write tests for new features
- Update documentation as needed
- Run
./vendor/bin/pintbefore committing - Keep commits atomic and well-described
This project is open-source software licensed under the MIT License.
MIT License
Copyright (c) 2025 Mustapha Hanif
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
This project is built on the shoulders of giants:
- Laravel - The PHP framework for web artisans
- NativePHP - Build native desktop applications with PHP
- Filament - Beautiful admin panels for Laravel
- Livewire - Full-stack framework for Laravel
- Tailwind CSS - Utility-first CSS framework
- Vite - Next generation frontend tooling
Special thanks to:
- The Laravel community for their amazing packages and support
- The NativePHP team for making native PHP apps possible
- All contributors and users of Native Mailer
Mustapha Hanif
- GitHub: @projecthanif
- Email: Contact via GitHub
If you find this project helpful, please consider:
- ⭐ Starring the repository
- 🐛 Reporting bugs
- 💡 Suggesting new features
- 🔀 Contributing code
- 📢 Sharing with others
Made with ❤️ using Laravel and NativePHP