Inspiration
Most coding practice sites hand you a problem and leave you alone with it. You either grind in silence or give up and read the solution. We wanted something closer to a sparring partner: a place where you write real code against a clock or an opponent, and where help makes you think instead of giving you the answer. CodeClash treats learning to code as a competitive game with a ladder to climb, and pairs it with an AI tutor that only ever asks questions.
What it does
CodeClash is a competitive Python coding arena with two modes.
Solo Dojo: practice at your own pace.
- Write real Python in an in-browser editor and run it against test cases. Problems come from a curated bank of 30 plus AI-generated challenges: pick a difficulty and topic and Gemini writes a fresh problem with test cases and hints.
- BYTE, the Socratic tutor. It sees your code and your failing tests, and asks guiding questions instead of giving answers. It is built to help you discover the right built-in function: first it asks about your data types, then it points at a category, and only then names the tool.
- Debugging tools you'd normally need an IDE for:
print()output shown per test, TRY IT to run your function on any arguments you type, and TRACE, which steps through your code one line at a time, highlighting the line in the editor and showing every variable change. - Hover help and a function library of about 140 entries (built-ins, string/list/dict/set methods,
math, handy imports, and syntax like slicing and comprehensions). Hover anything in the editor for its signature, return value and gotchas. - Code review. Once all tests pass, BYTE estimates your time and space complexity and suggests one improvement, in words and never as code.
- After your first solve you rate the problem's difficulty and how much you liked it. The community averages show next to every problem.
Clash: ranked 1v1 duels.
- Matchmaking pairs you with the closest rating. Both players ready up, a countdown runs, and you race on the same problem for 10 minutes while watching your opponent's live progress. The first fully passing solution wins.
- Elo updates after every match, with rematches, a leaderboard of top players, and a match history of your last 25 matches with win/loss, win rate and rating change.
Accounts and profiles: every challenge you solve, including AI-generated ones, is saved with your solution, so your profile is a record of what you've learned. You can click any player on the leaderboard to see what they've solved (but never their solutions).
How we built it
- Frontend: React 19 + Vite with a feature-based structure. Pages register themselves as routes, so teammates could work in parallel without merge conflicts.
- Editor: Monaco (the engine behind VS Code), extended with our own hover provider, autocomplete docs and trace-line highlighting.
- Code execution: Python runs in the browser with Pyodide inside a Web Worker, with a 5-second timeout. Player code never touches our server, which keeps execution safe and removes the need for a sandbox service. The step-through tracer is built on Python's
sys.settrace, running inside the same worker. - Gemini, three ways: structured-output problem generation (a strict JSON schema so every problem drops into the test runner), the Socratic tutor (a system prompt with a hint ladder and a rule never to give code), and the post-solve complexity review.
- Clash: matchmaking, lobbies and duels run on serverless endpoints, with all match state in Postgres.
- Auth and data: bcrypt-hashed passwords, JWT sessions, and a TigerData (Postgres) database for users, Elo, solutions, ratings and match history.
- Deployment: Vercel, using the same handler code locally and in production.
Challenges we ran into
- Running untrusted code safely. Running arbitrary Python on a server is dangerous. Pyodide in a Web Worker solved that, but we had to handle a ~10 MB runtime download, infinite loops (a timeout that kills the worker), and warming the runtime up early.
- Real-time multiplayer on serverless. Our first Clash used WebSockets, which Vercel's serverless functions can't host. We rebuilt matchmaking on short-interval polling backed by Postgres, so duels work on the same deployment as everything else.
- Reliable structured output from an LLM. Gemini would sometimes return a function name in a format our validator rejected, so about two in three Hard Math requests failed. We loosened the validator, asked for a specific style, and added a retry.
- A tutor that teaches without telling. Getting an LLM to point at the right function without handing it over took iteration. We settled on a three-step ladder in the prompt and tested it by hand.
- Stale state. A finished match's result card kept reappearing the next time a player opened Clash. We fixed it by recording when matches finish and dismissing results once you leave.
Accomplishments that we're proud of
- A full learning loop in one app: write code, debug it by stepping through it, get a Socratic hint, pass the tests, get a complexity review, and rate the problem.
- A step-through tracer that works entirely in the browser, with no backend.
- Ranked real-time duels that work on a serverless deployment.
- AI-generated problems that plug into exactly the same runner and tutor as hand-written ones.
- Accounts with persistent profiles, a leaderboard and match history, on a real Postgres backend.
What we learned
- WebAssembly makes in-browser execution of real languages practical, and enables tools like a tracer without any server.
- Schema-constrained LLM output is far more dependable than prompting for JSON, but you still have to validate it.
- Serverless platforms shape your architecture: WebSockets and function-count limits pushed us toward polling and fewer endpoints.
- Good teaching is a design problem. A tutor that asks the right question teaches more than one that gives the answer.
What's next for CodeClash
- Server-side judging. Python runs in the browser, so solves and ratings are currently self-reported. We'd re-verify winning Clash submissions on a sandboxed server before awarding Elo.
- More languages and a bigger problem bank, with a team-reviewed difficulty rubric.
- Learning paths and spaced review: daily challenges, streaks, and resurfacing problems you solved a while ago.
- Smarter tutoring: feed BYTE the player's history so it knows which concepts they keep missing.
Built With
- bcrypt
- css3
- express.js
- google-gemini
- html5
- javascript
- jwt
- monaco-editor
- node.js
- postgresql
- pyodide
- python
- react
- react-router
- tigerdata
- vercel
- vite
- webassembly