ONYX: Self-Hosted Messenger with E2EE and Offline LAN Mode
ONYX delivers a perfect balance between ease of deployment and powerful features: a Node.js server backed by MariaDB and Redis, and a Flutter-based client for Android, Windows, macOS, and Linux. It supports full end-to-end encryption using X25519 and XChaCha20-Poly1305, plus a unique offline LAN mode that enables communication without internet via UDP broadcast.
Architecture and Tech Stack
The server runs on Express with WebSocket (express-ws + ws), uses MariaDB for data storage, and Redis for sessions and caching. Files are stored in an S3-compatible storage system using AWS SDK v3. Transport protocols include wss:// and HTTP/REST. Encryption leverages X25519 for key exchange, XChaCha20-Poly1305 for messages, and AES-256-GCM for media within LAN.
Key advantages of XChaCha20-Poly1305 over AES-GCM:
- Constant-time execution independent of AES-NI support.
- Extended nonce (192 bits vs 96), reducing collision risk in long-running sessions.
Encrypted packet format: [pubkey 32B] [nonce 12B] [ciphertext] [mac 16B].
LAN Mode: Automatic Discovery and Offline Messaging
Clients broadcast UDP packets every 5 seconds to 255.255.255.255:45678 containing JSON:
{
"username": "alice",
"timestamp": 1710000000000,
"pubkey": "<X25519 public key, base64>"
}
Receiving clients update internal tables mapping username → IP and username → pubkey. No mDNS, manual IP entry, or additional handshake required—encryption starts instantly.
Media is sent in ~32 KB chunks over port 45679, with each chunk independently encrypted using AES-256-GCM. Decryption and rendering begin as soon as the first chunks arrive.
Multi-Device Sync with Full E2EE Protection
When adding a new device, it requests authorization from a trusted one. After approval, keys are exchanged—server never sees plaintext.
In private chats, the server sends encrypted copies of messages to each user device (one per device’s public key). Only incoming messages sync across devices; outgoing messages remain visible only on the sending device. This design maintains security while enabling basic sync.
Key derivation: HKDF-SHA256 with labels (onyx-lan-v2 for LAN, separate labels for individual chats).
Cross-Platform Client Built with Flutter
Single codebase across four platforms. Flutter powered by Skia/Impeller ensures smooth 60 FPS performance without DOM overhead. Desktop optimizations include:
fps_booster,fps_optimizer,fps_stimulatormessage_load_optimizer,chat_preloader
Desktop-specific features:
- System tray with minimize support
- Single-instance app via IPC
- Custom titlebar with drag zones
- Native notifications on Windows
Security Beyond E2EE
- PIN and biometrics via Flutter Secure Storage
- Proxy support (
proxy_manager.dart) - Secure storage: Keychain / Android Keystore
- Session management: view and delete sessions from trusted devices
Accounts use only username and password—no phone or email required. Usernames are permanent, multiple accounts supported within the app, and full data deletion available.
Groups, Channels, and Self-Hosted Instances
Built-in groups and channels via ONYX server—no E2EE for synchronization purposes.
External self-hosted options:
- Local network: file sharing and chat without internet
- Private community on a VPS via invite-only access
- Public channel with invite-based subscription
Connection: enter server address in external_server_join_screen. Deployment: ONYX Server.
Groups: bidirectional. Channels: admin-only.
Local 'Favorites' Storage
A dedicated tab for notes, categories (passwords, media, links). Stored locally only—no syncing, no server access.
Key Highlights:
- Offline LAN: UDP broadcast + chunked media transfer
- E2EE stack: X25519, XChaCha20-Poly1305, session keys
- Multi-device: per-device encryption, secure authorization
- Flutter: optimized 60 FPS UI across all platforms
- Self-hosted: external instances for groups and channels
The project is currently in beta, ideal for private communication and offline local networks.
— Editorial Team
No comments yet.