Where the code comes from

J
John Doe
|
Jan 15, 2024
|
5 min read
#react
#javascript
#frontend

Most of the code in this codebase was not written. It was produced. Giant Context, the website platform I build, runs on an apparatus that reads the API's description of itself and materializes the client side of the platform.

The API drives everything

The intent predates the repository. I wanted the API to drive everything, and the moment you commit to that, generation stops being optional. If the API is the single source of truth, then every place that truth appears (the typed client, the data hooks, the cache keys, the form validation, the route tables) must be derived from it, because any hand-written copy is a second source of truth that drifts out of agreement. The first generators landed in week one (2025-12-19 · 8e6f18335), and they have been the spine of the codebase since.

The two format choices were the least clever decisions in the system, on purpose. OpenAPI as the description, because it is the standard. Zod on the client, because it is also the standard, and it ties straight into form validation. Boring inputs, boring outputs. The apparatus earns its keep in the middle.

The shape of the machine

The apparatus is around ten small programs, each owning one output family. One reads the spec and emits the typed client. Others emit the query cache keys, the data hooks, the route tables, the actions, the mocks and factories the tests run on, the merged locales. No single grand generator, just narrow ones, because narrow generators are easy to write, easy to debug, and cheap to add to.

The generators do not parse source files. The dev API serves its own OpenAPI description at a local URL, and the generators read that URL. What they consume is the spec of a running, healthy server, not an inference over code sitting still. If the API cannot start, nothing generates. The description is always the description of something alive.

And a generator is a smaller program than the word "apparatus" suggests. The hooks generator is the kind of script any mid-level engineer would write:

packages/generated/scripts/generate-hooks.ts

// packages/generated/scripts/generate-hooks.tsconst outputFile = join(process.cwd(), "src/client/hooks.ts");
type OpenApiMethod = {  operationId?: string;  summary?: string;  tags?: string[];  requestBody?: {    content?: {      "application/json"?: { schema?: { $ref?: string } };    };  };};

Plain types over the OpenAPI shapes, a walk over the operations, a string template per hook, a file write. There is no magic anywhere in the machine.

There is no magic anywhere in the machine.

One package to hold it all

Everything the generators produce lands in a single package named generated, and its layout is the platform's client surface at a glance:

packages/generated/src/

packages/generated/src/├── client/│   ├── api.ts          typed client + zod schemas│   ├── hooks.ts        data hooks│   ├── keys.ts         query cache keys│   ├── routes.ts       the console route table│   ├── menu.ts         navigation│   ├── types.ts│   ├── __mocks__/      test mocks│   └── __e2e__/        generated e2e scaffolds├── server/└── locales/

Every file carries the same header, AUTO-GENERATED, DO NOT EDIT, and the rule behind the header has no exceptions. A hand edit to a generated file is not a shortcut. It is a bug, because the next generation pass erases it. If an output is wrong, you fix the source or the generator, never the artifact.

Quarantining the outputs in one package also solved a problem that has nothing to do with generation. A monorepo of compartmentalized sub-packages needs some surface that cuts across all of them, because every app needs the same typed client, the same hooks, the same keys. And the moment sub-packages import each other to share that surface, you are one refactor away from circular references. The generated package is the designated cross-cutter. Everything imports from it. It imports from no one, because its contents are not imported but produced.

Services, not scripts

For about an hour, early on, I ran the generators by hand. Then they became services. A tool runs when you call it. A service never stops. The dev environment runs every service hot, and the generators sit among the API and the web client in watch mode. Save a schema change and the API reloads, the spec updates, and regeneration follows in the same breath as the hot reload.

That choice paid immediately. January's receipts say the console grew from 25 routes to 74 over 30 days. Write the backend, and half the frontend work is already done. The client, the hooks, the cache keys, and the validation for every new endpoint arrive the moment the endpoint does, and prototyping runs at the speed of the API instead of the speed of my typing.

0

console routes at the start of January

0

console routes 30 days later

What it costs

The ledger has entries on both sides. Generators are code, and they break like code. A malformed schema can stall the whole chain, and debugging a generator means holding both the spec and the template in your head at once. The spec must stay healthy or nothing moves, which converts API discipline from a virtue into a dependency. And the DO-NOT-EDIT rule has a learning tax. Every instinct you have says fix the file in front of you, and the machine says fix the thing that made the file.

I pay those costs without complaint, because of what sits on the other side of the ledger. Most of the code in a codebase does not deserve to be written. It is derivable, and anything derivable that you write by hand becomes a copy you now maintain. Treat that code as a build artifact instead, and the surface you actually write shrinks to the parts that carry judgment, meaning the schema, the business logic, the tests, the things a machine cannot decide. The rest arrives the way compiled code arrives, correct by construction and disposable by design.

Where does the code come from? A running server describes itself, ten small programs read the description, and one package nobody wrote holds the result. Build the boring version of that and the platform on top of it stops being impressive and starts being inevitable.

Have questions?

If you're interested in my work or Giant Context, contact me!

Contact Jesse
Legal
Privacy Policy
Terms of Service
Cookie Policy

© 2026 Giant Context. All rights reserved.

Where the code comes from