What Bones

TypeScript

One language from the database schema to the button, with types that cross the network.

Why TypeScript

TypeScript runs in every workspace — backend, apps, sites, email templates, and scripts. One language means:

  • Types cross the wire. The backend exports its router type, and the apps import it. Rename a field in a procedure and the web app stops compiling.
  • One set of habits. The same linter, formatter, and test runner work everywhere.
  • Shared config. Every workspace extends tsconfig.base.json, so strict mode can't quietly go missing in one of them.

Zod

Zod validates every procedure's input at runtime. TypeScript types disappear when the code runs; Zod is what rejects a bad request. tRPC reads the Zod schema, so the client gets the same types for free.

Where types stop

The backend's package exports types only. A runtime value can't cross from backend to web app, so a few small rules exist twice — the password rules and the avatar file limits. Each copy has a comment pointing at the other.

Used in