A full-stack competitive programming judge — a LeetCode/Codeforces-style platform where users solve algorithmic problems and compete in timed contests. User-submitted code is compiled and executed against test cases inside isolated, resource-limited Docker sandboxes, with results streamed back over WebSockets.
Built as a Turborepo monorepo spanning a Next.js frontend, a Python (FastAPI + Celery) execution engine, a submission webhook service, and a WebSocket server, all backed by PostgreSQL and Redis.
Demo login: username
demo· passwordpassword123
- Multi-language execution — submit solutions in C++, Python, and JavaScript (Rust scaffolded).
- Sandboxed code runner — every submission runs in a throwaway Docker container with memory, CPU, PID, and network limits (see Security).
- Contests — timed rounds with problem sets, live leaderboards, and a time-decaying scoring system.
- Boilerplate generator — parses a per-problem
Structure.mdspec and auto-generates function stubs + a full I/O harness for each language. - Username/password auth — credentials-based auth via NextAuth + bcrypt (JWT sessions).
- Async pipeline — submissions are queued and processed by Celery workers, decoupling the web tier from execution.
┌──────────────────────────────────────────────────────┐
│ Browser │
└──────────────┬───────────────────────▲───────────────┘
│ submit code │ live results
▼ │ (WebSocket)
┌────────────────┐ ┌───────────────┐ ┌───────┴────────┐
│ web (Next.js) │──▶│ executor │ │ ws server │
│ :3000 │ │ FastAPI :8000 │ │ :4000 │
│ problems, │ │ + Celery │ └───────▲────────┘
│ contests, auth│ │ workers │ │
└───────┬────────┘ └──────┬────────┘ │
│ │ enqueue / run │ publish
│ ▼ │
│ ┌─────────────┐ ┌─────┴────────┐
│ │ Docker │ │ submission │
│ │ sandbox │────────▶│ webhook │
│ │ (per run) │ callback│ :3002 │
│ └─────────────┘ └─────┬────────┘
│ │
▼ ┌──────────────────────┴───────┐
┌───────────────┐ │ │
│ PostgreSQL │◀─────────┘ ┌──────▼──────┐
│ (Prisma) │ │ Redis │
└───────────────┘ │ broker/queue│
└─────────────┘
Flow: the web app writes a submission and calls the executor → the executor enqueues a Celery task → a worker runs the code in a Docker sandbox → the result is POSTed to the submission webhook → the webhook persists it and publishes to Redis → the WebSocket server pushes the verdict to the browser in real time.
| Path | Description |
|---|---|
apps/web |
Next.js 14 app — problems, contests, leaderboards, auth (App Router) |
apps/executor |
FastAPI API + Celery workers that compile & run code in Docker sandboxes |
apps/submission-webhook |
Express service handling judge callbacks, scoring & persistence |
apps/ws |
WebSocket server for live submission updates |
apps/boilerplate-generator |
Generates language stubs from each problem's Structure.md |
apps/problems |
Problems-as-files (statement, test inputs/outputs, reference solution) |
packages/db |
Prisma schema, client, migrations & seed |
packages/common |
Shared Zod schemas & language config |
packages/redis-utils |
Redis pub/sub helpers |
packages/ui |
Shared React component library (shadcn-style) |
Frontend: Next.js 14, React 18, TypeScript, Tailwind CSS, NextAuth Backend: FastAPI, Celery, Express, Node.js Data: PostgreSQL (Prisma ORM), Redis Infra: Docker / Docker Compose, Turborepo
Brings up the entire stack (Postgres, Redis, all services) and automatically runs migrations + seeds the database:
docker compose up --buildThen open http://localhost:3000 and sign in with demo / password123.
The executor shells out to
docker runto sandbox submissions, so it needs access to the Docker socket in a production setup.
Prerequisites: Node ≥ 18, Python 3.11, Docker, and a running PostgreSQL + Redis.
# 1. Install dependencies
yarn install
# 2. Configure environment (copy the examples and fill in values)
cp .env.example .env
cp apps/web/.env.example apps/web/.env
cp packages/db/.env.example packages/db/.env
cp apps/executor/.env.example apps/executor/.env
# 3. Set up the database
yarn db:generate # generate Prisma client
yarn db:migrate # apply migrations
yarn db:seed # seed 100 problems + 12 contests + demo user
# 4. Run the web app + node services
yarn dev
# 5. Run the Python executor (separate terminals)
yarn dev:python # FastAPI
yarn dev:celery # Celery workerUser code is never run on the host. Each submission executes in a fresh, ephemeral Docker container with strict limits (apps/executor/code/language_executor_factory.py):
| Control | Setting | Protects against |
|---|---|---|
| Memory cap | --memory=128m |
memory exhaustion |
| CPU cap | --cpus=0.5 |
CPU starvation |
| No network | --network=none |
data exfiltration / SSRF |
| PID limit | --pids-limit=128 |
fork bombs |
| No privilege escalation | --security-opt no-new-privileges |
container escapes |
| Wall-clock timeout | 30s on the subprocess | infinite loops |
| Ephemeral | --rm |
state leaking between runs |
yarn test # run the suite once
yarn test:watch # watch modeUnit tests (Vitest) cover the pure logic: the boilerplate ProblemDefinitionParser (parsing + per-language code generation) and the contest scoring function (time-decay, difficulty mapping, zero-window edge case).
| Command | Description |
|---|---|
yarn dev |
Run all JS/TS apps via Turborepo |
yarn build |
Build all apps & packages |
yarn lint |
Lint the workspace |
yarn test |
Run unit tests |
yarn db:migrate |
Apply Prisma migrations |
yarn db:seed |
Seed the database |