A privacy-first messaging app with zero server storage. Messages exist only while both peers are online, then vanish completely.
- No content on servers: Server only handles discovery + signaling; never sees message payloads
- Ephemeral sessions: Chats exist only while both peers are online; session keys die when either leaves
- Identity = keys, not PII: Usernames are public aliases; trust is anchored in device/account keys
- Metadata minimization: Store only what's essential for reachability; aggressively rotate/expire the rest
- Directory/Signaling Server: Maps usernames to online devices (volatile in-memory store)
- TURN/STUN: NAT traversal for P2P; fallback to TURN relay (still E2E-encrypted)
- Clients: Hold keys, contact list, and minimal logs locally; establish WebRTC data channels
- Account Keypair (AK): Ed25519 for identity (long-term, per user)
- Device Keypair (DK): Ed25519 + Curve25519 for device auth and ECDH
- Pre-keys: Short-lived X25519 bundles advertised only while online
- Session Keys: Derived via X3DH → Double Ratchet for continuous PFS
- Generate AK, DK, and initial pre-key bundle
- Choose username (check availability)
- Server records: username, AK_pub, deviceID, DK_pub (no private keys, no PII)
- Device stores private keys locally (Secure Enclave/KeyStore)
- QR Handoff: Old device displays enrollment token (signed with AK_priv)
- OTP Handoff: Remote device addition with signed token
- Enter username → server returns online status + safety number
- If online, request session → server forwards connection request
- Both sides fetch pre-keys and run X3DH/Noise key exchange
- Switch to Double Ratchet on P2P channel
- Transport: WebRTC DataChannel or QUIC
- Encryption: Double Ratchet with PFS + post-compromise security
- Storage: Messages only in memory (ring buffer), cleared on disconnect
- No persistence: App close/OS kill/lock → buffer cleared
- Persistent: username, AK_pub, deviceID, DK_pub, push tokens
- Ephemeral: Online presence, pre-key bundles, session offers
- Never: Messages, contact lists, safety numbers, IP logs
- Server compromise: Only public keys leak—no content or history
- MITM prevention: Authenticated AKE + safety number verification
- Metadata protection: TURN-only mode to hide peer IPs
- Spam prevention: Rate limits + proof-of-work for first contact
- Device loss: Revoke device with signed revocation from another device
- Mobile:
- Android: Kotlin + Jetpack Compose + Retrofit + OkHttp
- iOS: Swift + SwiftUI + Combine + URLSession
- Cross-platform: React Native + Expo
- Web: Vue.js 3 + Axios
- Transport: WebSocket + HTTP REST API
- Crypto: Android Keystore + iOS Keychain + JWT
- Server: Node.js + Express + SQLite
- Push: APNs / FCM with opaque tokens
- ✅ Cross-platform clients: Android, iOS, Expo, Vue web
- ✅ Account creation and username claim
- ✅ Device key generation and secure storage
- ✅ Real-time ephemeral messaging via WebSocket
- ✅ In-memory ephemeral sessions
- ✅ Friend management system
- ✅ Environment-based configuration
- ✅ Secure credential storage
- 🔄 Multi-device support via QR handoff
- 🔄 Friend requests with safety number verification
- 🔄 WebRTC messaging with Double Ratchet encryption
- 🔄 TURN fallback and push notifications
- 🔄 Device revocation and panic close
- Public: Directory shows username + online/offline status
- Default: Username-only lookup, no public directory
- Strict: Username + Friend Verification Code (FVC) required
- TOTP-based: Time-based codes (60-120s windows)
- Static: One-time printed codes
- Privacy-first: Server verifies without storing secrets
- Wickr Me: Zero-knowledge logs, millisecond ephemeral chats
- Confide: Screenshot-proof, self-destructing messages
- Snapchat: Mainstream ephemeral messaging
- Telegram Secret Chats: E2EE with self-destruct timers
- Session: Decentralized, no PII required
- Live ephemeral messaging with zero storage anywhere
- Strict control over presence & history
- Flexible discovery modes with FVC
- Real-time camera capture without disk storage
- Account creation and device management
- WebRTC messaging with Double Ratchet
- In-memory ephemeral sessions
- Basic friend system
- Auto-delete timers (5s, 1m, 1h, 1d)
- Server minimalism (presence only)
- Panic close functionality
- Screenshot protection
- Safety number verification
- Friend Verification Codes
- Self-destructing media
- Presence controls
- Multi-device support
- Custom discovery modes
- Metadata hiding (TURN-only)
- Group ephemeral chats
- E2E encryption implementation
- Chunked file transfer
- Decentralized relays
The Whisp application supports multiple environments with flexible configuration:
# Start all services for local development
./start-dev.sh- Development: Localhost URLs, debug logging, relaxed CORS
- Staging: Pre-production testing with staging URLs
- Production: Optimized performance, secure configuration
- Expo: Environment-specific
app.jsonfiles - Vue: Automatic hostname detection with fallbacks
- iOS: Build configurations and Info.plist settings
- Android: Build variants and environment-specific URLs
- Environment Variables:
NODE_ENV,PORT,JWT_SECRET,CORS_ORIGIN - Environment Files:
env.development,env.production - Scripts:
npm run dev:env,npm run prod:env
For detailed configuration instructions, see ENVIRONMENT_CONFIG.md.
# Start all services for local development
./start-dev.sh# Set required environment variables
export JWT_SECRET="your-super-secure-jwt-secret"
export CORS_ORIGIN="https://yourdomain.com"
# Deploy all clients and server
./deploy-prod.sh- Technology: Kotlin + Jetpack Compose
- Build:
cd clients/android && ./gradlew assembleDebug - Run: Open in Android Studio or
./gradlew installDebug
- Technology: Swift + SwiftUI
- Build: Open
clients/ios/Whisp/Whisp.xcodeprojin Xcode - Run: Build and run on device/simulator
- Technology: React Native + Expo
- Build:
cd clients/expo && npm run start:dev - Run: Scan QR code with Expo Go app
- Technology: Vue.js 3 + Axios
- Build: Open
clients/vue/index.htmlin browser - Run: Serve from any web server