Technology stack
The application leverages the following core technologies:- Frontend
- Backend
- Deployment
- Next.js 16 with App Router for the UI layer
- React 19 for component architecture
- TanStack Query for data fetching and caching
- @upstash/realtime client for WebSocket connections
System architecture
The application follows a hybrid architecture where Next.js handles routing and rendering, while Elysia manages the API layer.Frontend layer
The frontend uses Next.js App Router with client components for interactive features:src/app/page.tsx
@elysiajs/eden) provides full type inference from backend to frontend:
src/lib/client.ts
Backend layer
Elysia runs within Next.js API routes, providing a lightweight, type-safe backend:src/app/api/[[...slugs]]/route.ts
Room routes
Room routes
POST /api/room/create- Create a new roomGET /api/room/ttl- Get remaining TTL for a roomDELETE /api/room- Manually destroy a room
Message routes
Message routes
POST /api/messages- Send a message to a roomGET /api/messages- Fetch message history for a room
Request flow
Creating a room
- User clicks “Create Room” on the home page
- Frontend calls
client.room.create.post() - Elysia handler generates a
nanoid()for the room ID - Redis hash
meta:{roomId}is created with empty connected array - TTL of 600 seconds (10 minutes) is set on the meta key
- Room ID is returned and user is redirected to
/room/{roomId}
Joining a room
- User navigates to
/room/{roomId}URL - Next.js middleware intercepts the request:
src/proxy.ts
- If the room exists and has space, a token is generated and stored in an HTTP-only cookie
- Token is added to the
connectedarray in Redis - User gains access to the room page
Sending messages
- User types a message and presses Enter or clicks Send
- Frontend calls
client.messages.post()with sender name and text - Auth middleware validates the token from cookies:
src/app/api/[[...slugs]]/auth.ts
- Message is added to Redis list
messages:{roomId}usingrpush - Realtime event is emitted to all connected clients:
src/app/api/[[...slugs]]/route.ts
- All clients receive the WebSocket event and refetch messages
The auth token is included in stored messages but only returned to the message author, enabling the “YOU” label in the UI.
Authentication model
Authentication is cookie-based with randomly generated tokens:- Tokens are created using
nanoid()for cryptographic randomness - Stored in HTTP-only cookies for security
- Cookie settings:
- Tokens are validated on every API request via the
AuthMiddleware - Maximum 2 tokens (users) per room
TTL and expiry management
All room data is ephemeral with automatic expiration:- Initial TTL is set when the room is created
- All related keys (
meta:{roomId},messages:{roomId}) inherit the same TTL - When new messages are sent, TTL is synchronized:
src/app/api/[[...slugs]]/route.ts
- Frontend polls TTL every few seconds and displays countdown timer
- When TTL reaches 0, Redis automatically deletes all keys
- Users are redirected when the timer expires
Rooms can also be manually destroyed by clicking the “DESTROY NOW” button, which immediately deletes all Redis keys and broadcasts a
chat.destroy event.