A lightweight, self-hosted SMTP email client for sending emails from any SMTP server — right from your browser.
JustSend is a self-hosted web application that wraps any SMTP server with a clean, modern UI. Think of it as a personal email dashboard — configure your SMTP servers once, then compose and send emails from your browser.
No email provider lock-in. Works with Gmail, Outlook, Amazon SES, Mailgun, SendGrid, your own mail server, or any service that speaks SMTP.
- 🔀 Multi-SMTP — Add multiple SMTP configs and hot-swap between them per email
- 🔐 Encrypted Credentials — SMTP passwords encrypted at rest with AES-256-GCM
- 📬 Send History — Every email logged with delivery status and error details
- 🐳 Docker-Ready — One-command deploy with Docker Compose / Coolify
- 🗄️ SQLite — Zero-dependency database, no external services needed
- 🎨 Dark UI — Clean, modern interface with glassmorphism design
- Node.js 20+
- npm
# Clone the repo
git clone https://github.com/your-username/justsend.git
cd justsend
# Install dependencies
npm install
# Initialize the database
npm run db:push
# Start dev server
npm run devOpen http://localhost:3000, click the ⚙️ gear icon, add your SMTP server, and start sending.
docker compose up -dThe SQLite database and auto-generated encryption key persist in a named volume across restarts. No configuration needed.
| Variable | Required | Default | Description |
|---|---|---|---|
ENCRYPTION_KEY |
No | Auto-generated | 32-byte hex key for AES-256-GCM. If not set, a key is auto-generated and saved to data/.encryption_key |
DB_FILE_PATH |
No | ./data/justsend.db |
Path to the SQLite database file |
Note: SMTP credentials are configured through the UI and stored encrypted in the database — not in environment variables.
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router) |
| Database | SQLite via better-sqlite3 |
| ORM | Drizzle ORM |
| Nodemailer | |
| UI | Tailwind CSS + shadcn/ui |
| Encryption | Node.js crypto (AES-256-GCM) |
src/
├── app/
│ ├── api/
│ │ ├── emails/ # GET sent email history
│ │ ├── send/ # POST send email
│ │ └── smtp-configs/ # SMTP config CRUD
│ ├── globals.css
│ ├── layout.tsx
│ └── page.tsx
├── components/
│ ├── ui/ # shadcn/ui primitives
│ ├── compose-form.tsx # Email composition with SMTP selector
│ ├── email-detail-dialog.tsx
│ ├── header.tsx # App header with settings button
│ ├── sent-mail-table.tsx
│ ├── smtp-config-dialog.tsx
│ └── smtp-config-manager.tsx
├── db/
│ ├── index.ts # SQLite connection singleton
│ └── schema.ts # Drizzle schema
└── lib/
├── crypto.ts # AES-256-GCM encrypt/decrypt
├── smtp.ts # DB-driven SMTP transporter
└── utils.ts # Shared utilities
- SMTP passwords are AES-256-GCM encrypted before being stored in the database
- Encryption key is auto-generated if not provided — zero-config security
- Passwords are never returned in API responses
- The SQLite database file is excluded from version control via
.gitignore
See ROADMAP.md for planned features.
Topics: email smtp self-hosted email-client email-sender nextjs docker sqlite nodemailer coolify smtp-client mail web-app typescript
