A real-time private messaging application with video/audio calls and file sharing. Create instant chat rooms with shareable links - no signup required.
- Instant Room Creation - Generate shareable room links with one click
- Real-time Messaging - Send and receive messages instantly via WebSockets
- Video & Audio Calls - Peer-to-peer calls using WebRTC
- File Sharing - Share images, videos, audio, and documents
- Typing Indicators - See when others are typing
- No Database Required - All sessions are ephemeral and in-memory
- Beautiful UI - Vibrant gradient theme with smooth animations
- Framework: Next.js 16 with App Router
- Language: TypeScript
- Real-time: Socket.io for messaging and signaling
- Video/Audio: WebRTC for peer-to-peer media streaming
- Styling: Tailwind CSS + shadcn/ui
- Animations: Framer Motion
- Node.js 18+
- npm or yarn
-
Clone the repository:
git clone https://github.com/yourusername/roomlink.git cd roomlink -
Install dependencies:
npm install
-
Start the development server:
npm run dev
-
Open http://localhost:3000 in your browser.
- Click "Create Room" on the landing page
- Enter your name to join the room
- Share the room link with others
- Start chatting, sharing files, or make video/audio calls
roomlink/
├── src/
│ ├── app/
│ │ ├── page.tsx # Landing page
│ │ ├── room/[roomId]/page.tsx # Chat room page
│ │ ├── layout.tsx # Root layout
│ │ └── globals.css # Global styles
│ ├── components/
│ │ ├── ui/ # shadcn/ui components
│ │ ├── chat/
│ │ │ ├── ChatContainer.tsx # Main chat area
│ │ │ ├── ChatInput.tsx # Message input
│ │ │ └── MessageBubble.tsx # Message display
│ │ ├── video/
│ │ │ ├── VideoCall.tsx # Video call interface
│ │ │ └── IncomingCallModal.tsx # Incoming call notification
│ │ └── shared/
│ │ ├── RoomHeader.tsx # Room header with controls
│ │ └── UsersSidebar.tsx # Users list sidebar
│ ├── hooks/
│ │ ├── useSocket.ts # Socket.io connection hook
│ │ └── useVideoCall.ts # WebRTC video call hook
│ ├── lib/
│ │ └── socket.ts # Socket.io client setup
│ └── types/
│ └── index.ts # TypeScript interfaces
├── server.ts # Custom server with Socket.io
├── package.json
├── tailwind.config.ts
└── tsconfig.json
┌─────────────────────────────────────────────────────────┐
│ Next.js Application │
├─────────────────────────────────────────────────────────┤
│ Frontend (React) │ Backend (Custom Server) │
│ ├── Landing Page │ ├── Socket.io Server │
│ ├── Room Page │ ├── Room Management │
│ ├── Chat Components │ └── WebRTC Signaling │
│ ├── Video Call │ │
│ └── File Sharing │ │
├─────────────────────────────────────────────────────────┤
│ In-Memory Storage │
│ rooms: Map<roomId, { users, messages, createdAt }> │
└─────────────────────────────────────────────────────────┘
- User clicks "Create Room"
- Server generates a unique room ID (format:
xxx-xxx-xxx) - User is redirected to the room page
- Room exists in memory until all users leave
- Messages are sent via Socket.io events
- Server broadcasts messages to all room participants
- Files are converted to base64 and sent as data URLs
- Caller initiates call via Socket.io
- Receiver gets incoming call notification with ringtone
- On accept, WebRTC peer connection is established
- ICE candidates are exchanged via Socket.io (signaling)
- Media streams flow directly peer-to-peer
| Event | Description |
|---|---|
join-room |
Join a chat room |
leave-room |
Leave current room |
send-message |
Send text or file message |
typing |
User started typing |
stop-typing |
User stopped typing |
initiate-call |
Start a video/audio call |
accept-call |
Accept incoming call |
reject-call |
Reject incoming call |
end-call |
End active call |
webrtc-offer |
Send WebRTC offer |
webrtc-answer |
Send WebRTC answer |
webrtc-ice-candidate |
Send ICE candidate |
| Event | Description |
|---|---|
room-users |
List of users in room |
user-joined |
New user joined |
user-left |
User left room |
new-message |
New message received |
user-typing |
User is typing |
user-stop-typing |
User stopped typing |
call-initiated |
Incoming call notification |
call-accepted |
Call was accepted |
call-rejected |
Call was rejected |
call-ended |
Call ended |
webrtc-offer |
Received WebRTC offer |
webrtc-answer |
Received WebRTC answer |
webrtc-ice-candidate |
Received ICE candidate |
Contributions are welcome! Here's how you can help:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Run linting:
npm run lint - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
- UI/UX Improvements - Enhance the user interface
- New Features - Screen sharing, message reactions, etc.
- Bug Fixes - Fix any issues you find
- Documentation - Improve docs or add examples
- Testing - Add unit or integration tests
- Performance - Optimize for better performance
- Use TypeScript for type safety
- Follow the existing code patterns
- Use functional components with hooks
- Keep components small and focused
| Variable | Description | Default |
|---|---|---|
PORT |
Server port | 3000 |
NODE_ENV |
Environment mode | development |
| Script | Description |
|---|---|
npm run dev |
Start development server |
npm run build |
Build for production |
npm start |
Start production server |
npm run lint |
Run ESLint |
- No Persistence - Messages are lost when room is empty
- Two Users Max for Calls - Video/audio calls work best with 2 users
- File Size Limit - Maximum 10MB per file
- Browser Support - Requires modern browser with WebRTC support
- Screen sharing
- Message reactions
- Room passwords
- Message persistence (optional)
- Multi-party video calls
- End-to-end encryption
- Mobile app (React Native)
This project is licensed under the MIT License - see the LICENSE file for details.
- shadcn/ui for beautiful UI components
- Socket.io for real-time communication
- Framer Motion for animations
Made with love by contributors worldwide