That is worth knowing before you plan a sprint around it. What you get is a working app you own, not a kit of parts to assemble.
What is actually written
Adding React is the command that writes it, adopting an existing Vite app is the other route in, and front ends overview is the map.
A router, two globs and a shadow rule.
A session hook, a sign-out, and a signed-in route guard.
Sign-in screens — magic link, one-time code, callback — when the Worker composes auth.
A humanity-check widget, when turnstile is composed.
Paywall, pricing and subscription screens, when payments is composed.
One screen of your own, written once and never again.
Two stylesheets: yours, and the one defining every class a Pithy screen renders.
The router is two globs and a shadow rule
src/routes/pithy/*.tsx Pithy's screens
src/routes/app/*.tsx yoursEach route module exports its own path alongside its component. The router keys modules by that declared path, and yours shadows Pithy’s: a module in your directory declaring the same path replaces it entirely.
Adding a screen needs no edit and no re-run. Drop a file in with a declared path and it is routed. No route table, no generated manifest, no command to run again.
Replacing a Pithy screen needs no fork. Write yours with the same path and yours wins. Pithy’s file stays on disk, unmodified and inert — delete it whenever you like.
A screen names its own path, and guards read it
The router sends a signed-out visitor to whichever screen declares the sign-in role, and a visitor short an entitlement to the one declaring the paywall role — at whatever path that screen declares.
So renaming a route is one edit, in one file, and every redirect follows it.
Claim a role from your own directory to take the job over, exactly as you take a path over. A role nothing claims throws rather than sending anybody nowhere.
The callback path is read, not repeated
The sign-in screen reads the callback path from the callback screen, so that rename is one edit too.
This is the one round trip you cannot check by being signed in — which is exactly why it is not left as two strings that agree today.
Co-located tests are not routes
Both globs negate the test-file names, so a test beside a screen is registered as nothing and reaches no bundle.
That negation is the one filename rule the router has, and it earns its place: without it the file is a route, and everything in it — fixtures, stub tokens, the shape of an endpoint and how it fails — is served to anyone who asks.
A companion file under another tool’s convention is not covered. Give it its own negation, or keep it outside the routes directory.
Path parameters and the query string
A segment beginning with a colon is a parameter, and its value arrives as a typed prop rather than something you parse.
The query string is available the same way. Nothing here asks you to reach for the raw location.
What the client knows about your backend
Virtual modules, resolved in memory — not a generated types file on disk.
So there is no artifact to regenerate, nothing to gitignore, and no moment where the client and the backend disagree because somebody forgot to re-run something.
A capability’s client-safe projection is opt-in by construction: a new config field never reaches a browser bundle unless it is explicitly projected, and a capability with no browser surface projects nothing at all — the front end then reads a disabled flag.
What you are expected to write
Your design system. Every visual decision beyond the palette tokens.
Your components. Buttons, inputs, tables, modals, everything.
Your screens, beyond the one home screen and the auth flow.
Your layout and navigation.
That is a real amount of work, and pretending otherwise would waste your time. What the scaffold removes is the wiring — routing, session, sign-in, the asset allowlist, the build, the deploy — rather than the design.
Bring your own everything else
Nothing here is a dependency you cannot replace. A different styling approach, a different data-fetching library, a different component library — all fine, because the scaffolded files are yours from the moment they are written.