Tarek.
← All projects

2024

Typeflow

An open-source CLI that scaffolds type-safe forms from a Zod schema — validation logic shared verbatim between server and client.

Node.jsTypeScriptZodInk

The problem

Every React form I wrote repeated the same ritual: define a Zod schema for the server, then hand-write field components, then keep error messages in sync between both worlds. Three sources of truth for one form is two too many.

Typeflow collapses that: write one schema, get a typed form.

npx typeflow generate schema/contact.ts

generates:

import { createForm } from "./generated/contact.form";
 
export const ContactForm = createForm({
  onSubmit: async (values) => {
    // values: { name: string; email: string; message: string }
    await submit(values);
  },
});

Field components, labels, client-side validation and server-side parsing are all derived from the same source. Change the schema, and TypeScript tells you exactly which UI broke.

Approach

Codegen over runtime magic

Early prototypes did schema introspection at runtime. It worked until bundle sizes and hydration mismatches made it clear: generate code at build time instead. The generated output is plain, readable TSX you could have written yourself — and importantly, can edit when you need an escape hatch.

Interactive init via Ink

typeflow init runs an interactive terminal UI built with Ink:

<Select
  label="Which framework?"
  options={["react", "react-hook-form", "solid"]}
  onChange={setFramework}
/>

Small thing, but a friendly setup flow doubled completion rates in the repo's analytics.

Sharing validation verbatim

The same Zod schema instance validates on the client for instant feedback and on the server for authority. There is deliberately no "client version" of validation — one truth, two execution sites.

Outcome

  • ~800 GitHub stars and used in production by several indie products
  • Zero breaking changes across v0 → v1 thanks to generated-code snapshots in CI tests
  • Featured in a couple of newsletters, which taught me more about issue triage than any blog post ever could

What I learned

  1. Generated code must be boring. Cleverness in codegen multiplies into confusion for every user who reads the output.
  2. Golden-file testing keeps generators honest — every release diffs generated output against known-good examples.
  3. Open-source maintenance is 20% code and 80% writing issues that make strangers feel heard.