A modern, real-time interview collaboration platform built with React and Node.js. Practice coding problems, run code instantly, and conduct live interview sessions with video + chat in one place.
- Features
- Tech Stack
- Project Structure
- Prerequisites
- Installation and Setup
- Environment Variables
- Running the Application
- Project Architecture
- API Endpoints
- Usage Guide
- Development Notes
- Contributing
- Troubleshooting
- π Authentication with Clerk
- πΉ Real-time video sessions powered by Stream Video
- π¬ Live in-session chat via Stream Chat
- π₯ Session lifecycle: create, join, track, and end interview rooms
- π» Multi-language code execution through JDoodle (JavaScript, Python, Java, C++)
- π§© Problem practice pages with starter code and output validation
- π Dashboard with active sessions and recent completed sessions
- β‘ Fast and responsive UI built with React, TailwindCSS, and DaisyUI
- βοΈ Framework: React 19 + Vite
- π¨ Styling: TailwindCSS + DaisyUI
- π§ Routing: React Router
- π Data Fetching: TanStack React Query
- π Code Editor: Monaco Editor
- π‘ API Client: Axios
- π₯ Video SDK: Stream Video React SDK
- π¬ Chat SDK: Stream Chat React
- π Notifications: React Hot Toast
- π₯ Runtime: Node.js
- π Framework: Express 5
- π Database: MongoDB + Mongoose
- π Auth Integration: Clerk Express middleware
- π₯ Chat/Video Infra: Stream Chat + Stream Node SDK
- βοΈ Event Processing: Inngest
- π CORS + JSON APIs: Express middlewares
- π§ Dev Tooling: Nodemon + dotenv
REMOTE INTERVIEW PLATFORM/
βββ backend/
β βββ src/
β β βββ server.js
β β βββ controllers/
β β β βββ chatController.js
β β β βββ sessionController.js
β β βββ routes/
β β β βββ chatRoutes.js
β β β βββ executeRoutes.js
β β β βββ sessionRoutes.js
β β βββ middleware/
β β β βββ protectRoute.js
β β βββ lib/
β β β βββ db.js
β β β βββ env.js
β β β βββ inngest.js
β β β βββ stream.js
β β βββ models/
β β βββ Session.js
β β βββ User.js
β βββ package.json
β
βββ frontend/
β βββ src/
β β βββ App.jsx
β β βββ main.jsx
β β βββ api/
β β β βββ sessions.js
β β βββ components/
β β βββ hooks/
β β β βββ useSessions.js
β β β βββ useStreamClient.js
β β βββ pages/
β β β βββ HomePage.jsx
β β β βββ DashboardPage.jsx
β β β βββ ProblemsPage.jsx
β β β βββ ProblemPage.jsx
β β β βββ SessionPage.jsx
β β βββ lib/
β β βββ axios.js
β β βββ stream.js
β β βββ piston.js
β βββ package.json
β
βββ package.json
- Node.js 18+
- npm 9+
- MongoDB Atlas (or local MongoDB)
- Clerk project (publishable + secret keys)
- Stream project (API key + secret)
- JDoodle API credentials
- Inngest keys
From project root:
npm run buildThis command:
- Installs backend dependencies
- Installs frontend dependencies
- Builds frontend for production
npm install --prefix backend
npm install --prefix frontendPORT=5001
NODE_ENV=development
DB_URI=mongodb+srv://<username>:<password>@<cluster>/<dbName>
INNGEST_EVENT_KEY=<inngest_event_key>
INNGEST_SIGNING_KEY=<inngest_signing_key>
STREAM_API_KEY=<stream_api_key>
STREAM_API_SECRET=<stream_api_secret>
CLERK_PUBLISHABLE_KEY=<clerk_publishable_key>
CLERK_SECRET_KEY=<clerk_secret_key>
CLIENT_URL=http://localhost:5173
JOODLE_CLIENT_ID=<jdoodle_client_id>
JOODLE_CLIENT_SECRET=<jdoodle_client_secret>VITE_CLERK_PUBLISHABLE_KEY=<clerk_publishable_key>
VITE_STREAM_API_KEY=<stream_api_key>
VITE_API_UPL=http://localhost:5001/apiImportant: The frontend uses VITE_API_UPL in code. Keep this exact name unless you also refactor the source.
Terminal 1 (backend):
npm run dev --prefix backendTerminal 2 (frontend):
npm run dev --prefix frontendURLs:
- Frontend: http://localhost:5173
- Backend health: http://localhost:5001/health
npm run build
npm startThe backend serves static frontend assets when NODE_ENV=production.
- π Authentication
- Clerk provider wraps the app and protects private routes.
- Unauthenticated users stay on home/sign-in flow.
- π Dashboard and Sessions
- Users create interview sessions with problem + difficulty.
- Active and recent sessions are fetched with React Query.
- π₯ Live Session Experience
- Session page initializes Stream Video call + chat channel.
- Host and participant collaborate in real time.
- π» Code Execution
- Code editor sends language + script to backend execution API.
- Output panel displays run results and errors.
- π Request Protection
- Protected routes use Clerk auth via middleware.
- Middleware resolves Clerk user to MongoDB user document.
- π₯ Session Lifecycle
- Create session: persists to MongoDB + creates Stream call/channel.
- Join session: validates capacity and adds participant + channel member.
- End session: host-only action, tears down Stream resources and closes session.
- βοΈ User Sync
- Inngest handles Clerk user create/delete events.
- Stream user records are upserted/deleted accordingly.
| Method | Endpoint | Description |
|---|---|---|
| GET | /health |
Service health check |
| Method | Endpoint | Description |
|---|---|---|
| POST | / |
Create a new interview session |
| GET | /active |
Get active sessions |
| GET | /my-recent |
Get current user's recent completed sessions |
| GET | /:id |
Get session by ID |
| POST | /:id/join |
Join an active session |
| POST | /:id/end |
End a session (host only) |
| Method | Endpoint | Description |
|---|---|---|
| GET | /token |
Generate Stream token for authenticated user |
| Method | Endpoint | Description |
|---|---|---|
| POST | /execute |
Execute submitted code via JDoodle |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/inngest |
Inngest event handler endpoint |
- Open the app and authenticate through Clerk.
- Navigate to Dashboard.
- Choose a problem and difficulty.
- Create room and enter session.
- Open a session link (
/session/:id) from host. - If seat is available, you join as participant.
- Discuss on video call.
- Exchange messages in chat.
- Solve in the code editor and run code instantly.
- Host can end the interview room.
- Session is marked completed and shown in recent history.
npm run build-> install both apps + build frontendnpm start-> start backend app
npm run dev-> start backend with nodemonnpm start-> start backend with node
npm run dev-> Vite dev servernpm run build-> production buildnpm run preview-> preview built appnpm run lint-> run ESLint
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m "Add amazing feature") - Push branch (
git push origin feature/amazing-feature) - Open a pull request
- Confirm
backend/.envexists and required keys are present. - Verify MongoDB URI and credentials.
- Check if port is already in use.
- Confirm backend is running on configured port.
- Verify
VITE_API_UPLinfrontend/.env. - Ensure
CLIENT_URLin backend matches frontend origin.
- Validate Stream API key/secret in backend.
- Validate frontend
VITE_STREAM_API_KEY. - Ensure users are authenticated before entering session.
- Verify JDoodle client ID/secret values.
- Check submitted language is supported.
ISC
Built with focus for technical interview collaboration. Happy coding! π
