Privacy-first anonymous P2P chat with ephemeral messaging, AI assistance, and cross-device notifications
A monochromatic dark mode chat platform optimized for Cloudflare with D1 Database, Workers AI, and polling-based real-time updates. No WebSocket infrastructure required.
- No Sign-Up: Join instantly with any username
- Code-Based Rooms: Share 6-character codes to invite
- Auto-Delete: All messages expire after 1 hour
- Anonymous Sessions: No persistent user tracking
- Local-First: Preferences stored in browser only
- Polling Updates: 2-second interval, no WebSocket needed
- Typing Indicators: See when others are composing
- Message Editing: Edit with "edited" badge
- Direct Messages: Hover over usernames for ephemeral DM overlay
- Online Presence: See active users in real-time
- GIF Integration: Giphy API with search and trending
- Image Sharing: Share via URL, client-side rendering
- IsraelGPT AI: Mention @israelgpt, @bigyahu, @israel, or @netanyahu
- Timestamps: Context-aware time display
- Save Messages: Clip others' messages to personal library
- Visual Indicators: See clip counts on messages
- Persistent Storage: Clips survive 1-hour expiry
- Easy Management: View and organize in sidebar
- Local Notification Server: Node.js process for cross-device delivery
- Works When Tab Closed: Get notified even when not active
- Customizable: Control what triggers notifications
- ChromeOS Compatible: Full native support
- Monochromatic Theme: Pure grayscale palette
- Dark Mode Default: Easy on eyes, #0a0a0a to #ffffff
- Ghost UI: Transparent elements with subtle borders
- Minimal & Elegant: Focus on content, not chrome
- Node.js 18+
- pnpm (or npm)
- Cloudflare account
- Wrangler CLI:
npm install -g wrangler
pnpm install# Login to Cloudflare
wrangler login
# Create D1 Database
wrangler d1 create echo-db
# Copy the database ID and paste it into wrangler.toml
# Run migrations
pnpm db:migrate# Start Next.js dev server
pnpm dev
# In another terminal, start notification server (optional)
pnpm notifyVisit http://localhost:3000 🎉
# Build and deploy
pnpm cf:deploy
# Or push to GitHub and connect via Cloudflare Pages dashboardSee CLOUDFLARE_SETUP_GUIDE.md for detailed deployment instructions.
┌─────────────────────────────────────────────────────┐
│ Next.js 16 Application │
│ (React 19 + Server Components) │
└───────────────────┬─────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ Cloudflare Workers (Edge) │
│ API Routes (Edge Runtime) │
└──┬─────────┬──────────┬──────────┬──────────────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌────────┐ ┌──────┐ ┌────────┐ ┌──────────────┐
│ D1 │ │Workers│ │ Giphy │ │Local Notify │
│Database│ │ AI │ │ API │ │ Server │
│(SQLite)│ │(Llama)│ │(Proxy) │ │ (Node.js) │
└────────┘ └──────┘ └────────┘ └──────────────┘
- ✅ Cloudflare-Friendly: No persistent connection infrastructure
- ✅ Simpler Deployment: Just deploy to Cloudflare Pages
- ✅ Universal Compatibility: Works everywhere, no connection issues
- ✅ Battery-Efficient: Less resource usage on mobile
- ✅ Automatic Reconnection: No connection management needed
- ✅ Still Real-Time: 2-second polling feels instant
| Document | Description |
|---|---|
| FEATURES.md | Complete feature documentation with code examples |
| CLOUDFLARE_SETUP_GUIDE.md | Step-by-step Cloudflare deployment guide |
| ARCHITECTURE.md | System design and technical architecture |
| QUICK_START.md | Getting started guide |
| USAGE_GUIDE.md | User guide for end users |
| IMPLEMENTATION_SUMMARY.md | Implementation details and decisions |
All messages automatically expire after 1 hour:
- Message created with
expires_attimestamp - Visible and editable for 1 hour
- Cron job runs every 10 minutes to cleanup
- After 1 hour: permanently deleted
- Exception: Clipped messages persist in clips table
Powered by Cloudflare Workers AI (Llama 2 7B):
User: @israelgpt explain quantum computing
IsraelGPT: Quantum computing uses quantum bits (qubits) that can exist in
multiple states simultaneously, enabling parallel processing...
Trigger with: @israelgpt, @bigyahu, @israel, or @netanyahu
Lightweight Node.js server for cross-device notifications:
# Start server (port 3001)
pnpm notify
# Server polls API for new messages
# Shows notifications even when tab is closed
# No cloud service neededCreate → Active (1 hour) → Expired → Auto-Deleted
↓
Clip → Persists in clips table (survives expiry)
- Next.js 16: React framework with App Router
- React 19: Latest React with Server Components
- Tailwind CSS: Utility-first styling
- shadcn/ui: Radix UI component primitives
- TypeScript: Type safety
- Cloudflare Workers: Edge API routes
- D1 Database: SQLite at the edge
- Workers AI: Llama 2 7B model
- Cron Triggers: Automatic cleanup
- Giphy: GIF search and trending (proxied)
- Polling: 2-second interval updates
- Local Server: Node.js notification server
echo/
├── app/
│ ├── api/
│ │ ├── rooms/route.ts # Create/get rooms
│ │ ├── messages/route.ts # CRUD messages
│ │ ├── poll/route.ts # Polling endpoint
│ │ ├── typing/route.ts # Typing indicators
│ │ ├── join/route.ts # Join room
│ │ ├── giphy/route.ts # Giphy proxy
│ │ └── clips/route.ts # Message clipping
│ ├── room/[code]/page.tsx # Chat room page
│ ├── page.tsx # Home (join/create)
│ ├── layout.tsx # Root layout
│ └── globals.css # Theme & styles
├── components/
│ ├── chat-interface.tsx # Main chat UI
│ ├── message-bubble.tsx # Message display
│ ├── chat-input.tsx # Input with media
│ ├── typing-indicator.tsx # Typing animation
│ ├── user-hover-card.tsx # Hover for DM
│ ├── direct-message-overlay.tsx # DM interface
│ ├── clips-library.tsx # Saved messages
│ ├── gif-picker.tsx # GIF selection
│ └── ui/ # shadcn components
├── hooks/
│ ├── use-polling.ts # Polling hook
│ └── use-mobile.tsx # Responsive hook
├── lib/
│ ├── types.ts # TypeScript types
│ ├── chat-utils.ts # Helper functions
│ ├── d1-client.ts # D1 operations
│ └── notification-service.ts # Notifications
├── notification-server/
│ └── server.js # Local notify server
├── scripts/
│ └── setup-d1-database.sql # Database schema
├── wrangler.toml # Cloudflare config
└── next.config.ts # Next.js config
In hooks/use-polling.ts:
usePolling({
roomCode,
userId,
interval: 2000 // Change to 1000 (faster) or 5000 (slower)
})In wrangler.toml:
[vars]
MESSAGE_EXPIRY_HOURS = "2" # Change from 1 to any numberIn app/globals.css:
:root {
--background: 0 0% 4%; /* Darker: 2%, Lighter: 8% */
--foreground: 0 0% 95%; /* Text brightness */
--border: 0 0% 18%; /* Border visibility */
}- Visit home page
- Click "Create Room"
- Optionally set custom code
- Enter username
- Share room code
- ✅ Send text messages
- ✅ Share an image URL
- ✅ Search and send GIFs
- ✅ Mention @israelgpt for AI response
- ✅ Edit your messages
- ✅ Clip someone's message
- ✅ Hover over username for DM
- ✅ See typing indicators
- ✅ Watch messages expire after 1 hour
- Time to Interactive: < 2s
- First Contentful Paint: < 1s
- Message Latency: ~2s (polling interval)
- Global Edge: < 50ms API responses
- Bundle Size: < 300KB gzipped
- Edge-first architecture
- D1 database at edge locations
- Indexed SQL queries
- Code splitting
- Image lazy loading
- Debounced typing indicators
- ✅ Chrome/Edge 90+
- ✅ Firefox 88+
- ✅ Safari 14+
- ✅ Mobile browsers
- ✅ ChromeOS (full notification support)
- Anonymous sessions (no accounts)
- Auto-delete after 1 hour
- No tracking or analytics
- Session-based user IDs only
- Local storage for preferences
- Parameterized SQL queries (prevent injection)
- Input sanitization (XSS protection)
- HTTPS enforced
- CORS configuration
- Rate limiting ready (optional)
# Development
pnpm dev # Start Next.js dev server
pnpm notify # Start notification server
# Database
pnpm db:migrate # Run D1 migrations
pnpm db:shell # Open D1 shell
# Deployment
pnpm build # Build for production
pnpm cf:deploy # Deploy to Cloudflare Pages
pnpm cf:dev # Test with Cloudflare locally
# Utilities
pnpm lint # Run ESLint
pnpm type-check # TypeScript validation
pnpm clean # Clean build artifacts- Anonymous code-based rooms
- Ephemeral messaging (1-hour expiry)
- Message clipping
- Polling-based real-time updates
- GIF integration (Giphy)
- Image sharing
- IsraelGPT AI assistant
- Typing indicators
- Message editing
- Direct message overlays
- Local notification server
- Monochromatic dark theme
- End-to-end encryption
- Voice messages
- File sharing
- Message reactions
- Threading/replies
- Room passwords
- Custom expiry times
- Native mobile apps
- Multiple AI models
- Advanced analytics (anonymous)
Contributions welcome! Please:
- Fork the repository
- Create feature branch:
git checkout -b feature/amazing - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing - Open Pull Request
See CONTRIBUTING.md for guidelines.
MIT License - see LICENSE file.
Built with:
- Next.js - React framework
- Tailwind CSS - Styling
- shadcn/ui - UI components
- Cloudflare - Edge platform
- Giphy - GIF integration
- Documentation: See
/docsfolder - Issues: GitHub Issues
- Discussions: GitHub Discussions
echo. - Ephemeral messaging for the privacy-conscious web.
Made with ♥ for anonymous, temporary conversations.