B1 · Part 1 · Foundations
What this site is
One decision shaped everything else: the site is a build artifact, and the heavy work runs in your browser.
07On this page
The one-sentence version
A reading site with four tools attached — a code playground, a set of runnable problems, a mock interview and a whiteboard — rendered to files at build time, served by a CDN, and doing its heavy lifting inside the reader's browser. There is no database, no login, no session, and nothing kept alive between deploys. Three small server functions exist. Everything else was either written before you arrived or runs on your own machine.
The decision underneath
Almost every choice in these chapters follows from one call made early: the content lives in the repository as TypeScript, and the whole site is rendered ahead of time. That is not the obvious choice for a site whose latest production build wrote out 1,803 routes, and it has a real cost: fixing a typo means a deploy, and adding a problem means a build.
What it buys is that the interesting parts of this system are the parts that do not run. A page that was written at build time cannot time out, cannot exhaust a connection pool, and cannot return a 500 because something upstream is slow. The failure modes that dominate most web architectures were removed rather than handled.
The second decision followed from the first. Once there was no server to lean on, anything that
looks like computation had to move to the reader. When you run Python on a problem, the Python
interpreter is WebAssembly running in a Web Worker in your tab. When you compile C++, the compiler
is clang, compiled to WebAssembly, downloaded once and cached by your browser. When you save a
whiteboard, it goes to localStorage. The server never receives your code, your boards or your interview answers, because it has nowhere to put them.
| Measured today | |
|---|---|
| Prerendered routes | 1,803 in a local production build of this branch, counted from .next/prerender-manifest.json |
| Server functions | 3, all under /api/ |
| Databases | 0 |
| Topics | 32 — 5 written, 25 outlined, 2 standalone |
| Written chapters | 253, plus 358 outlines |
| Exercises with tests | 955 |
| Interview questions | 420 across 27 rounds |
| Editor languages | 17, of which 11 run in the browser |
| Application code | 274 TypeScript files in app/, components/ and lib/, 26,684 lines |
The route count comes from .next/prerender-manifest.json. The content counts come from
the data through lib/content.ts. The code count is wc -l over the tracked
files at commit d6b12d7.
The three layers, and where work happens
What the 1,803 routes are
A static site with that many routes sounds like a site with that many pages of prose. It is not. About a third are reading pages. Most of the rest exist because every problem gets two routes: its own page, and a JSON file of test cases recorded from the JavaScript solution at build time.
noindex and left out of the sitemap. Counted from .next/prerender-manifest.json.
The four tools, and where each one runs
| Tool | URL | Where the work happens | Where its state lives |
|---|---|---|---|
| Reader | /<topic>/<chapter> | HTML from the build; search JSON fetched on the first keystroke | jsnotes:progress |
| Playground and problems | /practice?id=free, /problems/<id> | Web Workers, WebAssembly runtimes and sandboxed iframes | groundwork:playground:project, jsnotes:code:… |
| Mock interview | /mock | A client-side session engine over 12 prerendered question banks | groundwork:mock:… |
| Whiteboard | /whiteboard | A canvas that never renders on the server at all | groundwork:boards |
The storage keys are the real ones. The older features write under jsnotes: and the newer
ones under groundwork:. Renaming the old keys would orphan every reader's saved progress,
so both prefixes stay.
What the server still does
Three route handlers under app/api/ run as functions on request. /api/tts
turns chapter text into speech for the Listen button. /api/joke fetches one programming joke for the progress
page. /api/client-error writes browser errors to the function log when Sentry is not
configured. Each one has a per-IP rate limit, held in memory in the function instance, and none of them
is on the path of reading a chapter or running code. If all three went down, the site would lose a
voice and a joke.
What this chapter set covers
The beginner tier is orientation: this overview, the stack, the repository, the content model, what is written and what is not, and every route. After that come the chapters on how it runs: the request path, the build, rendering, state, the playground, the endpoints and search, plus the in-browser runtimes, how a solution in another language is graded, the step-through debugger, the whiteboard, the mock interview engine, the design system and how a change reaches production. The last tier is how it holds up: performance, security, the tests, the health of the project, what breaks first, and what is deliberately missing.
Nothing on these pages is an estimate. Counts come from the data itself, the route count from the
build's own manifest, and line counts from the tracked files. Several of the numbers in these chapters
are also checked by tests/claims.test.ts, which recomputes them from
lib/content.ts and fails if the prose has drifted, so adding a chapter without updating
the claims here breaks npm test. Where a number is unflattering it is still the number.
Finished reading?
0 of 26 chapters read in this series