Ephemeral peer-to-peer messaging for the haunted web
A real-time WebRTC chat application where messages fade like ghosts,
screens shake with supernatural force, and whispers echo through the void.
π Live Demo β’ Built with Kiro β’ Architecture β’ Why It's Unique
GhostNet is a Halloween-themed, real-time chat application that demonstrates the power of pure WebRTC mesh networking. Built for the Kiro Halloween Hackathon, it showcases how AI-assisted development can produce production-ready, architecturally sound applications.
- Ghost Messages β Ephemeral messages that materialize and fade away after 5 seconds
- Persistent Messages β Leave your mark in the chat history
- Screen Shake β Rattle every connected user's display with supernatural force
- Whisper Sounds β Synthesized ghostly audio that echoes across all peers
- Zero Friction β No accounts, no passwords, just pick a ghost name and haunt
Beneath the spooky surface lies serious WebRTC engineering:
- True peer-to-peer mesh network (no message relay servers)
- WebSocket signaling for connection establishment only
- Shared TypeScript types across frontend and backend
- Production deployment on Netlify + Render
Open in multiple browser tabs or share with friends to experience the full P2P magic. No sign-up required.
GhostNet was developed with Kiro as a full engineering partnerβnot just a code assistant, but a collaborator that shaped architecture, debugged complex systems, and refined the user experience.
| Development Phase | How Kiro Contributed |
|---|---|
| π Spec Generation | Created structured requirements documents with acceptance criteria, breaking down the entire project into implementable tasks |
| ποΈ Architecture Planning | Designed the signaling server, WebRTC peer manager, and React component hierarchy with repo-wide awareness |
| π§ Signaling System Debug | Diagnosed WebSocket reconnection issues, intentional disconnect handling, and error state management |
| π§ Repo-Wide Reasoning | Maintained consistency across frontend, backend, and shared typesβunderstanding how changes in one file affect others |
| π¨ Vibe Coding for UI | Refined the Halloween aesthetic through iterative promptsβanimations, color schemes, responsive layouts |
| π‘ WebRTC State Management | Implemented the peer connection lifecycle, ICE candidate exchange, and data channel message handling |
| β‘ Development Velocity | Accelerated implementation from concept to production deployment in a fraction of typical development time |
-
Complex Distributed System β WebRTC mesh networking requires coordinating signaling, ICE negotiation, and peer state across multiple browsers. Kiro handled this complexity with architectural clarity.
-
Full-Stack Type Safety β Shared TypeScript definitions between frontend and backend, with Kiro ensuring protocol consistency across the codebase.
-
Production-Ready Code β Not a prototype. Deployed, tested, and handling edge cases like browser autoplay policies, reconnection logic, and graceful disconnection.
-
Iterative Refinement β From initial scaffolding to final polish, Kiro adapted to feedback and improved the implementation across dozens of iterations.
Kiro generated comprehensive requirements using Kiro Specs, producing structured documents that defined:
- User stories for ghost name entry and lobby joining
- Acceptance criteria for message types (ghost vs. persistent)
- Technical requirements for WebRTC peer connections
- Edge cases for disconnection and reconnection
.kiro/specs/ghostnet/
βββ requirements.md # Functional requirements & acceptance criteria
βββ design.md # Technical architecture & component design
βββ tasks.md # Implementation checklist
Kiro designed a clean separation of concerns:
- Signaling Server β Minimal WebSocket server for peer discovery and SDP exchange
- Peer Manager β Client-side WebRTC connection management
- Message Protocol β Typed message formats shared between all components
- React Hooks β
useGhostNetencapsulating all P2P logic
Development proceeded through continuous dialogue with Kiro:
- Initial scaffolding of frontend and backend
- WebRTC data channel implementation
- Signaling protocol refinement
- Error handling and reconnection logic
- Feature additions (shake, whisper, persistent messages)
Kiro guided test design with property-based thinking:
- Message validation edge cases
- Ghost name constraints
- Signaling protocol correctness
- WebRTC state transitions
The Halloween aesthetic emerged through Vibe Codingβiterative prompts that refined:
- Color palette (ghost purple, neon green, dark backgrounds)
- CSS animations (floating ghost, message fade, screen shake)
- Responsive layout adjustments
- Audio synthesis for whisper effects
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β GhostNet System Architecture β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββββββ βββββββββββββββββββ β
β β Browser A β β Browser B β β
β β βββββββββββββ β β βββββββββββββ β β
β β β React β β β β React β β β
β β β Frontend β β β β Frontend β β β
β β βββββββ¬ββββββ β β βββββββ¬ββββββ β β
β β β β β β β β
β β βββββββ΄ββββββ β WebRTC DataChannel β βββββββ΄ββββββ β β
β β β Peer ββββΌββββββββββββββββββββββββββΌββΊβ Peer β β β
β β β Manager β β (Direct P2P - No β β Manager β β β
β β βββββββ¬ββββββ β Server Involved) β βββββββ¬ββββββ β β
β β β β β β β β
β ββββββββββΌβββββββββ ββββββββββΌβββββββββ β
β β β β
β β WebSocket WebSocket β β
β β (Signaling Only) (Signaling Only) β
β β β β
β ββββββββββββββββ ββββββββββββββββββββββ β
β β β β
β βΌ βΌ β
β ββββββββββββββββββββ β
β β Signaling Server β β
β β (Render.com) β β
β β β β
β β β’ Lobby Manager β β
β β β’ SDP Relay β β
β β β’ ICE Relay β β
β ββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ghostnet/
βββ frontend/ # React + TypeScript + Vite + Tailwind
β βββ src/
β β βββ components/ # UI Components
β β β βββ WelcomeScreen.tsx # Ghost name entry
β β β βββ ChatArea.tsx # Message display + shake animation
β β β βββ MessageInput.tsx # Input + action buttons
β β β βββ GhostMessage.tsx # Ephemeral message component
β β β βββ PersistentMessage.tsx# Permanent message component
β β β βββ Header.tsx # Settings + leave button
β β β βββ Sidebar.tsx # Connected ghosts list
β β βββ hooks/
β β β βββ useGhostNet.ts # Main P2P logic hook
β β βββ lib/
β β β βββ webrtc.ts # PeerManager class
β β β βββ signaling.ts # SignalingClient class
β β β βββ messages.ts # Message creation utilities
β β β βββ audio.ts # Web Audio API whisper sound
β β β βββ validation.ts # Ghost name validation
β β β βββ types.ts # Frontend type definitions
β β βββ App.tsx
β βββ package.json
β
βββ backend/ # Express + ws WebSocket Server
β βββ src/
β β βββ server.ts # HTTP + WebSocket server
β β βββ signaling.ts # Signaling message handlers
β β βββ lobby.ts # Ghost name registry
β β βββ types.ts # Backend type definitions
β βββ package.json
β
βββ shared/ # Shared TypeScript Types
β βββ types.ts # Protocol definitions
β
βββ README.md
| Layer | Technology | Purpose |
|---|---|---|
| Frontend | React 18, TypeScript, Vite | UI framework and build tooling |
| Styling | Tailwind CSS | Halloween-themed responsive design |
| Real-Time | WebRTC DataChannels | Direct P2P message delivery |
| Signaling | WebSocket (ws) | Peer discovery and SDP exchange |
| Backend | Node.js, Express | Signaling server runtime |
| Audio | Web Audio API | Synthesized whisper sounds |
| Deployment | Netlify, Render | Production hosting |
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β GhostNet Connection Flow β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β 1. User enters ghost name β
β β β
β βΌ β
β 2. Frontend connects to signaling server (WebSocket) β
β β β
β βΌ β
β 3. Server validates name, adds to lobby β
β β β
β βΌ β
β 4. Server broadcasts updated ghost list to all peers β
β β β
β βΌ β
β 5. New ghost creates WebRTC offers for each existing ghost β
β β β
β βΌ β
β 6. Offers/Answers exchanged via signaling server β
β β β
β βΌ β
β 7. ICE candidates exchanged for NAT traversal β
β β β
β βΌ β
β 8. Direct P2P DataChannels established β
β β β
β βΌ β
β 9. All messages now flow directly between browsers β
β (Signaling server no longer involved in messaging) β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Message Type | Transport | Behavior |
|---|---|---|
ghost_message |
WebRTC P2P | Appears, then fades after 5 seconds |
persistent_message |
WebRTC P2P | Remains in chat history |
shake |
WebRTC P2P | Triggers CSS shake animation on all peers |
whisper |
WebRTC P2P | Plays synthesized audio on all peers |
Welcome Screen
Enter your ghost name to join the haunted lobby
Chat Interface
Send ghost messages, persistent messages, shake screens, or whisper
Ghost Message Fading
Ephemeral messages that disappear like spirits
Kiro Specs
Requirements and design documents generated with Kiro
Vibe Coding Session
Iterative UI refinement with Kiro
Unlike typical chat applications that relay messages through servers, GhostNet establishes direct browser-to-browser connections. After the initial WebRTC handshake, the signaling server is only used for new peer discovery. All messages, shake effects, and whisper sounds travel directly between browsers with zero server involvement.
- Zero persistence β Messages exist only in browser memory
- No user accounts β Anonymous ghost names validated client-side
- No cookies or tracking β When you leave, you're gone
- Privacy by architecture β The server literally cannot store your messages
The signature feature: messages that materialize and fade away after 5 seconds. Like whispers in a haunted house, they're there and then they're not. Perfect for the Halloween theme and a genuine technical differentiator.
- Screen Shake β CSS animation triggered across all connected peers via WebRTC
- Whisper Sound β Web Audio API synthesized ghostly audio (no audio files needed)
- User Controls β Toggle effects on/off for accessibility
The theme isn't just a skinβit's integrated into the UX:
- Dark purple/green color palette with glow effects
- Floating ghost animations
- Spooky placeholder text and messaging
- Responsive design that maintains atmosphere on mobile
- Open the app
- Enter a ghost name
- Start chatting
No sign-up forms. No email verification. No password requirements. Just instant haunting.
- Node.js 18+
- npm
# Clone the repository
git clone https://github.com/AhmedAlmaghz/ghostnet.git
cd ghostnet
# Install backend dependencies
cd backend
npm install
# Install frontend dependencies
cd ../frontend
npm installTerminal 1 β Backend:
cd backend
npm run devTerminal 2 β Frontend:
cd frontend
npm run devThe frontend runs on http://localhost:5173 and automatically connects to the backend at ws://localhost:3001/ws.
# Backend tests
cd backend && npm test
# Frontend tests
cd frontend && npm test- Connect your GitHub repository to Netlify
- Configure build settings:
- Base directory:
frontend - Build command:
npm run build - Publish directory:
frontend/dist
- Base directory:
- Add environment variable:
VITE_WS_URL = wss://ghostnet-app.onrender.com/ws - Deploy
- Create a new Web Service on Render
- Connect your GitHub repository
- Configure settings:
- Root directory:
backend - Build command:
npm install && npm run build - Start command:
npm start
- Root directory:
- Deploy
| Variable | Service | Value |
|---|---|---|
VITE_WS_URL |
Netlify (Frontend) | wss://ghostnet-app.onrender.com/ws |
PORT |
Render (Backend) | Auto-configured |
This project would not exist in its current form without Kiro. From generating the initial requirements to debugging WebRTC edge cases to polishing the Halloween UI, Kiro functioned as a full engineering team:
- Architect β Designed the signaling protocol and peer management system
- Backend Engineer β Implemented the WebSocket server and lobby management
- Frontend Engineer β Built React components and the
useGhostNethook - DevOps β Guided deployment configuration for Netlify and Render
- QA Engineer β Identified edge cases and helped write tests
- UI/UX Designer β Refined the Halloween aesthetic through Vibe Coding
Kiro didn't just write codeβit understood the project holistically and made architectural decisions that a human engineer would make.
MIT License β Feel free to fork, modify, and haunt your own version.
Built with π» and Kiro AI
for the Kiro Halloween Hackathon 2024