A real-time collaborative coding interview platform built with React, Express.js, and Socket.io. This application allows multiple users to edit code simultaneously with live synchronization and execute JavaScript code safely in the browser.
- Create Shareable Sessions: Generate unique session links for interviews
- Real-time Collaborative Editing: All connected users can edit code simultaneously
- Live Synchronization: Code changes sync instantly across all participants
- Syntax Highlighting: Support for multiple programming languages (JavaScript, TypeScript, Python, Java, C++, Go, Ruby, PHP)
- Safe Code Execution: Execute JavaScript code in browser using Web Workers with 5-second timeout
- Participant Management: See who's connected to the session in real-time
- Monaco Editor: Industry-standard code editor (VS Code's editor)
- Modern UI: Built with Tailwind CSS and dark theme
- React 18 - UI framework
- Vite - Build tool and dev server
- TypeScript - Type safety
- Monaco Editor - Code editor component
- Socket.io Client - Real-time communication
- React Router - Routing
- Tailwind CSS - Styling
- Express.js - Web server
- Socket.io - WebSocket server for real-time features
- TypeScript - Type safety
- UUID - Session ID generation
- In-memory storage - Session management
coding-interview-platform/
├── frontend/ # React frontend
│ ├── src/
│ │ ├── components/ # React components
│ │ ├── services/ # Socket.io and code execution services
│ │ ├── hooks/ # Custom React hooks
│ │ └── utils/ # Constants and utilities
│ └── package.json
├── backend/ # Express.js backend
│ ├── src/
│ │ ├── services/ # Session management and socket handlers
│ │ ├── routes/ # REST API routes
│ │ └── types/ # TypeScript types
│ └── package.json
├── shared/ # Shared types between frontend and backend
│ └── types.ts
└── package.json # Root package.json for running both servers
- Node.js (v18 or higher)
- npm or yarn
-
Clone the repository
git clone <repository-url> cd coding-interview-platform
-
Install all dependencies
npm run install:all
This command installs dependencies for the root, frontend, and backend.
Run both frontend and backend concurrently:
npm run devThis will start:
- Backend: http://localhost:3000
- Frontend: http://localhost:5173
The frontend is configured with a proxy to forward API requests to the backend.
Run frontend only:
npm run dev:frontendRun backend only:
npm run dev:backend-
Build the frontend:
npm run build
-
Start the backend:
npm start
- Open the application at http://localhost:5173
- Click "Create New Session"
- You'll be redirected to a unique session URL (e.g.,
/session/abc-123-def) - Share this URL with candidates
- Open the application at http://localhost:5173
- Enter the session ID in the "Join an Existing Interview" field
- Click "Join Session"
- Code Editing: Type in the Monaco Editor - changes sync in real-time
- Language Selection: Choose from the language dropdown (syntax highlighting only)
- Run Code: Click "Run Code" to execute JavaScript code
- Share Link: Copy the session URL to invite more participants
- View Participants: See who's connected in the right sidebar
- Leave Session: Click "Leave" to exit the session
Client Server
│ │
├─ join-session(sessionId) ────>│
│<──── session-state ───────────┤ (current code + participants)
│ │
├─ code-change(code) ──────────>│
│ ├─ Broadcast to others
│<──── code-update ─────────────┤
│ │
│ disconnect │
│<──── participant-left ────────┤
-
SessionManager - Manages in-memory session storage
- Creates unique session IDs using UUID v4
- Stores session code, language, and participants
- Cleans up expired sessions (24 hours of inactivity)
-
SocketHandler - Handles WebSocket events
- join-session: Add user to session room
- code-change: Broadcast code changes
- language-change: Broadcast language changes
- disconnect: Remove user from session
-
useCollaborativeEditor Hook - Manages collaborative editing
- Prevents infinite update loops using
isRemoteChangeflag - Handles real-time synchronization
- Manages participant list updates
- Prevents infinite update loops using
-
CodeExecutor - Safe code execution
- Creates new Web Worker for each execution
- 5-second timeout to prevent infinite loops
- Captures console.log output
- Terminates worker after execution
-
POST /api/sessions- Create a new session- Response:
{ success: true, data: { sessionId, code, language } }
- Response:
-
GET /api/sessions/:id- Get session details- Response:
{ success: true, data: { sessionId, code, language, participantCount, ... } }
- Response:
-
GET /api/health- Health check- Response:
{ success: true, data: { status, timestamp, sessions } }
- Response:
Client → Server:
join-session- Join a session roomcode-change- Send code updatelanguage-change- Change programming language
Server → Client:
session-state- Initial session statecode-update- Code updated by another userlanguage-update- Language changedparticipant-joined- New user joinedparticipant-left- User left sessionerror- Error message
Backend (optional):
PORT- Server port (default: 3000)CLIENT_URL- Frontend URL for CORS (default: http://localhost:5173)
Frontend (optional):
VITE_API_URL- Backend API URL (default: http://localhost:3000)VITE_SOCKET_URL- Socket.io URL (default: http://localhost:3000)
The application includes comprehensive integration tests for both frontend and backend.
Run all tests (backend + frontend):
npm testRun backend tests only:
npm run test:backend
# OR
cd backend && npm testRun frontend tests only:
npm run test:frontend
# OR
cd frontend && npm testWatch mode (auto-rerun on changes):
npm run test:watchGenerate coverage reports:
npm run test:coverageCoverage reports will be generated in:
- Backend:
backend/coverage/ - Frontend:
frontend/coverage/
Located in backend/src/tests/
-
API Integration Tests (api.test.ts)
- REST endpoint testing (GET, POST)
- Session creation and retrieval
- Health check endpoint
- Error handling (404, 400)
- Concurrent session creation
-
SessionManager Unit Tests (sessionManager.test.ts)
- Session CRUD operations
- Participant management (add/remove)
- Code and language updates
- Session existence checks
-
Socket.io Integration Tests (socket.test.ts)
- WebSocket connection handling
- join-session event and state synchronization
- code-change event broadcasting
- language-change event broadcasting
- disconnect handling
- Multi-participant collaboration
- Participant notifications
Located in frontend/src
-
HomePage Component Tests (components/tests/HomePage.test.tsx)
- UI rendering
- Session creation flow
- Session joining flow
- Input validation
- Error handling
- Loading states
-
CodeExecutor Service Tests (services/tests/codeExecutor.test.ts)
- JavaScript code execution
- console.log capture
- Return value capture
- Error handling (syntax, runtime, reference errors)
- Object and array serialization
- ES6 feature support
- Language support validation
- Backend: >80% coverage for core services and routes
- Frontend: >70% coverage for components and services
To run tests in CI/CD pipeline:
# Install dependencies
npm run install:all
# Run tests
npm test
# Check coverage
npm run test:coverageBackend (Jest):
// backend/src/__tests__/myFeature.test.ts
import { describe, it, expect } from '@jest/globals';
describe('MyFeature', () => {
it('should do something', () => {
expect(true).toBe(true);
});
});Frontend (Vitest):
// frontend/src/components/__tests__/MyComponent.test.tsx
import { render, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { MyComponent } from '../MyComponent';
describe('MyComponent', () => {
it('renders correctly', () => {
render(<MyComponent />);
expect(screen.getByText('Hello')).toBeInTheDocument();
});
});- Only JavaScript execution is supported (browser-based)
- In-memory session storage (sessions lost on server restart)
- No user authentication
- Basic conflict resolution (last-write-wins)
- More Language Support: Python (Pyodide), Java, C++ via WebAssembly
- Persistence: Redis or database for session storage
- Authentication: User accounts and profiles
- Video/Audio: WebRTC integration
- Code Review: Inline comments and annotations
- Test Cases: Built-in test runner
- AI Assistant: Code suggestions and explanations
- Recording: Session recording and playback
- Analytics: Interview metrics and insights
- Collaboration: Cursors showing other users' positions
# Kill process on port 3000
lsof -ti:3000 | xargs kill -9
# Kill process on port 5173
lsof -ti:5173 | xargs kill -9# Clean install
rm -rf node_modules frontend/node_modules backend/node_modules
npm run install:all- Check that backend is running on port 3000
- Verify CORS configuration in backend/src/server.ts
- Check browser console for connection errors
- Create component in
frontend/src/components/ - Import and use in
App.tsxor other components - Add types if needed
- Add event handler in backend/src/services/socketHandler.ts
- Add event emission in frontend/src/services/socketService.ts
- Update types in
shared/types.ts - Write tests for the new event in
backend/src/__tests__/socket.test.ts
After running automated tests, manually verify:
- Create new session generates unique URL
- Copy session URL and open in new tab/window
- Code changes in one tab appear in other tab immediately
- Participants list updates when users join/leave
- Language selector updates syntax highlighting
- Run Code button executes JavaScript and shows output
- Console.log statements appear in output panel
- Syntax errors are caught and displayed
- Infinite loops are terminated after 5 seconds
- Disconnection and reconnection preserves session state
- Multiple simultaneous edits sync correctly
MIT License
Initial Prompt for AI Implementation:
"Build an online coding interview platform with the following requirements:
Core Features:
- Create shareable links for interview sessions using unique session IDs
- Real-time collaborative code editing - all connected users can edit simultaneously
- Automatic synchronization of code changes across all connected users
- Syntax highlighting for multiple programming languages (JavaScript, Python, Java, C++, etc.)
- Safe code execution in the browser with timeout protection
Technical Requirements:
- Frontend: React with Vite, TypeScript, Monaco Editor for the code editor, Socket.io for real-time communication, Tailwind CSS for styling
- Backend: Express.js with TypeScript, Socket.io for WebSocket handling, in-memory session storage using Maps
- Use a monorepo structure with frontend/ and backend/ directories
- Real-time: Socket.io rooms for session isolation
- Code execution: Web Workers in the browser (sandboxed, 5-second timeout)
Architecture:
- Generate unique session IDs using UUID v4
- Store sessions in-memory with Map (sessionId → Session object containing code, language, participants)
- Use Socket.io rooms where each session is a separate room
- Implement last-write-wins for conflict resolution
- Debounce editor changes by 300ms to reduce network traffic
- Use a custom React hook (useCollaborativeEditor) to manage real-time editing and prevent infinite update loops
File Structure: Create approximately 35 files following this structure:
- Root: package.json (with concurrently to run both servers), .gitignore, README.md
- shared/types.ts for TypeScript types shared between frontend and backend
- backend/src: server.ts, services/ (sessionManager.ts, socketHandler.ts), routes/ (sessions.ts)
- frontend/src: main.tsx, App.tsx, components/ (HomePage, InterviewRoom, CodeEditor, OutputPanel, ParticipantsList, LanguageSelector), services/ (socketService.ts, codeExecutor.ts), hooks/ (useCollaborativeEditor.ts)
UI Layout:
- Home page with 'Create New Interview' and 'Join Interview' options
- Interview room with Monaco Editor (70% width), participants sidebar with language selector and share link, and output panel below (30% height)
- Dark theme (vs-dark for Monaco Editor)
Socket.io Events:
- join-session: Client joins a session room
- session-state: Server sends current code/participants to newly joined client
- code-change: Client sends code update to server
- code-update: Server broadcasts code changes to other clients
- language-change: Client changes programming language
- participant-joined/participant-left: Notify all clients of participant changes
Please implement all files needed for this platform to work end-to-end."
Contributions are welcome! Please feel free to submit a Pull Request.
For questions or support, please open an issue on GitHub.