SYSTEM Cited by 2 sources
Yelp CHAOS¶
Definition¶
CHAOS is Yelp's internal server-driven UI (SDUI) framework. The server authors a CHAOS Configuration (a bundle of views, layouts, components, and actions) per request; the client (iOS, Android, web) reads the configuration and renders a UI that the server fully determined. CHAOS was first introduced publicly in Yelp's 2024-03 post and the backend was unpacked in "Exploring CHAOS: Building a Backend for Server-Driven UI" (2025-07-08).
Surface area¶
- GraphQL API — a single CHAOS Subgraph in Yelp's
Apollo Federation supergraph.
Clients issue a
chaosConfiguration(name, context)query. - CHAOS REST API — the contract each CHAOS backend service implements; the subgraph routes to the backend for the requested view. Multiple teams run their own CHAOS backend, all conforming to this contract.
- Python Strawberry subgraph — the GraphQL-facing layer.
Build pipeline¶
Four layers, all named in the post:
ChaosConfigBuilder— request entry point; holds registered ViewBuilder classes and returns the final configuration.ViewBuilder— one class per logical view (view_id()== e.g.consumer.welcome). Selects the layout and declares optional subsequent views for view flows.LayoutBuilder— e.g.SingleColumnLayoutBuilder(onemainsection) or mobile layouts with toolbar/footer sections. Holds an ordered list of FeatureProviders per section; order == render order.FeatureProvider— one per product feature; produces the components and actions that implement the feature. Follows the six-stage lifecycle —registers→is_qualified_to_load→load_data→resolve→is_qualified_to_present→result_presenter.
The build runs FeatureProviders in two parallel loops: loop 1 fires all async upstream requests, loop 2 waits on results and composes components. ("The latest CHAOS backend framework introduces the next generation of builders using Python asyncio, which simplifies the interface" — a future post will cover this.)
Element model¶
Components and actions are JSON strings inside a stable GraphQL schema (concepts/json-string-parameters-for-schema-stability):
ChaosJsonComponent{ identifier, componentType, parameters }— e.g.componentType: "chaos.button.v1"withparameters: "{\"text\": \"Find local businesses\", ...}".ChaosJsonAction{ identifier, actionType, parameters }— e.g.actionType: "chaos.open-subsequent-view.v1"withparameters: "{\"viewId\": \"consumer.view_two\"}".
Backend Python dataclasses (TextV1, ButtonV1,
IllustrationV1, OpenUrlV1, OpenSubsequentView,
ViewPlaceholderV1, …) type-check the element content before
serialisation.
Client capability matching¶
A FeatureProvider.registers returns a list of Register
entries, each carrying a Condition(platform=[...],
library=[...]) and a presenter_handler. First matching
condition wins; if no register matches the requesting client,
the feature is omitted from the response. This is how
Yelp keeps old app versions working while new components ship
— see
concepts/register-based-client-capability-matching.
Error isolation¶
Every FeatureProvider is wrapped in an error decorator
(patterns/error-isolation-per-feature-wrapper). An
exception in one feature drops that feature only; the rest
of the view still renders. Developers can flag a provider as
IS_ESSENTIAL_PROVIDER = True to opt out — if the feature is
"essential," its failure fails the whole view.
Failure logs include feature name, owner, exception details, and request context — used for threshold-based alerting and owner-team notification.
Advanced primitives¶
- View Flows —
ViewBuilder.subsequent_views()returns additional ViewBuilder classes whose output is packed into the same response'sviewsarray. Navigation happens locally viachaos.open-subsequent-view.v1actions — no network round-trip. Canonical example: Yelp for Business customer-support FAQ menu. See patterns/preloaded-view-flow-for-predictable-navigation. - View Placeholders —
ViewPlaceholderV1embeds a nested CHAOS view that the client fetches asynchronously after rendering the parent. Configurable loading / error / empty / header / footer component IDs and anestimatedContentHeightfor layout stability. Production example: Yelp for Business home screen embeds the Reminders feature (served by a different CHAOS backend) as a placeholder. See patterns/view-placeholder-async-embed.
Component vocabulary: Cookbook + Konbini¶
CHAOS serves UI components from Yelp's cross-platform design
system Cookbook. The
Konbini library family auto-
generates four platform-specific libraries (Kotlin, Swift,
Python, TypeScript) from a single JSON interface
definition per Cookbook component. Every CHAOS backend at
Yelp instantiates the same generated Python classes (e.g.
CookbookButton(text=..., style=..., on_click=..., size=...,
background_color=...)); those instances serialise to a JSON
wire format that Konbini-generated client libraries
deserialise into identically-shaped interface models. A
hand-written per-platform render extension
(CookbookButtonInterface.Render on Android Compose, etc.)
binds the deserialised model to the platform-native Cookbook
widget family. See
patterns/single-json-spec-to-multi-platform-codegen.
Konbini is also where CHAOS solves backward compatibility at component-version granularity (below the feature-level Register- based matching that operates at Register granularity):
- Each client bundles a
spec file listing the
component versions it supports (e.g.
android@23.0:{"cookbook.Button": "1.0", "cookbook.ButtonStyle": "0.1"}). - Every CHAOS request carries a Konbini context
(
spec_name@spec_version). - Backend picks the highest compatible component version per
spec; falls back to a
migrate()function to downgrade to the previous major when needed. - Major bumps
(e.g. Button
0.8 → 1.0whentext: Stringchanges totext: FormattedText) are the only trigger for a migrate function; additive changes are minor bumps requiring no backport.
See patterns/spec-version-negotiation-for-backward-compat and patterns/migrate-function-for-component-downgrade.
Known tradeoffs¶
- GraphQL schema stability bought at the cost of losing per-element schema validation in GraphQL introspection (payloads are opaque strings). Backend dataclasses and client-side renderers must agree out-of-band.
- Register-based capability gating is first-match and order- sensitive; correctness depends on most-specific-first ordering.
- Two-loop build pattern is a pre-asyncio design; an asyncio- native redesign is in flight.
- No disclosed operational numbers (latency, RPS, cache hit rates) — the post is an architecture walkthrough, not a retrospective.
Seen in¶
- sources/2025-07-08-yelp-exploring-chaos-building-a-backend-for-server-driven-ui — the backend deep-dive canonicalised by the wiki. The 2024-03 CHAOS introduction post has not been ingested.
- sources/2026-04-22-yelp-how-yelp-keeps-server-driven-ui-consistent-across-four-platforms
— follow-up unpacking Konbini + Cookbook, the
cross-platform codegen layer beneath CHAOS. Discloses the
{name, raw_value}design-token wire format, the spec-version negotiation for backward-compat, and themigrate()function pattern for component-version downgrade.
Related¶
- systems/apollo-federation — the GraphQL substrate
- systems/strawberry-graphql — Python subgraph library
- systems/yelp-konbini — the codegen bridge from Cookbook component interfaces to per-platform serialisation libs
- systems/yelp-cookbook — Yelp's cross-platform design system; CHAOS serves its components via Konbini
- concepts/server-driven-ui
- concepts/register-based-client-capability-matching
- concepts/json-string-parameters-for-schema-stability
- concepts/client-spec-version
- concepts/component-version-migrate-function
- patterns/federated-graphql-subgraph-per-domain
- patterns/feature-provider-lifecycle
- patterns/two-loop-parallel-async-build
- patterns/error-isolation-per-feature-wrapper
- patterns/preloaded-view-flow-for-predictable-navigation
- patterns/view-placeholder-async-embed
- patterns/single-json-spec-to-multi-platform-codegen
- patterns/spec-version-negotiation-for-backward-compat
- patterns/migrate-function-for-component-downgrade
- companies/yelp