True peer-to-peer chat where messages travel directly between users.
No servers storing or reading your conversations. Everything exists only in memory and disappears when you close the tab.
- Screenshots
- Why GhostChat?
- Comparison
- Features
- Quick Start
- Architecture
- Security
- Development
- Deployment
- Professional Services
- License
- Acknowledgments
- Support
Most "secure" messaging apps still store your messages on servers. Even Signal and WhatsApp keep metadata. GhostChat is different:
- ✅ True P2P - Messages travel directly between users via WebRTC
- ✅ Zero server storage - No databases, no logs, no message history
- ✅ Memory-only - Everything stored in RAM, wiped on tab close
- ✅ No accounts - No phone numbers, emails, or persistent identity
- ✅ Self-destructing - Messages auto-delete after 5s, 30s, 1m, or 5m
- ✅ Open source - Fully auditable code (MIT license)
Perfect for: Journalists, whistleblowers, activists, lawyers, executives, or anyone who values true privacy.
| Feature | GhostChat | Signal | Telegram | |
|---|---|---|---|---|
| True P2P | ✅ Yes | ❌ No | ❌ No | ❌ No |
| No server storage | ✅ Yes | ❌ Metadata | ❌ Metadata | ❌ Messages |
| Does not require account | ✅ Yes | ❌ Phone | ❌ Phone | ❌ Phone |
| No logs | ✅ Yes | ❌ No | ❌ No | ❌ No |
| Self-destruct | ✅ Yes | ✅ Yes | ❌ No | ✅ Yes |
| Open source | ✅ Yes | ✅ Yes | ❌ No | ❌ Partial |
| Cost | 💰 Free | 💰 Free | 💰 Free | 💰 Free |
- Direct P2P connections - Messages never touch servers
- E2E encryption - WebRTC native DTLS/SRTP
- Memory-only storage - Zero disk traces, no forensics possible
- Ephemeral identity - Random peer ID per session
- Auto-clear on close - All data wiped when tab closes
- Connection fingerprint - 4-emoji hash to verify no MITM
- Sensitive content blur - Auto-detect and blur passwords, SSN, credit cards
- Metadata stripping - Remove EXIF data from images
- Anti-forensics - Memory overwrite on message delete
- Self-destructing messages - Timer: 5s, 30s, 1m, 5m, or never
- Message deletion - Delete for both sides with P2P sync
- Read receipts - Single/double checkmark delivery status
- Typing indicators - See when peer is typing
- Markdown support - 16 formatting buttons (bold, italic, code, etc.)
- Quick emojis - 15 one-click emoji buttons
- Message search - Real-time filtering with highlighting
- Copy protection - Clipboard auto-clears after 10 seconds
- P2P file transfer - Send files up to 10MB directly
- Chunked transfer - Reliable transmission via 64KB chunks
- Upload progress - Real-time progress bar
- Image preview - Inline display for images
- Metadata stripping - EXIF removal from images
- Panic button - Clear all messages instantly (Ctrl+Shift+X)
- Message limit - Auto-cleanup (10, 25, 50, or 100 messages)
- Session timeout - Auto-disconnect after inactivity (5m-1h)
- Screen blur - Auto-blur on tab switch or idle
- $0 operating costs - Cloudflare Workers signaling (200k requests/day)
- Automatic fallback - Worker 1 → Worker 2 → PeerJS backup
- PWA support - Installable as desktop/mobile app
- No tracking - Zero analytics, telemetry, or user data collection
1. Visit the app:
https://ghost-chat.pages.dev
2. Create a room:
- Click "Generate chat"
- Click "Create Room"
- Copy the invite link
3. Share with peer:
- Send invite link via text, email, or any channel
- Peer clicks link and connects automatically
4. Chat privately:
- Messages travel directly between you (P2P)
- Close tab when done - everything vanishes
Clone and run locally:
# Clone repository
git clone https://github.com/teycir/ghostchat.git
cd ghostchat
# Install dependencies
npm install
# Run development server
npm run dev
# Open http://localhost:3000Test P2P locally:
# Terminal 1
npm run dev
# Browser Tab 1: localhost:3000/chat
# Click "Create Room" → Copy invite link
# Browser Tab 2: Paste invite link
# Messages sync via WebRTC P2PBuild for production:
npm run build
npm start
# Or deploy static export
npm run build
# Upload /out directory to any static hostUser A Signaling Server User B
| | |
|------ Create Room ---------->| |
|<----- Peer ID: abc123 -------| |
| | |
| |<----- Join: abc123 -----|
|<---- WebRTC Offer -----------|------ Forward Offer --->|
|<---- ICE Candidates ---------|------ Forward ICE ----->|
| | |
|<========== Direct P2P Connection ===================>|
| | |
|-- "Hello!" ------------------------------------------>|
|<----------------------------------------- "Hi!" ------|
| | |
(Signaling server no longer involved)
Key Points:
- Signaling server only helps establish connection (WebRTC SDP exchange)
- Once connected, messages flow directly peer-to-peer
- Server never sees message content
- Connection uses WebRTC DataChannels (DTLS encrypted)
- Frontend: Next.js 15, React, TypeScript
- P2P Protocol: simple-peer (primary), PeerJS (fallback)
- Signaling: Cloudflare Workers (self-hosted)
- Styling: CSS-in-JS (no external CSS frameworks)
- Storage: Memory-only (no localStorage/IndexedDB)
- Deployment: Static export (Cloudflare Pages, Vercel, Netlify)
ghostchat/
├── app/ # Next.js App Router
│ ├── page.tsx # Landing page
│ ├── chat/page.tsx # Chat page
│ └── globals.css # Global styles
├── components/ # React components
│ ├── ChatCore.tsx # Main chat logic
│ ├── MessageList.tsx # Message rendering
│ └── ...
├── lib/ # Core libraries
│ ├── peer-manager.ts # P2P connection manager
│ ├── storage.ts # Memory-only storage
│ ├── file-transfer.ts # Chunked file transfer
│ └── ...
├── public/ # Static assets
│ ├── manifest.json # PWA manifest
│ └── sw.js # Service worker
└── tests/ # Test suite
What GhostChat protects against:
- ✅ Server-side data breaches (no server storage)
- ✅ Message interception (E2E encrypted)
- ✅ Forensic analysis (memory-only, no disk traces)
- ✅ Persistent surveillance (ephemeral sessions)
- ✅ Metadata collection (no accounts, minimal logs)
What GhostChat does NOT protect against:
- ❌ Compromised devices (keyloggers, screen capture)
- ❌ Man-in-the-middle attacks (verify fingerprint!)
- ❌ IP address exposure (peers see each other's IPs - use VPN)
- ❌ Browser vulnerabilities (keep browser updated)
GhostChat is vulnerable to MITM attacks during the initial connection phase. Here's how:
1. Signaling Server Compromise
- The Cloudflare Worker facilitates WebRTC handshake (SDP exchange)
- A compromised signaling server could intercept and modify:
- Session Description Protocol (SDP) offers/answers
- ICE candidates (connection endpoints)
- Encryption keys during negotiation
- Result: Attacker establishes two separate connections (A↔Attacker↔B)
2. Invite Link Interception
- Invite links contain the peer ID:
https://ghost-chat.pages.dev/chat?peer=abc123 - If shared via insecure channel (SMS, unencrypted email, public chat):
- Attacker intercepts link and connects first
- Original recipient connects to attacker instead of intended peer
- Result: Both parties unknowingly chat with the attacker
3. Network-Level Attack
- Attacker on same WiFi/network can:
- Perform DNS spoofing to redirect traffic
- Intercept WebRTC negotiation packets
- Inject malicious ICE candidates
- Result: Traffic routed through attacker's machine
GhostChat includes a connection fingerprint system to detect MITM attacks:
🔴🟢🔵🟡 ← 4-emoji hash
123456 ← 6-digit verification code
Simple Explanation:
Think of it like a secret handshake that only works if you're talking directly:
- When you connect, both you and your peer combine your unique IDs
- This creates a fingerprint - 4 emojis like a "connection DNA"
- Both see the SAME emojis if directly connected
- If someone is in the middle, they have a different ID, so emojis won't match
Real-world analogy: You and a friend each write your names on paper, mix them together, and create a unique pattern. If you both see the same pattern, you're talking directly. If an attacker intercepts, they use their own name, creating a different pattern - you'd notice!
How it works technically:
- Both peers generate a deterministic hash from their peer IDs
- Hash is displayed as 4 emojis + 6-digit code
- If connection is direct: Both see IDENTICAL fingerprint
- If MITM present: Each sees DIFFERENT fingerprint (because attacker has different peer ID)
Example:
Direct Connection:
Alice sees: 🔴🟢🔵🟡 (hash of Alice+Bob)
Bob sees: 🔴🟢🔵🟡 (hash of Alice+Bob) ✅ MATCH
MITM Attack:
Alice sees: 🔴🟢🔵🟡 (hash of Alice+Attacker)
Bob sees: 🟣🟠⚫🔶 (hash of Bob+Attacker) ❌ MISMATCH
CRITICAL: Always verify fingerprint out-of-band
-
Verify connection fingerprint - Compare 4-emoji hash via separate channel:
- Phone call (read emojis aloud)
- Video call (show screen)
- In-person verification
- Signal/WhatsApp message (different channel than invite link)
- DO NOT verify via the same channel you shared the invite link
-
Share invite links securely
- Use end-to-end encrypted messaging (Signal, WhatsApp)
- Share in person (QR code scan)
- Avoid SMS, email, public forums
-
Use VPN - Hide your IP address from peer and network observers
-
Secure device - Keep OS and browser updated
-
Private browsing - Use incognito/private mode
-
Trusted network - Avoid public WiFi without VPN
-
Fresh session - Create new room for each conversation (don't reuse peer IDs)
- Independent security audit (planned)
- Penetration testing (planned)
- Bug bounty program (planned)
Found a vulnerability? Please report responsibly to teycir@pxdmail.net
- Node.js 18+
- npm or yarn
- Modern browser with WebRTC support
Supported Browsers:
- Chrome/Chromium (recommended)
- Firefox
- Edge
- Safari
- Brave (with shields down for this site)
Not Compatible:
- LibreWolf - WebRTC is disabled by default for privacy
- Tor Browser - WebRTC is blocked for anonymity
- Browsers with strict WebRTC blocking
Note: Privacy-focused browsers often disable WebRTC to prevent IP leaks. To use GhostChat with these browsers, you must enable WebRTC in settings (not recommended as it defeats their privacy purpose). Use mainstream browsers with a VPN instead
# Install dependencies
npm install
# Run tests
npm test
# Run E2E tests
npm run test:e2e
# Lint code
npm run lint
# Type check
npm run type-check# Optional: Custom PeerJS server
NEXT_PUBLIC_PEERJS_HOST=your-server.com
NEXT_PUBLIC_PEERJS_PORT=443
NEXT_PUBLIC_PEERJS_PATH=/myappWe welcome contributions! Please see CONTRIBUTING.md for guidelines.
Ways to contribute:
- 🐛 Report bugs
- 💡 Suggest features
- 🔧 Submit pull requests
- 📖 Improve documentation
- 🌍 Add translations
- 🎨 Design improvements
npm run build
wrangler pages deploy outnpm run build
vercel --prodnpm run build
# Upload /out directory to any static host
# Nginx, Apache, S3, etc.docker build -t ghostchat .
docker run -p 3000:3000 ghostchatMIT License - see LICENSE file for details.
TL;DR: Free to use, modify, and distribute. No warranty provided.
Need custom P2P solutions or privacy-focused applications? I build production-ready secure communication tools.
- TimeSeal (GitHub) - Cryptographic time-locked vault and dead man's switch with zero-trust encryption
- GhostChat - True P2P encrypted chat with WebRTC, no server storage, self-destruct timers
- BurpAPISecuritySuite - Professional API security testing toolkit for Burp Suite
- BurpCopyIssues - Burp Suite extension for browsing, copying, and exporting scan findings
- BurpWpsScan - WordPress security scanner for Burp Suite with WPScan API integration
- 🔒 Privacy-First Development - P2P applications, encrypted communication, zero-knowledge systems
- 🚀 Web Application Development - Full-stack development with Next.js, React, TypeScript
- 🔧 WebRTC Solutions - Real-time communication, video/audio streaming, data channels
- 🛡️ Security Tool Development - Burp extensions, penetration testing tools, automation frameworks
- 🤖 AI Integration - LLM-powered applications, intelligent automation, custom AI solutions
Get in Touch: teycirbensoltane.tn | Available for freelance projects and consulting
- simple-peer - WebRTC library
- PeerJS - Fallback P2P protocol
- Next.js - React framework
- Cloudflare Workers - Signaling infrastructure
If you find GhostChat useful, please:
- ⭐ Star this repository
- 🐦 Share on social media



