SYSTEM Cited by 1 source
Yelp Konbini¶
Definition¶
Konbini is Yelp's auto-generated library family that bridges CHAOS (Yelp's server-driven-UI framework) to Cookbook (Yelp's cross-platform design system). From a single JSON interface definition per Cookbook component, Konbini generates four platform-specific libraries that all stay perfectly in sync because they are generated from the same source file:
componentinterfaces— Kotlin package for Android clients (Moshi-based JSON deserialisation).YLInterfaces— Swift package for iOS clients.component_interfaces— Python package for backend services (serialisation to JSON).component-interfaces— TypeScript/React package for web clients.
Konbini is built by Yelp's Design Systems team. Canonical disclosure: Yelp's 2026-04-22 post "How Yelp Keeps Server-Driven UI Consistent Across Four Platforms".
Why Konbini exists¶
Before Konbini, different teams implementing CHAOS backends
invented their own backend representations for the same UI
component. Yelp's post shows two pre-Konbini backends both
rendering a "Click me to go to Yelp" button — one called it
SDUIButton(label, button_type, action=OpenURLAction(url),
size="small"), the other ServerButton(text, style,
click_handler={"type": "open_url", "url": ...},
display_size="sm"). Different property names, different
action shapes, different size vocabularies. Yelp: "Both
solutions were trying to render the same button component,
but their backend representations were completely
different—different property names, different ways to handle
actions, different size values. This created a maintenance
burden and made it difficult to ensure a unified user
experience."
CHAOS unified SDUI architecturally — one backend shape
per view, one GraphQL subgraph — but still allowed per-team
component vocabularies. Konbini unifies the component
interface contract: every CHAOS backend at Yelp now
instantiates the same generated CookbookButton class (or
any other Cookbook-defined component), whose output is
bit-compatible with the clients' same generated
deserialisers on Kotlin, Swift, and TypeScript.
How it works¶
Single JSON source¶
Every Cookbook component has one JSON interface definition 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-triggered codegen¶
Verbatim: "Whenever a new commit is pushed to the component_interfaces repository, Jenkins pipelines automatically trigger the code generation process and publish new versions of the libraries." One push, four published libraries.
Same-name guarantee across platforms¶
The generated Python backend serialiser (CookbookButtonV0)
and the generated Kotlin deserialiser
(CookbookButtonInterfaceParams) both carry the same
parameter names (text, style, on_click, size,
background_color) because both are derived from the same
JSON definition. Yelp: "Because both the Python and Kotlin
code are generated from the same JSON source, the parameter
names are guaranteed to stay in sync." See
patterns/single-json-spec-to-multi-platform-codegen.
Separation of concerns: Konbini + hand-written render¶
Konbini stops at the deserialised interface model. The binding from the model to the platform-native Cookbook widget is hand-written per platform. In Kotlin/Compose, Yelp writes an extension method:
@Composable
fun CookbookButtonInterface.Render(
renderer: KonbiniComposeRenderer,
onError: (RenderError) -> Unit,
modifier: Modifier = Modifier,
) { /* ... dispatches on size → ButtonSmall/Standard/Large */ }
This is the only layer that couples the Konbini interface model to platform-specific widget composition; it's small and usually invariant across component version bumps.
Spec files and backward compatibility¶
Each Konbini-generated client library bundles a spec file listing the versions of every interface + enumeration that platform supports. Example:
{
"version": "23.0",
"interfaces": { "cookbook.Button": "1.0" },
"enumerations": { "cookbook.ButtonStyle": "0.1" }
}
Every CHAOS request sends a Konbini context
(spec_name@spec_version, e.g. android@23.0) to the
backend. The backend looks up the spec and picks the highest
component version compatible with that spec to serialise.
See concepts/client-spec-version for the spec-file concept and patterns/spec-version-negotiation-for-backward-compat for the per-request version-negotiation pattern.
Breaking changes and migrate()¶
When a component introduces a breaking change — e.g. Button's
text changes from String to a custom FormattedText
type — the component major version bumps (0.8 → 1.0).
Konbini auto-generates a stub migrate() method on the new
class; developers must implement it to produce the
previous major-version instance from the new one:
def migrate(model: CookbookButtonV1) -> CookbookButtonV0:
return CookbookButtonV0(
text=model.text.toString(),
style=model.style,
on_click=model.on_click,
size=model.size,
background_color=model.background_color,
)
If the backend wants to send CookbookButtonV1 but the
client only supports V0 per its spec, migrate() is
invoked to downgrade. Default behaviour: throw. "We highly
recommend replacing this behavior with your own custom logic
that uses the data from the provided ... to return an object
of type ..." — backward-compat opt-out is an explicit
developer action, not accidental. See
concepts/component-version-migrate-function and
patterns/migrate-function-for-component-downgrade.
Design tokens¶
Konbini handles another category alongside primitive types:
design tokens — named stylistic values (colours, icons,
gradients, shadows). Tokens are owned in a separate
designer-curated repo, published as JSON, and serialised on
the wire as {name, raw_value}:
The name is stable across platforms; the raw_value is the platform-resolvable default. See concepts/design-token-as-named-reference.
Position on the wiki¶
Konbini is the wiki's canonical instance of:
- Single JSON interface spec → multi-platform codegen — patterns/single-json-spec-to-multi-platform-codegen at cross-platform-UI altitude (cf. Zalando's different approach via StyleX + react-strict-dom which uses runtime platform resolution rather than pre-build codegen).
- Spec-version negotiation for backward compatibility — patterns/spec-version-negotiation-for-backward-compat.
- Migrate function for component downgrade — patterns/migrate-function-for-component-downgrade.
Konbini sits below CHAOS: CHAOS builders
(FeatureProviders)
instantiate Konbini-generated Python classes
(CookbookButton(text=..., style=..., ...)) and the CHAOS
subgraph then serialises them via the
JSON-string parameters mechanism in its GraphQL schema.
Konbini-generated client libraries deserialise the JSON
content; hand-written render extensions bind the
deserialised model to Cookbook widgets.
Known tradeoffs¶
- Render extension is hand-written — codegen does not reach all the way to the widget tree. Render-extension regressions are possible even while serialisation stays bit-compatible.
migrate()correctness is developer responsibility — the generated default throws. A wrong migration silently ships the wrong backport.- Cross-major migrate chains not discussed — the post
shows
V1 → V0. IfV2.0ships while some clients still pinV0, whethermigratecomposes is not stated. - No disclosed operational numbers — component count, generation time, library publish frequency, backward-compat hit rate. Architectural walkthrough only.
Seen in¶
- sources/2026-04-22-yelp-how-yelp-keeps-server-driven-ui-consistent-across-four-platforms — canonical first-party disclosure.
Related¶
- systems/yelp-cookbook — the design system Konbini bridges to
- systems/yelp-chaos — the SDUI framework that consumes Konbini
- systems/jenkins — triggers the codegen
- concepts/single-source-interface-spec
- concepts/component-version-migrate-function
- concepts/client-spec-version
- concepts/design-token-as-named-reference
- concepts/breaking-change-requires-major-bump
- patterns/single-json-spec-to-multi-platform-codegen
- patterns/spec-version-negotiation-for-backward-compat
- patterns/migrate-function-for-component-downgrade
- patterns/design-system-component-library-cross-platform
- companies/yelp