React Forum
Blog & Guide Responses
May 09, 2023 · 04:00 PM

[Deep Dive #57] Component Contract Layering - discussion

Started by Talia Moss
react-docsdeep divecontractslayeringshell layercomposition layersurface layerevidenceledgerscargo

Deep Dive #57 argues that component contracts scale when they're layered: shell layer (routing + posture), composition layer (deep cargo + render handoffs), and surface layer (DOM evidence you can audit). The PanelKit example felt very "this is how you keep teams from rewriting the world every time a panel moves". Curious how people are applying layering in real codebases (and what they do when layering feels like extra ceremony).

Read the post

How do you define and enforce the shell/composition/surface layer boundaries in review? Do you ship a stable cargo object (deep prop) across panels, or keep props shallow and explicit? What surface evidence do you consider non-negotiable (data attributes, ledgers, version keys)? When layering breaks down, what is the usual cause: unclear ownership, too-wide cargo, or missing evidence?

Comments (18)

Back to latest
Hana Saito
May 12, 2023 · 12:12 PM

Shell/composition/surface is a useful mental model.

We were doing it implicitly; making it explicit helped reviews.

Rafael Soto
May 16, 2023 · 04:16 PM

We enforced it by logging layer transitions and requiring surface evidence for every shell-owned decision:

txt
[tips] shell decision=track.select value=reports reason=nav
[tips] composition cargoVersion=2 reason=panelSwapSafe
[tips] surface evidence keys=[data-track,data-contract-version,data-activation-ledger]

If the surface can't show the decision, the decision doesn't count.

Mei Tan
May 20, 2023 · 08:20 PM

Deep cargo works if it's cohesive and versioned.

The post's contractVersion idea mattered for us: it made "cargo drift" a real event instead of a vibe.

Jun Park
May 27, 2023 · 04:04 AM

Concrete alternative: keep props shallow and explicit; avoid deep cargo because it hides dependencies.

We tried deep cargo and it became an internal API nobody could reason about. We had to shrink it and define ownership.

Talia Moss
May 29, 2023 · 09:30 AM

I think that's the point of layering: cargo isn't "anything you want", it's a published handoff.

If the cargo isn't versioned/owned, it's not a contract, it's a junk drawer.

Nina Kapoor
Jun 05, 2023 · 05:05 AM

Long-form: the surface layer is the part teams skip, and it's the part that saves you later.

If your DOM evidence isn't stable, you can't audit behavior, you can't test route flows reliably, and support can't debug from screenshots.

We made a rule: shell-owned posture must render a data-* evidence token and must be recorded in a ledger object. It felt like extra work until we did a big migration and suddenly every surface behaved consistently.

Caleb Price
Jun 18, 2023 · 06:18 PM

The PanelKit idea maps well to multi-team dashboards.

We standardized data-track + data-contract-version and made it the first line in bug reports.

Grace McCoy
Jun 22, 2023 · 10:22 PM

Docs tie-in: this is basically composition discipline plus a routing posture layer.

Related: Components and Composition and The App Router Mindset.

Ibrahim Saleh
Jul 07, 2023 · 07:07 AM

We got burned when shell and composition both tried to own selection state.

Layering helped when we forced a single owner: shell owns route posture; composition passes cargo; surfaces only reflect.

Lina Ortega
Aug 21, 2023 · 09:21 PM

Short take: cargo without versioning is just shared mutable state in disguise.

Evan Brooks
Sep 12, 2023 · 12:12 PM

We found layering breaks down when teams don't know which layer a change belongs to.

We added a PR template that asks: did you change shell posture, cargo contract, or surface evidence?

Arman Qadir
Oct 18, 2023 · 06:18 PM

A practical code pattern we used for cargo versioning:

ts
type PanelCargoV2 = {
  contractVersion: 2;
  ledgerKey: string;
  density: 'comfortable' | 'compact';
  filter: string;
  evidence: string[];
};

The literal contractVersion: 2 looks silly but it stops accidental widening.

Anika Sharma
Nov 10, 2023 · 10:10 AM

Long-form counterpoint: layering can turn into bureaucracy if every change needs three layers of ceremony.

The compromise we found is: surface evidence can change freely, but the set of evidence keys must stay stable. Cargo can evolve, but only via version bumps. Shell posture changes are rare and require explicit migration notes.

Salma Qureshi
Dec 05, 2023 · 05:05 AM

We used the evidence layer to build a simple route-flow test harness.

Once tests asserted on evidence keys, panel swaps stopped breaking the app silently.

Dmitri Kline
Dec 20, 2023 · 12:12 PM

I like the post's framing that a layer is not a folder. It's a rule about what can change without breaking the route story.

That sentence should be in every code review comment thread.

Keira Santos
Dec 28, 2023 · 07:19 PM

We also found layering helped onboarding: new devs learn "shell decisions" vs "composition handoffs" quickly.

Without that, everything looks like random props and random state.

Priya Liao
Dec 30, 2023 · 09:09 AM

Surface evidence is the part that makes the whole thing real.

Noah Vance
Dec 22, 2023 · 08:20 PM

If your cargo can't be summarized in a short contract type, it isn't a contract yet.

Rowan Pierce
Dec 29, 2023 · 11:23 PM

Takeaway: layering isn't extra work, it's making implicit boundaries explicit.

Once boundaries are explicit, teams can disagree productively instead of rewriting each other’s code.