Interactive mock-interview drill for frontend and full-stack engineer loops in Berlin / EU — Senior, Staff, Lead or Architect frontend, or Senior and Staff full-stack. Eleven rounds across the six loops, 461 curated questions with model answers, key points and likely follow-ups. Reveal, rate yourself, and weak questions come back first.
Live: https://namityadav.github.io/interview-prep/
Switch the active role from the Loop date row on the home screen — it's a per-device setting, like the theme. Progress, notes and stories carry over between roles; only the round list and the visible question set change.
| Role | Rounds |
|---|---|
| Senior frontend | HR, hiring manager, live coding, algorithms, system design, case study, debrief |
| Staff frontend | HR, hiring manager, live coding, algorithms, system design, case study, debrief, head of engineering |
| Lead frontend | HR, hiring manager, live coding, algorithms, system design, tech lead round, head of engineering |
| Frontend architect | HR, hiring manager, architecture deep-dive, system design, case study, debrief, head of engineering |
| Senior full-stack | HR, hiring manager, live coding, algorithms, backend & data, system design, case study, debrief |
| Staff full-stack | HR, hiring manager, live coding, algorithms, backend & data, system design, case study, debrief, head of engineering |
- HR screen (compensation, negotiation, German employment basics)
- Hiring manager (live code review, web fundamentals, CSS & layout, accessibility, security, regulated & payments FE, TypeScript, i18n, reliability, deployment & infrastructure, AI-assisted engineering, situational, behavioral)
- Live coding (pairing, debugging, code review, build prompts, AI-allowed rounds)
- Algorithms (Codility-style tasks with hidden correctness and performance tests, and a 90-minute timed test)
- Frontend system design (one prompt, 45 minutes)
- Case study (take-home + presentation)
- Case study debrief (panel grilling)
- Head of engineering
- Tech lead round (Lead only) — people & growth, delivery & process, hiring & team shape, conflict & stakeholders, technical direction, running the round, AI-assisted engineering
- Architecture deep-dive (Architect only) — cross-team platform, migration strategy, decision records & governance, design-system ownership, build & runtime architecture, trade-off probes
- Backend & data (full-stack only) — API design, data & Postgres, caching & performance, async & messaging, auth & security, Node & Go runtime, full-stack design, backend live coding (runnable TS pads; Go appears as read-only snippets)
- Role switcher — the Role select on the home screen swaps the active loop (see Roles above): the round list, readiness counts and every drill below re-scope to it immediately, without touching your ratings, notes or stories.
- Round practice — a priority queue for one round: weak questions come first, then unseen, then ok, then solid; within a bucket the one you saw longest ago comes first, and exact ties (in practice, every unseen question) are shuffled, so a first lap mixes categories instead of walking the bank in file order. Rating a question Weak doesn't just leave it — it comes back around roughly 8 questions later, in the same lap, instead of waiting for a whole different lap (on the last question of a lap it simply comes back once more before the summary). Filter by category and by status — Unseen (never rated), Weak, OK, Solid — or switch to the Browse tab to search every question, answer and key point at once, grouped by category (a Top button appears once you have scrolled a way down it). The status filter is frozen when you pick it, so rating a question doesn't pull it out from under the lap; pick it again to rebuild the set; a filter with nothing in it offers a Show all questions button instead of a dead end. The progress bar keeps describing the whole category either way. A lap ends once every question (and every requeued one) has been shown, with a summary and a way to start another.
- By category — a collapsed panel on every round showing where you stand in each of its categories: a bar of the weak/ok/solid split and a one-word verdict (Weak, OK, Solid, or Unrated), averaged over the questions you have actually rated. A Solid that has gone stale counts as OK here, same as everywhere else. Click a row to drill that category, click it again to go back to all — the category select beside the tabs moves with it, and stays the way to change the filter without opening the panel.
- Weak drill — everything you rated Weak, across every round in the active role's loop, in one queue. The set is frozen on entry; re-enter it to rebuild.
- Mock session — a cross-round set in one sitting, in round order, like a real loop day. Two presets: Full loop (a slice of every round) and Technical rounds (hiring manager, live coding, algorithms, system design, plus architecture or backend & data where the role has them), each a fresh random draw per round. A banner marks each round transition. Ends in a recap, either by hitting Finish or once you have gone through the whole set: the counts, then the questions you rated Weak listed by round, and the ones you never rated folded under them.
- Frontend system design → 45-min prompt — a third tab on the design round: one prompt, a visible (non-forcing) 45-minute clock, and the requirements → API/data → components → state → performance → a11y/i18n → observability → rollout phase checklist to work through out loud, plus a scratch pad. Finish reveals the model answer and lets you rate yourself.
- Algorithms → Timed test — the third tab on the algorithms round, laid out like a Codility session: Start test draws three tasks from three different categories, weakest first, and starts one 90-minute countdown for all of them. Switch between Task 1, 2 and 3 freely; Run examples checks a solution against the example cases only, while the hidden tests stay hidden. Submit test (it asks you to confirm first) — or the clock reaching zero, which submits whatever is in the pads without asking — grades all three at once: a correctness, performance and total score per task, the model answer folded under each, and a rating for each. New test resets it. A test in progress survives a reload — the round reopens on its tab until the test is handed in, and one whose clock ran out while you were away is submitted and graded the moment it reopens — and is dropped once it is over three hours old; its code is kept apart from the practice pads' drafts.
- Search — every question in the active role's loop, in one search box, with the same status filter (Unseen / Weak / OK / Solid).
- Print cheat sheet — everything rated Weak plus everything you have a note on, grouped by round, laid out for printing before you walk in.
- Write your answer in three bullets first — before you reveal anything. It stays visible above the model answer once revealed, so you're comparing what you actually said, not just reading key points cold. It is kept on this device until you rate the question, so a reload mid-answer (or Back) does not lose it.
- If your browser supports it, click to record a spoken answer (click again to stop); play it back once revealed. Nothing is saved or sent anywhere — it's gone the moment you move to the next question.
- Reveal the model answer, then tick off the key points you actually said out loud. The hit count suggests a rating: all of them Solid, fewer than half Weak, otherwise OK. Once revealed, the card shows how long you took and the round's target time — a stopwatch, not a countdown, so nothing forces a hide, unless you turn on Strict mode (below).
- If you wrote an answer, Copy for Claude under it copies a grading prompt — the question, your answer and the key points — to paste into Claude for an outside read instead of grading yourself. Nothing is sent from the app.
- Algorithms tasks are graded pads: Run examples runs your solution against the example cases only, with its console output shown; Submit runs every hidden case, console muted, and reports Correctness X% · Performance Y% · Total Z% with a row per case — ✓, ✗, or ⏱ timed out after 1.5 s, with the input, the expected value and what you got. After a Submit, the suggested rating counts tests passed instead of key points (all passed Solid, under half Weak, otherwise OK).
- Back steps to the previous question if you want to re-rate it; disabled at the start of a lap.
- Likely follow-ups — probe yourself on one at a time, before you reveal, each with its own running clock from the moment you asked for it. Once revealed, they're listed in full for reference.
- On categories that call for a real story (from your CV, motivation, leadership, situational, and similar), your story bank shows up before you answer — pick one with "Use this" and it expands inline and marks itself rehearsed.
[bracket slots]in an answer are yours to fill from your own experience — the answers are coaching scaffolds, not a script to memorise.- Every question takes a note.
- The Live coding build prompts, the data-structures questions and the
Backend & data live-coding pads give you an editable scratch pad pre-filled
with the starter code, instead of a read-only snippet — write your approach out
before revealing, then Run it (
⌘↩/Ctrl+↩inside the pad). Console output and errors show up under the pad; the React component prompts (Autocomplete, Tabs, VirtualList and friends) also render live in a preview with sample props once the sandbox reports in. Every Run starts from a clean slate, and Stop kills whatever is going on. Tab indents inside the pad; Esc moves focus to Run. Console-only starters run in a Web Worker, so Stop ends even an infinite loop; the component starters and the few that need the DOM run in a sandboxed frame instead, where forms submit but nothing can navigate, open windows or touch your saved progress. Either way it runs TypeScript and JSX without type-checking, the way CoderPad does, with React's hooks available as globals — no imports. What you type is kept per question on this device, so a reload or a switch to another question doesn't lose it; it stays out of export/import backups. Run output is never stored.
- My notes — every note you have written, in round order, read-only. Edit them on the question itself.
- My stories — a STAR-style story bank, independent of any one question. Sorted least-recently-rehearsed first, so the stale ones surface. New story drops you straight into its title. Mark one rehearsed when you have said it out loud, or pull one up mid-question via "Use this".
Set a Loop date on the home screen and every round card shows how many questions are unseen, how many are weak, and how many days you have left, and the line under the date says how many questions a day clears everything weak or unseen by then; cards themselves reorder by urgency (weak and unseen count more), and the Round N labels come off since they would contradict the order. Once the date has passed the countdown stops and the cards go back to round order. Under the title, a line counts the questions you rated today and in the last seven days, so an empty day is visible. A banner nudges you to export if you have progress and haven't backed it up in the last week.
Space reveal · 1 / 2 / 3 rate Weak / OK / Solid · N skip · B back.
- Ratings, notes and stories stay in your browser (localStorage). Nothing is sent
anywhere. Export / Import to back up or move devices; Reset progress
clears everything. If one saved entry is ever unreadable, only that entry is dropped on
load; the original blob is kept aside under
interview-prep:v1:corrupt. - Theme: Dark, Gruvbox, Gruvbox Light or Light, switchable from the top of any page. Stored per device, outside the backup.
- Strict mode: switchable from the top of any page. When on, running out of a round's target time auto-reveals the answer instead of waiting for you to click Reveal. Stored per device, outside the backup.
- Focus sound: white, pink or brown noise synthesized in the browser (Web Audio) and looped while you drill, with a volume slider, in Settings. No audio files are downloaded. The chosen sound and volume are stored per device, outside the backup; playback never starts on its own, so press Play after a reload. While it plays, the Settings button shows a ♪.
- Scratch pads (Build-prompt code, 45-minute design write-ups, your pre-reveal answers), lap positions and the running design session are working state, stored per device and outside the backup: a new machine starts them fresh, and Reset and Import clear all of them along with the data they belonged to. Anything worth keeping goes in a note. Run output is not stored at all — it is gone when you leave the question.
- Offline: the app installs as a PWA and works without a network after its first visit — the build writes a service worker that precaches every file it emits, including the Web Workers that run console-only scratch pads and grade algorithm tasks. The one exception is Run on a component starter (or one flagged as needing the DOM): the sandbox frame has an opaque origin the worker cannot serve, so it needs the network.
Edit src/data/<round>.ts. Ids are <round>-<nnn>. A question can carry an
optional roles: RoleId[] to opt out of roles whose loop would otherwise show
it (e.g. a platform-scoped question tagged away from Senior) — leave it off to
show the question to every role whose loop includes its round. npm test
validates shape and uniqueness. A tag that lists staff also lists fs-staff, so
Staff full-stack keeps seeing everything Staff does.
npm install
npm run dev # http://localhost:5173/interview-prep/
npm test # vitest watch
npm run build # tsc + vite build — emits index.html and sandbox.html (the code-runner frame)
npm run smoke # build, then drive the built app in headless Zen (Firefox): app boot, sandbox frame, workersThe smoke check covers what jsdom cannot: the opaque-origin frame loading its module
script cross-origin and answering over postMessage, the worker compiling and reporting
output and dying on terminate(), the grader worker answering a case and a quadratic
solution still spinning at its time limit, the built app rendering. It is local-only — CI has
no browser — and SMOKE_BROWSER points it at any Firefox or Chromium binary.
Vite · React 19 · TypeScript · Tailwind CSS 4 · GeistMono Nerd Font (self-hosted from public/fonts) · Vitest · GitHub Pages
Two JS chunks for the app itself — the app and the React runtime, ~385KB gzipped
together, most of it the question bank's own text, not code — plus three runners the app
only fetches on Run or Submit: the sandbox.html page that runs component starters in a
sandboxed iframe, a self-contained Web Worker for the console-only ones, and a second
Web Worker, the grader, that runs the algorithm tasks' hidden tests one case at a time
so the page can time each and terminate a runaway. All carry Sucrase to strip types and
compile JSX; React is shared between the two pages, and the compiler is never downloaded
by the app. Measured, not optimized:
further code-splitting would trim the initial load, but this is a single-user app run
from a laptop, so it isn't worth the added complexity.
The service worker is written by a ~40-line plugin in vite.config.ts rather than
vite-plugin-pwa: it only has to precache the build output, and a hash of the file list
as the cache name gives it versioning for free. Browse and Search render every row and
lean on content-visibility: auto to skip laying out the off-screen ones instead of a
virtualised list.
Skipped for the same reason: a CSP <meta> tag (the inline pre-paint theme script
would need a build-time hash to keep it, which is fragile for the gain on a static
page with no user input to sanitize), type-aware ESLint rules (recommendedTypeChecked
surfaces a long tail of findings unrelated to this app's actual bugs), and Prettier
(the codebase is formatted consistently by hand).