Skip to content

GhostNet is a Halloween-themed, real-time chat application that demonstrates the power of pure WebRTC mesh networking.

License

Notifications You must be signed in to change notification settings

engrtitooo/GhostNet-App

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

29 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

GhostNet Logo

πŸ‘» GhostNet

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

Kiro Halloween Hackathon WebRTC P2P Built with Kiro


πŸŽƒ Introduction

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.

The Haunted Experience

  • 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

The Engineering Reality

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

🌐 Live Demo

Live Demo

https://ghostnet.app

Open in multiple browser tabs or share with friends to experience the full P2P magic. No sign-up required.


πŸ€– Built With Kiro AI

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.

Kiro's Role in Development

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

What Makes This a Kiro Showcase

  1. Complex Distributed System β€” WebRTC mesh networking requires coordinating signaling, ICE negotiation, and peer state across multiple browsers. Kiro handled this complexity with architectural clarity.

  2. Full-Stack Type Safety β€” Shared TypeScript definitions between frontend and backend, with Kiro ensuring protocol consistency across the codebase.

  3. Production-Ready Code β€” Not a prototype. Deployed, tested, and handling edge cases like browser autoplay policies, reconnection logic, and graceful disconnection.

  4. Iterative Refinement β€” From initial scaffolding to final polish, Kiro adapted to feedback and improved the implementation across dozens of iterations.


πŸ› οΈ How Kiro Helped Build GhostNet

Phase 1: Requirements Creation

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

Phase 2: Architecture Design

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 β€” useGhostNet encapsulating all P2P logic

Phase 3: Iterative Implementation

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)

Phase 4: Testing & Property-Based Reasoning

Kiro guided test design with property-based thinking:

  • Message validation edge cases
  • Ghost name constraints
  • Signaling protocol correctness
  • WebRTC state transitions

Phase 5: UI Refinement with Vibe Coding

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

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        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      β”‚                               β”‚
β”‚                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                β”‚
β”‚                                                                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Project Structure

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

Technology Stack

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

πŸ”„ How It Works

Connection Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     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 Protocol

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

πŸ“Έ Screenshots

Welcome Screen
Enter your ghost name to join the haunted lobby

Welcome Screen

Chat Interface
Send ghost messages, persistent messages, shake screens, or whisper

Chat Interface

Ghost Message Fading
Ephemeral messages that disappear like spirits

Ghost Message Fading

Kiro Specs
Requirements and design documents generated with Kiro

Kiro Specs

Vibe Coding Session
Iterative UI refinement with Kiro

Vibe Coding


🎯 Why GhostNet Is Unique

πŸ•ΈοΈ Pure WebRTC Mesh Network

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.

🚫 No Database, No Authentication

  • 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

πŸ‘» Ephemeral Ghost 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.

πŸ“³ Interactive Spooky Effects

  • 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

πŸŽƒ Halloween Aesthetic

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

⚑ Zero Friction User Flow

  1. Open the app
  2. Enter a ghost name
  3. Start chatting

No sign-up forms. No email verification. No password requirements. Just instant haunting.


πŸ’» Local Development

Prerequisites

  • Node.js 18+
  • npm

Quick Start

# 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 install

Running Locally

Terminal 1 β€” Backend:

cd backend
npm run dev

Terminal 2 β€” Frontend:

cd frontend
npm run dev

The frontend runs on http://localhost:5173 and automatically connects to the backend at ws://localhost:3001/ws.

Running Tests

# Backend tests
cd backend && npm test

# Frontend tests
cd frontend && npm test

πŸš€ Deployment

Frontend β€” Netlify

  1. Connect your GitHub repository to Netlify
  2. Configure build settings:
    • Base directory: frontend
    • Build command: npm run build
    • Publish directory: frontend/dist
  3. Add environment variable:
    VITE_WS_URL = wss://ghostnet-app.onrender.com/ws
    
  4. Deploy

Backend β€” Render

  1. Create a new Web Service on Render
  2. Connect your GitHub repository
  3. Configure settings:
    • Root directory: backend
    • Build command: npm install && npm run build
    • Start command: npm start
  4. Deploy

Environment Variables

Variable Service Value
VITE_WS_URL Netlify (Frontend) wss://ghostnet-app.onrender.com/ws
PORT Render (Backend) Auto-configured

πŸ™ Acknowledgments

Kiro β€” The Engineering Partner

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 useGhostNet hook
  • 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.


πŸ“„ License

MIT License β€” Feel free to fork, modify, and haunt your own version.


Built with πŸ‘» and Kiro AI
for the Kiro Halloween Hackathon 2024

Enter the Haunted Lobby β†’

About

GhostNet is a Halloween-themed, real-time chat application that demonstrates the power of pure WebRTC mesh networking.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published