Features • Architecture • Environment • Getting Started • API • Sockets • Contributing
CatfishMeet is a Next.js web client for discovering and connecting with people in real‑time video rooms. It combines Socket.IO for realtime signaling, PeerJS/WebRTC for low‑latency media, and a clean component architecture for multiple room layouts (2‑user, 3‑user, shuffle, etc.).
Production demo URL used by the client:
https://www.catfishmeet.live
- Real‑time rooms: Matchmaking via Socket.IO with JOIN/LEAVE flow
- WebRTC calls: Peer‑to‑peer media with PeerJS
- Multiple layouts: Two, three, and more‑than‑three user frames
- Media controls: Toggle camera and mic, reflect remote state
- Responsive UI: TailwindCSS + Next.js App Router
- Typed networking: Axios instance, interceptor, and helpers
src/
app/
rooms/ # Rooms page and layout
features/
rooms/
components/ # Call frames, header, controls
constants/events.ts # Socket event names (client/server)
hooks/ # useHome, useInit (media + signaling)
chat/
constants/events.ts # Chat socket events
networking/
config.ts # Axios instance
requestInterceptor.ts # Axios request interceptor
socketUtils.ts # Socket.IO client wrapper
The client maintains a Socket.IO connection for room coordination and uses PeerJS for WebRTC media between matched peers. Media state (camera/mic) is synchronized through socket events.
The client reads environment variables via Next.js config.
BASE_URL: REST base URL (e.g.https://demo.catfishmeet.live/api/v1in prod)SOCKET_URL: Socket.IO endpoint (e.g.https://demo.catfishmeet.livein prod)
See next.config.ts for defaults depending on NODE_ENV.
# Install
npm install
# Development
npm run dev
# Production build
npm run build && npm startOpen http://localhost:3000 in your browser.
REST interactions use a shared Axios instance and a small wrapper for convenience.
-
src/networking/config.tsaxiosInstance: preconfigured withbaseURL = process.env.BASE_URLrequestInterceptor: placeholder to apply headers, auth, tracing, etc.
-
src/networking/networkUtils.tsNetworkUtils.get(url, params?)NetworkUtils.post(url, data?, headers?)NetworkUtils.put(url, data?)NetworkUtils.patch(url, data, headers?)NetworkUtils.delete(url, data?)NetworkUtils.addHeader(header, value)
Example usage:
import NetworkUtils from "@/networking/networkUtils";
async function fetchSomething() {
const res = await NetworkUtils.get("/example", { page: 1 });
return res.data;
}The client wraps Socket.IO in src/networking/socketUtils.ts and exposes utility methods: emit, on, once, off, disconnect, getSocket().
Defined in src/features/rooms/constants/events.ts.
// Client -> Server
RoomEvents.client = {
JOIN_ROOM: 'join-room',
LEAVE_ROOM: 'leave-room',
TOGGLE_CAMERA: 'toggle-camera',
TOGGLE_MIC: 'toggle-mic',
STREAM_STARTED: 'stream-started',
}
// Server -> Client
RoomEvents.server = {
USER_JOINED: 'user-joined',
USER_DISCONNECTED: 'user-disconnected',
CAMERA_TOGGLED: 'camera-toggled',
MIC_TOGGLED: 'mic-toggled',
READY_TO_JOIN: 'ready-to-join',
STREAM_STARTED: 'stream-started',
}Typical flow (src/features/rooms/hooks/useHome.ts & useInit.ts):
- User clicks “Join/Next” →
JOIN_ROOMemitted withuserId - Server matches peers → emits
USER_JOINEDto other user - PeerJS connects and calls; upon receiving stream, the callee answers
- Once remote stream is received, UI updates and media toggles are synced
- Leaving/skipping emits
LEAVE_ROOM; server responds withREADY_TO_JOIN
Defined in src/features/chat/constants/events.ts.
ChatEvents.client = { SEND_MESSAGE: 'send-message' }
ChatEvents.server = { RECEIVE_MESSAGE: 'receive-message' }Media is acquired with getUserMedia and previewed locally. PeerJS is used for P2P media exchange. Camera/mic toggles both update local tracks and notify others through sockets.
Key locations:
src/features/rooms/hooks/useInit.ts: Peer setup, answering calls, remote stream handling, reconnection logicsrc/features/rooms/hooks/useHome.ts: Join/leave flows, media toggle handlers
Room frames and responsive layouts live under src/features/rooms/components/CallFram/* with variants for 2, 3, and more users, plus mobile/desktop specific views.
{
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start",
"lint": "next lint"
}Place marketing screenshots in docs/screenshots/ and link them below.
Contributions are welcome! Please:
- Fork the repo and create a feature branch
- Follow the existing code style and TypeScript patterns
- Keep components small and focused; prefer hooks for logic
- Open a PR with a clear description and screenshots where relevant
This project’s license is not yet specified. If you plan to open source, consider MIT/Apache-2.0 and add a LICENSE file.
Made with ❤️ using Next.js, Socket.IO, and WebRTC.
