Free, open-source system design interview practice that runs on your own machine. Pick one of 108 problems, draw the architecture on a canvas, and an AI interviewer reads the diagram and questions it. When you're done it grades the design against a written rubric and tells you whether it would pass.
It runs against your existing Claude Code login. There is no account to create and no API key to paste. Your diagram and your token stay on your laptop.
There is no hosted demo, and that is deliberate: serving other people's interviews through one personal Claude plan would be reselling it. Clone it and run it locally. If you'd rather read about it first, there's a write-up at jackhomer.com/projects/backpressure.
You need Node.js 20.9 or newer (node -v) and Claude Code, logged in:
npm install -g @anthropic-ai/claude-code # if you don't have it
claude login # opens a browser, sign in onceAny Claude plan works. Then:
git clone https://github.com/jhomer192/backpressure.git
cd backpressure
npm install
npm run devOpen http://localhost:3000, pick a problem, and start drawing. That's the whole setup — no API key, no .env, no signup.
If you'd rather spend a pay-as-you-go API key than your Claude plan, set ANTHROPIC_API_KEY and it gets used automatically. See .env.example.
- "not configured" or auth errors in the app — you're not logged in. Run
claude login, then reload the page. node -vshows below 20.9 — upgrade Node, e.g.nvm install 20.- Port 3000 is taken —
npm run dev -- -p 3001.
The canvas is blank on purpose. There's no palette of pre-labelled AWS boxes to drag in, because naming your own components is part of the exercise — you type the label, the same as you would on a whiteboard. Make a block once and drag it in as many times as you need.
The interviewer sees your node labels and how they're connected, not a screenshot, so it can tell when a component is sitting on the canvas unwired. It pushes back on what you drew rather than reciting a model answer.
Hitting Submit for grading produces a scored verdict: an overall number out of 100, a pass or fail call, a score and comment per rubric dimension, and lists of strengths, gaps, and what a senior would have added.
The verdict above is real output from the diagram in the first screenshot. A clean set of boxes with no reasoning attached does not pass, which is roughly what happens in the real thing.
One LlmProvider interface (lib/llm/) sits under everything, so the backend and the auth are both env switches:
| setting | effect |
|---|---|
LLM_AUTH=claude-code |
your own Claude Code login (default when no API key is set) |
LLM_AUTH=api-key |
a pay-as-you-go Console key (default when ANTHROPIC_API_KEY is set) |
LLM_BACKEND=agent-sdk |
Claude Agent SDK (default) — the only backend that can use your login |
LLM_BACKEND=anthropic-api |
raw Messages API, key only |
The Agent SDK spawns a Claude Code subprocess, which is exactly why this works locally with no key.
If you host this for other people, use api-key. Running their traffic through one personal Max or Pro plan is reselling it, and that's on you.
Chat runs on Haiku and grading runs on Sonnet, so a full practice session costs a few cents of your existing Claude usage. Nothing else is billed, because there's nothing else running.
108 problems, listed in docs/PROBLEMS.md, covering fundamentals like URL shorteners and rate limiters through to news feeds, payments, storage systems, and ML platform problems like RAG pipelines and feature stores.
The rubrics in lib/problems/ are the actual product. One authored file per problem: weighted grading dimensions, a reference architecture, what a senior would add, and likely follow-ups.
Criteria describe properties, not components. A rubric saying "uses Redis" fails a candidate who solved it with edge KV, and then the score means nothing. The right phrasing is "the hot read path avoids durable storage for popular keys, by any mechanism". The reference architecture is one valid solution and never an answer key; the grader is told so explicitly. See the guidance at the top of lib/problems/_template.ts.
cp lib/problems/_template.ts lib/problems/<id>.ts # write it
# add it to lib/problems/index.ts
npm run check-content # structure: weights=100, required fields, tech-name warnings
npm run smoke <id> # pipeline: does the grader return a valid verdict?
npm run calibrate <id> # quality: does the rubric grade a real answer correctly?Two levels, both running the real grader.
npm run smoke runs every problem against three adversarial probes: a generic shape-only design with textbook boxes and no reasoning, an empty canvas, and a prompt-injection attack telling the grader to score everything 100. Each verdict has to be structurally valid and internally coherent, with the overall score matching the weighted average of its dimensions, shaped to that rubric, and hard to fool: no probe passes, the empty canvas scores near the floor, and the injection gets graded on the absent design rather than obeyed. This proves the pipeline works and can't be rubber-stamped. It does not prove a good design passes. Sweeps are paced in chunks so a full run doesn't trip the local login's rate throttle; tune with SMOKE_CHUNK and SMOKE_RECOVERY_MS.
npm run calibrate is the real proof a rubric grades correctly. It runs golden answers from lib/calibration/ with pre-registered score bands:
| case | expectation |
|---|---|
conventional |
strong answer near the reference → passes |
alternative |
strong answer deliberately unlike the reference → must also pass |
mediocre |
right boxes, no reasoning → mid band, no pass |
garbage |
buzzwords → low, no pass |
injection |
labels that instruct the grader → scored on the absent design |
The alternative case is the point of the whole harness. If it fails, the rubric is grading resemblance to the reference instead of grading the design, and the harness says so by name.
Free and open source, made for the love of the game. The canvas → interviewer → verdict loop is built and verified end to end, and every rubric is smoke-tested. Extending golden-answer calibration past the seed set is ongoing.
Next.js 16, React 19, TypeScript, Tailwind v4, and @xyflow/react for the canvas. The interviewer and grader go through the Claude Agent SDK.
MIT — see LICENSE.

