Skip to content

Schemas and types — one source of truth

Shared types live in one library — server and client import the same schema.

nx-monorepo-schema-single-source

Why it matters

Failure modes if this rule is ignored
StakeIf ignored
Data corruption
  • Two seemingly-identical types will diverge within 3 months. One gets a new field, the other doesn't, and you have a silent bug.

How to fix

The Site type isn't written twice. It lives in one library (usually data-access or a dedicated schemas lib), and both server and client import from it.

Examples

Bad
ts
// apps/api/src/types/site.ts
export type Site = { id: string; name: string; slug: string; };

// apps/frontend/src/types/site.ts
export type Site = { id: string; name: string; slug: string; ownerId: string; };
// someone added ownerId on one side only
Good
ts
// libs/sites-management/data-access/src/lib/schemas.ts
import { z } from 'zod';

export const SiteSchema = z.object({
  id:    z.string(),
  name:  z.string(),
  slug:  z.string(),
});
export type Site = z.infer<typeof SiteSchema>;

// both sides
import { SiteSchema, type Site } from '@acme/sites-management-data-access';

Contribute

Released under the MIT License.

esc