CONCEPT Cited by 1 source
Single-source interface spec¶
Definition¶
A single-source interface spec is a language-agnostic description of a component's (or API's, or message's) public interface — field names, field types, default values, documentation, version — stored as data in one place and consumed by a code-generation step that produces matching client and server bindings in every language that needs them.
The contract: every language binding is generated from the same file. If any binding drifts from the spec, regenerate — don't patch.
Canonical wiki instance (Yelp Konbini)¶
Yelp's Konbini stores one JSON file
per Cookbook component in the component_interfaces
repository:
{
"name": "cookbook.Button",
"version": "0.8",
"description": "A customizable Cookbook button.",
"owners": ["Design Systems <design-systems@yelp.com>"],
"parameters": {
"text": { "type": "String", "description": "..." },
"style": { "type": "cookbook.ButtonStyle", "description": "..." },
"on_click":{"type": "Nullable<Action>", "default": null, "description": "..." },
"size": { "type": "cookbook.ButtonSize", "default": "standard", "description": "..." },
"background_color": { "type": "Color", "description": "..." }
}
}
Jenkins triggers a code-generation pipeline on every push to this repo; four platform libraries — Kotlin, Swift, Python, TypeScript — are published automatically. Because each language binding is derived from the same file, Yelp can guarantee "the parameter names are guaranteed to stay in sync" on both sides of the wire.
What makes a spec "single-source"¶
- One physical file per interface. Not multiple per- language declarations reconciled by convention.
- Language-neutral format. JSON, YAML, Protobuf, Avro, Thrift — the format must be readable by all downstream codegens without privileging one language.
- Version is part of the spec, not of the generated code. Bumping the version is the act that triggers a new generation cycle.
- Codegen is hermetic. Generated code is not edited by hand — if it needs to change, the spec changes and codegen re-runs. Drift between spec and generated code is treated as a bug.
Contrast with other sources of truth¶
- Protocol Buffers / Thrift / Avro — RPC-native cousins of this concept for wire-message schemas. Same mechanism (spec → codegen) at a different altitude (data message vs UI component interface). See Protocol Buffers.
- GraphQL SDL — describes query schemas; tools like Strawberry and Apollo Codegen produce clients from SDL. GraphQL schema is a spec but often hand-edited while code follows along; the Konbini discipline (spec → code, never the other way) is stricter.
- OpenAPI / Swagger — REST equivalent for endpoints; similar discipline achievable but less commonly enforced.
- TypeScript types shared across packages (the "types file" approach in Zalando's cross-platform design system stack) — single source of types, but implementation code is hand-written per platform. Different trade-off: codegen effort eliminated, manual drift possible.
Preconditions for the discipline to hold¶
- Automated regeneration on every spec change. Jenkins / GitHub Actions / similar CI that republishes libraries on commit. Without automation, manual regen drift is inevitable.
- Versioned, language-agnostic type system. The spec's
types (
String,Nullable<Action>,cookbook.ButtonStyle) must all map cleanly to every target language. Yelp'scookbook.ButtonStyleenum, for instance, needs a Kotlin enum and a Python enum and a Swift enum — the codegen generates all three. - Migration discipline for breaking changes. Adding a field is additive and non-breaking; changing a field's type is breaking. The concept is tied to concepts/breaking-change-requires-major-bump and concepts/component-version-migrate-function.
Seen in¶
- sources/2026-04-22-yelp-how-yelp-keeps-server-driven-ui-consistent-across-four-platforms
— canonical wiki first source. Yelp Konbini's
component_interfacesrepo is the single source of truth; Jenkins-triggered codegen produces four platform libraries.