Skip to content

Repository files navigation

Backpressure

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.

The Backpressure workspace: the URL shortener prompt on the left, a nine-box architecture diagram on the canvas, and the interviewer questioning the design on the right

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.

Quick start

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 once

Any Claude plan works. Then:

git clone https://github.com/jhomer192/backpressure.git
cd backpressure
npm install
npm run dev

Open 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.

If something goes wrong

  • "not configured" or auth errors in the app — you're not logged in. Run claude login, then reload the page.
  • node -v shows below 20.9 — upgrade Node, e.g. nvm install 20.
  • Port 3000 is takennpm run dev -- -p 3001.

The interview

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.

A scored verdict: 56 out of 100, Would not pass, with per-dimension scores for short-code generation, read path and latency, and storage and scaling

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.

How it authenticates

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.

Cost

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.

The problem library

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.

Adding a problem

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?

Testing the rubrics

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.

Status

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.

Stack

Next.js 16, React 19, TypeScript, Tailwind v4, and @xyflow/react for the canvas. The interviewer and grader go through the Claude Agent SDK.

License

MIT — see LICENSE.

About

Practice system-design interviews on your own machine. Draw an architecture on a canvas, and an AI interviewer grills it and scores it. Runs on your existing Claude Code login, so nothing leaves your laptop.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages