A Real-Time 1v1 Competitive Programming Duel Platform where developers and competitive programmers compete head-to-head on official Codeforces problems with automated submission verification, live matchmaking, and global rankings.
π Live Client: https://code-arena-ochre.vercel.app
π‘ Live Backend API: https://codearena-backend-z759.onrender.com
CodeArena transforms solitary algorithm practice into an interactive, high-stakes competitive duel. Players can create custom rooms and share a 6-character room code, configure problem rating difficulties, and race against the clock. The backend engine continuously polls the official Codeforces REST API to automatically detect accepted verdicts (OK) in real-time.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β React 18 Single Page App β
β (Vite + Custom CSS Design System + Lucide Icons) β
βββββββββββββββββ¬ββββββββββββββββββββββββββββββ²ββββββββββββββββ
β REST API / WebSockets β JSON / Socket Events
βΌ β
βββββββββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββ
β Node.js & Express Server β
β βββ JWT Authentication & bcrypt Password Hashing β
β βββ Socket.IO Auth Middleware (JWT Handshake) β
β βββ Real-Time Duel Engine & Room State Machine β
β βββ Background Codeforces API Poller (every 5s) β
β βββ Rate-Limited Auth Routes (express-rate-limit) β
β βββ PostgreSQL Database Layer (Neon Serverless) β
βββββββββββββββββ¬ββββββββββββββββββββββββββββββ²ββββββββββββββββ
β Polling β SQL Queries
βΌ βΌ
βββββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββ
β Codeforces REST API β β PostgreSQL (Neon) β
β (Submissions & Problemset) β β (Users, Matches) β
βββββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββ
- Custom Duel Settings: Choose problem difficulty ratings (800β3500) and match durations (1β300 mins).
- Synchronized Match Lifecycle:
- Lobby (
WAITING): Host creates room and shares 6-character room code; opponent joins. - Live Duel (
ACTIVE): Codeforces problem unveiled with synchronized countdown timer. - Automated Verification: The server polls Codeforces every 5 seconds for accepted submissions (
verdict: OK). - Resolution (
FINISHED): Winner declared instantly upon solve; if timer expires without a solution, the match resolves as a Draw (winner isnull).
- Lobby (
- Rankings Table: Global top 50 rankings featuring Rank, Player, Codeforces Handle, Wins, Losses, Draws, and Matches Played.
- Profile Dashboard: Track your personal match history and competitive record.
- Customizable timed solo practice sessions with automatic Codeforces submission verification.
- Real-time handle verification via the Codeforces
user.infoAPI during registration and profile updates, with debounced inline feedback (rating, rank, and validity).
CodeArena utilizes a relational PostgreSQL schema with atomic transactions for match resolution:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β users β
βββββββββββββββββββββ¬ββββββββββββββββββββββββββββββ¬ββββββββββββββ€
β id β UUID (PK, uuid_generate_v4) β PRIMARY KEY β
β username β VARCHAR(255) β NOT NULL β
β email β VARCHAR(255) β UNIQUE β
β password_hash β VARCHAR(255) β NOT NULL β
β cf_handle β VARCHAR(255) β Codeforces β
β wins β INT β DEFAULT 0 β
β losses β INT β DEFAULT 0 β
β draws β INT β DEFAULT 0 β
β created_at β TIMESTAMP β CURRENT_TIMEβ
βββββββββββββββββββββ΄ββββββββββββββββββββββββββββββ΄ββββββββββββββ
β²
β 1:N (Player1, Player2, Winner)
βββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββ
β matches β
βββββββββββββββββββββ¬ββββββββββββββββββββββββββββββ¬ββββββββββββββ€
β id β UUID (PK, uuid_generate_v4) β PRIMARY KEY β
β room_code β VARCHAR(6) β UNIQUE β
β player1 β UUID (FK -> users.id) β NULLABLE β
β player2 β UUID (FK -> users.id) β NULLABLE β
β problem_id β VARCHAR(255) β Problem Ref β
β winner β UUID (FK -> users.id) β Winner User β
β start_time β TIMESTAMP β Start Date β
β end_time β TIMESTAMP β End Date β
β status β VARCHAR(50) β Duel Status β
βββββββββββββββββββββ΄ββββββββββββββββββββββββββββββ΄ββββββββββββββ
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
POST |
/auth/register |
Register new user account | No |
POST |
/auth/login |
Authenticate user & return JWT | No |
GET |
/auth/me |
Get authenticated player stats | Yes (JWT) |
POST |
/auth/update-cf |
Link Codeforces handle to account | Yes (JWT) |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
POST |
/create-room |
Create new duel room with custom rating/timer | Yes (JWT) |
POST |
/join-room |
Join an existing duel room via 6-character room code | Yes (JWT) |
GET |
/room/:id |
Get room configuration and participants by room code | Yes (JWT) |
GET |
/winner |
Get winner details for a room by room code | No |
GET |
/leaderboard |
Get global rankings (Wins, Losses, Draws) | No |
GET |
/problem |
Fetch random Codeforces problem by rating range | No |
GET |
/verify-cf |
Verify a Codeforces handle exists via CF API | No |
All Socket.IO connections are authenticated via JWT middleware β the client must provide a valid token in the handshake auth object.
| Event Name | Direction | Payload / Description |
|---|---|---|
join-room |
Client β Server | { roomId, userId } β Join duel room via room code |
room-updated |
Server β Room | { room } β Notify room of updated state (player joined) |
start-match |
Client β Server | { roomId } β Host triggers match start |
start-match |
Server β Room | { room } β Synchronized match start with problem |
problem-selected |
Server β Room | { contestId, index, name, rating } β Problem details |
submission-found |
Server β Room | { player, cfHandle, problem } β Accepted submission detected |
match-ended |
Server β Room | { roomId, winner, winnerId } β Match finished (win or draw) |
- Frontend:
- React 18 (Hooks, Functional Components)
- Vite (Build & Development Server)
- React Router v6 (Client-side routing)
- Custom CSS Design System (1,500+ lines β dual-theme dark/light mode, design tokens, responsive)
- Socket.IO Client (Authenticated WebSocket connection)
- Lucide React (Icons)
- Backend:
- Node.js & Express.js (REST API & WebSocket gateway)
- Socket.IO (JWT-authenticated connections, room isolation, broadcast channels, match timers)
- PostgreSQL &
pg(Relational persistence with transactions) - Neon Database (Serverless PostgreSQL with connection pooling)
bcryptjs&jsonwebtoken(Password hashing & stateless JWT authentication)express-rate-limit(Rate limiting on authentication endpoints)- Codeforces REST API (Problem fetching, live submission verification, handle verification)
- Node.js:
v18+orv20.20.2 - PostgreSQL Database: Local PostgreSQL or a Neon Serverless PostgreSQL instance
- Git
Backend (backend/.env):
PORT=3000
JWT_SECRET=your_jwt_secret_here
DATABASE_URL=postgresql://username:password@localhost:5432/database_name
CLIENT_URL=http://localhost:5173Frontend (frontend/.env):
VITE_API_URL=http://localhost:3000Run the initialization script to create required tables, indexes, and extensions:
# Run schema initialization against your database (Neon or local PostgreSQL):
psql "$DATABASE_URL" -f init.sqlcd backend
npm install
npm run dev # Starts server on http://localhost:3000cd frontend
npm install
npm run dev # Starts client on http://localhost:5173Distributed under the MIT License. Designed and developed by Sasank Reddy.