English | فارسی | Русский | العربية | 中文 | Español | ไทย | Português | Deutsch | Dansk | Svenska | Türkçe
Elahe Messenger is an open-source, self-hosted, end-to-end encrypted messaging platform built for teams, communities, and individuals who demand full control over their data. It combines the power of Next.js 15, React 19, and Socket.IO on a Node.js runtime, backed by Prisma ORM with PostgreSQL (or SQLite for local development) and optionally scaled horizontally via Redis.
The server never sees plaintext messages. All cryptographic operations are performed client-side using the Web Crypto API.
- Features
- Architecture
- Requirements
- Quick Start
- Manual Installation
- Configuration
- Docker Deployment
- Security
- Contributing
- License
| Category | Capabilities |
|---|---|
| 🔐 Encryption | Browser-side E2EE (ECDH-P256, HKDF-SHA256, AES-256-GCM), forward-secrecy ratchet |
| 💬 Messaging | Real-time DMs, group chats, channels, message reactions, edits, drafts |
| 👥 Social | Contact management, community groups, invite links, member roles |
| 🛡️ Security | TOTP/2FA, session binding, rate limiting, local math captcha, audit logs |
| 🧭 Admin | User management, ban/verify controls, settings panel, observability dashboard |
| 📦 DevOps | Docker Compose variants, one-line installer, Caddy auto-SSL, health checks |
| 📱 PWA | Installable on any device, offline-capable service worker |
| 🔔 Push | VAPID web-push notifications, optional Firebase FCM fallback |
┌─────────────────────────────────────────────────────────┐
│ Browser (Client) │
│ Next.js 15 (App Router) · React 19 · Tailwind CSS 4 │
│ Web Crypto API · Socket.IO Client · IndexedDB (E2EE) │
└──────────────────────┬──────────────────────────────────┘
│ HTTPS / WSS
┌──────────────────────▼──────────────────────────────────┐
│ Node.js Server (server.ts) │
│ Next.js Request Handler · Socket.IO · Background Queue │
└──────┬──────────────────────────────────────┬───────────┘
│ │
┌──────▼──────┐ ┌──────────▼──────────┐
│ PostgreSQL │ │ Redis (optional) │
│ via Prisma │ │ Pub/Sub · Queue │
└─────────────┘ └─────────────────────┘
Key design principles:
- Zero-trust server: private keys never leave the browser
- Stateless auth: signed session cookies, no server-side session store required
- Horizontal scaling: Redis adapter for Socket.IO cluster mode
- Graceful degradation: SQLite fallback for development; Redis is optional
| Dependency | Minimum Version | Notes |
|---|---|---|
| Node.js | 20 LTS | Required for native crypto APIs |
| npm | 10+ | Package management |
| PostgreSQL | 15+ | Production database |
| Redis | 6+ | Optional; enables clustering |
| Docker + Compose | v2+ | Recommended for production |
curl -fsSL https://raw.githubusercontent.com/ehsanking/ElaheMessenger/main/install.sh | bashThe installer will:
- Check system requirements
- Clone the repository
- Prompt for domain / IP configuration
- Generate secrets automatically
- Start services via Docker Compose with auto-SSL (Caddy)
# 1. Clone the repository
git clone https://github.com/ehsanking/ElaheMessenger.git
cd ElaheMessenger
# 2. Copy environment template
cp .env.example .env.local
# 3. Edit .env.local — at minimum set:
# DATABASE_URL, JWT_SECRET, ENCRYPTION_KEY, APP_URL
# 4. Install dependencies (generates Prisma client automatically)
npm install
# 5. Apply database migrations
npx prisma migrate deploy
# or for development:
npx prisma db push
# 6. Build for production
npm run build
# 7. Start
npm startFirst run:
npm installautomatically runsscripts/db-setup.tswhich detects your database type and generates the correct Prisma client.
All configuration is done through environment variables. Copy .env.example to .env.local and set the values below.
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
SQLite (dev only) | PostgreSQL connection string for production |
APP_URL |
http://localhost:3000 |
Public base URL of the application |
NODE_ENV |
development |
Set to production for production builds |
PORT |
3000 |
HTTP server port |
| Variable | Description |
|---|---|
JWT_SECRET |
HMAC-SHA256 signing secret for session tokens (≥ 32 chars) |
ENCRYPTION_KEY |
AES encryption key for sensitive fields |
ADMIN_USERNAME |
Initial admin username (default: admin) |
ADMIN_PASSWORD |
Initial admin password — change immediately after first login |
| Variable | Description |
|---|---|
VAPID_PUBLIC_KEY |
Web Push VAPID public key |
VAPID_PRIVATE_KEY |
Web Push VAPID private key |
VAPID_EMAIL |
Contact email for VAPID |
| Variable | Description |
|---|---|
REDIS_URL |
e.g. redis://localhost:6379 — enables Socket.IO clustering |
| Variable | Default | Description |
|---|---|---|
RATE_LIMIT_WINDOW_MS |
900000 |
Rate limit window in milliseconds (15 min) |
RATE_LIMIT_MAX_REQUESTS |
100 |
Max requests per window per IP |
SOCKET_RATE_LIMIT_WINDOW_MS |
10000 |
Socket rate limit window (10 s) |
SOCKET_RATE_LIMIT_MAX |
30 |
Max socket events per window |
docker compose up -d# Set your domain and secrets in .env, then:
docker compose -f compose.prod.yaml up -d --buildContainer names and services:
| Service | Container | Description |
|---|---|---|
| App | elahe-app |
Next.js + Socket.IO server |
| Database | elahe-db |
PostgreSQL 16 |
| Reverse proxy | elahe-caddy |
Caddy with automatic Let's Encrypt SSL |
Health check endpoint: GET /api/health
Elahe Messenger is designed with a privacy-first, zero-trust philosophy:
- End-to-End Encryption: Messages are encrypted in the browser before transmission using
ECDH-P256key agreement,HKDF-SHA256key derivation, andAES-256-GCMauthenticated encryption. - Server Blindness: The server stores only ciphertext. It cannot read message content.
- Session Security: Session tokens are HMAC-signed, HttpOnly, SameSite=Strict cookies with optional IP and User-Agent binding.
- 2FA/TOTP: RFC 6238 compliant one-time passwords via any standard authenticator app.
- Rate Limiting: Per-IP limits enforced at both the HTTP and WebSocket layers, backed by Redis when available.
- Audit Logging: Admin actions are recorded with IP, timestamp, and actor for forensic traceability.
For vulnerability disclosures, see SECURITY.md.
elahe-messenger/
├── app/ # Next.js App Router pages and API routes
│ ├── actions/ # Server Actions (auth, messages, admin)
│ ├── api/ # REST API route handlers
│ ├── auth/ # Login, register, 2FA pages
│ ├── chat/ # Chat UI and profile pages
│ └── admin/ # Admin panel pages
├── components/ # Shared React components
├── lib/ # Core server-side modules
│ ├── session.ts # Session management
│ ├── crypto.ts # E2EE primitives
│ ├── prisma.ts # Database client singleton
│ ├── rate-limit.ts # Rate limiting logic
│ └── local-captcha.ts # Stateless math captcha
├── prisma/ # Prisma schema and migrations
├── public/ # Static assets (logo, manifest, SW)
├── scripts/ # Utility scripts (db-setup, backup)
├── server.ts # Custom Node.js server (Socket.IO)
├── docker-compose.yml # Development Compose
├── compose.prod.yaml # Production Compose
└── install.sh # One-line production installer
Contributions are welcome. Please follow these steps:
- Fork the repository and create a feature branch:
git checkout -b feat/my-feature - Follow the existing code style — run
npm run formatandnpm run lintbefore committing - Write or update tests where applicable:
npm test - Commit using Conventional Commits:
feat:,fix:,docs:, etc. - Open a Pull Request against
mainwith a clear description of changes
npm run dev # Start dev server with hot-reload
npm run build # Production build
npm run lint # ESLint check
npm run format # Prettier auto-format
npm test # Run Vitest test suite
npm run db:setup # Detect DB type and run migrations
npm run backup # Create database backup archiveReleased under the MIT License.
Copyright © 2025 Elahe Messenger Contributors.
Built with ❤️ by @ehsanking and contributors.
t.me/kingithub
