01The idea
Half the screens in a business app are forms, and most of them get drawn twice: once in a design file and once in code. We wanted to see how far a schema on its own could get us before a designer touched anything.
The rule for the experiment was simple: the schema is the single source of truth. Labels, input types, validation messages and the order of fields all come from it. If a generated form looked wrong, we fixed the generator, never the form.
02Try it
This is a cut-down version running right here. Edit the schema and the form rebuilds as you type; validation comes from the same lines.
03How it's built
A small TypeScript function walks a Zod schema and maps each field to a component: strings become text inputs, enums become selects, booleans become toggles. Descriptions turn into help text, and refinements turn into live validation.
- One mapping table from schema types to components
- Validation runs on the same schema the API uses
- Labels and field order come from the schema, not the markup
- Any field can opt out and take a hand-built component
1// one schema field in, one form field out2function toField(key: string, s: ZodTypeAny): Field {3 const label = s.description ?? startCase(key)4 if (s instanceof ZodEnum)5 return { key, label, kind: "select", options: s.options }6 if (s instanceof ZodBoolean)7 return { key, label, kind: "toggle" }8 if (s instanceof ZodNumber)9 return { key, label, kind: "number" }10 return { key, label, kind: "text", optional: s.isOptional() }11}04What we learned
Generated forms get you most of the way in minutes. The last stretch is where design still earns its keep: grouping, sensible defaults and the words in the error messages.
- Generate the boring parts, design the important ones
- Error copy deserves as much care as layout
- A shared schema stops the API and the UI drifting apart
We now start most admin screens from a schema, and spend the saved days on the screens customers actually see.





