Skip to content

PATTERN Cited by 2 sources

TypeScript as code-gen source of truth

Use TypeScript types as the primary source of truth for code-generating APIs, CLIs, SDKs, configuration schemas, MCP servers, Terraform providers, and documentation — instead of a standalone schema DSL like OpenAPI, Protobuf, or Smithy (Source: sources/2026-04-13-cloudflare-building-a-cli-for-all-of-cloudflare).

Problem

Classical code-gen pipelines center on a separate schema language — OpenAPI for REST, Protobuf for gRPC, Smithy for AWS APIs, ThriftIDL, etc. These DSLs work well for a single interface shape but create friction as the surface expands:

  • OpenAPI describes REST only — cannot express CLI commands, RPC APIs, configuration files, or agent skills.
  • Two-language tax — engineers write the schema in one DSL, consume it in TypeScript/Go/Python, and context-switch constantly.
  • Tooling gap — schema DSLs have weaker IDE support, weaker type checking, and weaker linting than mainstream programming languages.
  • Extension friction — adding a new concept to the schema (e.g., "this command has a local mode") often requires forking or out-of-band annotations.

Pattern

Define APIs, commands, and configuration as a set of TypeScript types with conventions, linting, and guardrails. Every generator (CLI, SDK, Terraform, MCP, docs) consumes these TypeScript types as its input.

  • The "schema" is just normal TypeScript code in the source tree — no separate .yaml / .proto files to keep in sync.
  • Conventions (e.g., "every resource has get / list / create / delete") are expressed as reusable generic types or marker utility types.
  • Linting catches violations at compile time. Convention rules like "always get never info" become type errors. See concepts/cli-convention-enforcement.
  • Existing schema standards (OpenAPI, JSON Schema) become generated outputs for REST-API-compatibility use cases, not inputs. Customers who need OpenAPI get it for free; internal teams work in TypeScript directly.
  • Full IDE support (autocomplete, go-to-definition, refactor) comes for free because it's just TypeScript code.

Why this works at Cloudflare specifically

  • "We write a lot of TypeScript at Cloudflare. It's the lingua franca of software engineering."
  • Cloudflare already uses TypeScript type systems for Cap'n Web (RPC library) and Code Mode (tool calling as TypeScript function calls). The same instinct — TypeScript's type system is expressive enough to replace a schema DSL — scales to interface generation.
  • Workers bindings are naturally TypeScript-typed, so the schema and the runtime speak the same language.

Scope — where this is most applicable

Good fit:

  • Platform orgs generating multiple related interfaces from one spec (SDK + CLI + IaC + MCP).
  • Teams already TypeScript-heavy.
  • Orgs that want to extend schemas to cover new interface shapes (configuration, agent skills, RPC) that OpenAPI cannot express.

Less good fit:

  • Polyglot ecosystems where TypeScript is not universal.
  • Teams that truly only need one REST API; OpenAPI is still the shortest path to spec-generated clients.

Risk / tradeoffs

  • TypeScript lock-in — you're committed to TypeScript in perpetuity as your schema language.
  • No external standard — unlike OpenAPI, there's no industry tooling ecosystem already trained on your schema shape. Cloudflare mitigates by still generating OpenAPI as an output.
  • Schema-as-code discipline — the codebase must treat schema-type files as public API; refactoring them needs the same care as any cross-repo API change.

Example

Cloudflare generates from one TypeScript schema: cf CLI commands, Workers bindings, wrangler.jsonc config, Cloudflare SDKs across languages, Terraform provider, MCP Code Mode server, Agent Skills, dashboard UI, developer docs, and (as an output) OpenAPI schemas. See patterns/schema-driven-interface-generation for how the 1-to-N generation pipeline is structured.

Seen in

Last updated · 200 distilled / 1,178 read