Design · August 23, 2026

Design Systems Need a Forkable Core — Not Another Component Library

By Anika Sarder · Digital Marketing Specialist

The component-library trade-off is finally visible

Most design-system teams still offer consumers a false choice: adopt the central library and inherit its brand and release cadence, or copy the parts you need and accept that accessibility, fixes, and upgrades are now your problem. The next generation of design systems will separate a durable behavioral core from a replaceable expression layer.

That is not a prediction based on aesthetics. It is the architecture already emerging in production systems. Meta’s Astryx makes behavior, accessibility, and quality independent from brand-level theming. Atlassian is organizing its system into core, platform, and app layers, then adding a context layer that agents can consume. Singapore’s Government Design System uses Web Components and shadow DOM to keep component internals testable while admitting that page-level patterns remain a shared responsibility. Spotify has spent years designing APIs that move from configuration to slots to full composition instead of forcing every use case into one abstraction.

Together, these examples point to a practical rule: centralize what must remain correct; make identity and composition easy to replace. A design system that cannot be adapted without a fork will eventually be forked. A system that exposes only copy-paste snippets will eventually lose the guarantees that justified having a system in the first place.

Why the old adoption model breaks

A design system is often described as a library of reusable components. In practice it is a dependency relationship between a platform team and every product that consumes its decisions. That relationship has two failure modes.

The first is the branded package. A team imports a central Button, Modal, or Card, but the component carries assumptions about color, typography, spacing, motion, markup, framework, or analytics. The consumer can configure a few props, but the first genuinely different product requirement produces overrides. Those overrides become a local dialect. The central team adds another prop to accommodate it. Eventually the component API becomes a map of historical exceptions.

The second is the copy-paste package. A team copies a component because it needs freedom or cannot wait for the next release. This feels fast until the copied component needs a keyboard fix, a contrast correction, a browser workaround, or a security update. The fork is now a maintenance obligation, and the central system can no longer measure or improve its real usage.

Meta describes this exact dilemma in the announcement for Astryx: adopt a large system and inherit someone else’s brand, or use copy-paste collections and lose shared coherence, upstream fixes, an upgrade path, and accessibility ownership. Astryx’s proposed boundary is unusually clear: the system controls behavior, accessibility, and quality; tokens control color, typography, radius, and motion (Meta’s Astryx announcement).

That boundary is more useful than the usual “flexible versus opinionated” debate. It tells a team which freedoms are safe. Brand expression is usually safe to vary. Interaction semantics, focus behavior, keyboard support, and accessible names are not safe to vary casually.

The result is a design system with two different kinds of API:

LayerCentral system should ownConsumer should be able to change
BehaviorKeyboard behavior, focus management, state transitions, event semanticsDomain-specific orchestration around the component
AccessibilitySemantic structure, accessible names, tested states, contrast defaultsPage-level semantics and content-specific alternatives
Visual foundationToken roles, spacing scales, motion contractsBrand values, themes, density, typography choices
CompositionStable primitives and documented slotsLayout, content, analytics, routing, product-specific regions
DistributionVersioning, deprecation, tests, migration toolsFramework adapter or delivery method where practical

The important distinction is not “shared code versus local code.” It is shared guarantees versus local expression.

The durable core is behavioral, not visual

The core of a design system should be the smallest surface that can make a promise and test that promise. For a button, that may include native button semantics, disabled behavior, focus-visible styling, loading state, and an explicit contract for an accessible name. It should not require every product to adopt the same border radius or brand color.

A tokenized implementation makes this boundary concrete. The component consumes semantic roles; the theme supplies values.

/* behavioral component contract */
.ds-button {
  min-block-size: var(--control-size-md);
  padding-inline: var(--control-padding-inline);
  border: 1px solid var(--button-border);
  border-radius: var(--control-radius);
  background: var(--button-background);
  color: var(--button-foreground);
}

.ds-button:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: var(--focus-ring-offset);
}

/* brand expression: replaceable at the theme boundary */
[data-brand="acme"] {
  --button-background: oklch(52% 0.19 260);
  --button-foreground: white;
  --control-radius: 0.375rem;
}

The snippet is not a claim that CSS solves design-system architecture by itself. It demonstrates a useful ownership boundary: a component owns which states exist and how they are reached; a theme owns the values that express those states.

The accessibility side of that contract must be explicit. The W3C’s WCAG 2.2 guidance requires a 4.5:1 contrast ratio for normal text and 3:1 for large text, with defined exceptions (W3C’s contrast guidance). A theme system that lets brands replace foreground and background tokens therefore needs automated contrast checks. “The token is customizable” cannot mean “the token is exempt from the product’s accessibility bar.”

Singapore’s Government Design System shows what enforcement looks like in a real implementation. Its CI pipeline runs Oobee accessibility scans across component pages before each release. The team forwards an ariaLabel property through a Web Component’s shadow DOM to the native button, and it tests the rendered documentation site as well as the component source. Shadow DOM gives the team stronger control over internal markup than a light-DOM snippet would, but the team explicitly notes that it cannot make an entire page accessible: developers still control surrounding semantics, such as whether list content uses li elements (SGDS’s engineering account).

That limitation is a feature of the model, not an embarrassment. A core can guarantee component-level behavior. It cannot pretend to own every composition around the component. Good architecture states where the guarantee ends and supplies tests for the next layer.

Composition is the escape hatch that prevents prop inflation

A central library becomes brittle when every variation is expressed as another prop. The component starts with title, description, and icon; then arrives titleIconPosition, footerMode, analyticsId, compactHeader, contentDensity, and a boolean for each exception. The API is technically reusable but cognitively expensive.

Spotify’s Encore team describes a better abstraction spectrum: configuration for standard cases, slots for small modifications, and custom composition for complex cases. A consumer can pass data to receive a complete default, replace a subcomponent when it needs a small change, or use the primitives directly when the default is genuinely wrong. Spotify also reports that slot analytics can reveal which overrides are common enough to become a better default (Spotify Engineering on multiple abstraction layers).

A React-shaped API makes the boundary legible:

<Card
  title="Quarterly report"
  image={<CardImage src={report.cover} alt="" />}
  footer={
    <CardFooter>
      <Link href={report.url}>Open report</Link>
    </CardFooter>
  }
/>

The default path remains easy. The footer can carry product-specific routing and analytics without forcing the central Card to know either. If the system later changes spacing or focus behavior, the consumer still receives those fixes because it has composed from the core rather than copied the implementation.

The rule for slots is that they should expose meaningful regions, not internal DOM trivia. A CardFooter slot is a stable design decision. A prop that targets the third div inside the footer is an accidental coupling. Slots also need accessible defaults: if a consumer omits a label, the component should fail clearly in development or provide a safe semantic default where one exists.

This is where a forkable core differs from a permissive component. Permissiveness means every internal detail is available to override. Forkability means the stable guarantees are portable, while the expression and composition points are intentional.

Three production patterns converge on the same architecture

The strongest evidence is not one vendor’s announcement. It is the convergence between systems built for different jobs.

Meta separates quality from brand. Astryx is presented as an open-source system with more than 150 accessible components, brand-level theming, dark mode, templates, and a CLI. Meta says the system has matured over eight years inside the company and powers more than 13,000 apps. Those numbers describe scale, but the architectural point is more important: customization is positioned at the token layer instead of requiring a rewrite.

Atlassian separates organizational scope from composition. Its core, platform, and app tiers provide shared structure without insisting that a central team make every product decision. The Panel example uses a constrained shell, reusable primitives, and purposeful slots. Atlassian says its internal evaluations found a 52% accuracy improvement in AI calls, 34% faster average performance on ADS-specific tasks, 26% fewer tooling calls, and 16% lower token usage after adding structured context. Those are Atlassian’s reported internal results, not a universal benchmark, but they show why the same ownership boundary matters to agents: explicit tokens, semantics, and intent are easier to select than a visual library alone (Atlassian’s design-system context engine).

Monzo separates editorial autonomy from engineering quality. In its 2026 redesign of Monzo.com, the team identified seven page templates and created a 13-point scorecard before pages reached customers. It built modular blocks for marketing managers, aligned Figma and code APIs, and reported a 9.7% conversion uplift on its first pilot page. The practical lesson is not that every design system should copy Monzo’s scorecard. It is that the reusable unit was a tested page composition with room for content teams to assemble it, not a rigid page that required an engineer for every change (Monzo’s case study).

GitHub separates internal acceleration from portable distribution. GitHub describes using Catalyst and ViewComponent inside its codebase, then extracting components into dependency-free Web Components when they become generic enough for wider use. Its open-source component requirements included being framework- and library-agnostic, lightweight, style-free, decoupled, typed, tested, and linted. That is a lifecycle boundary: experiment locally, generalize only after production learning, then distribute a smaller contract (GitHub’s Web Components workflow).

These systems do not use identical technologies. That is why their common boundary is credible. The pattern survives React, Web Components, CMS templates, AI context files, and multi-product governance.

How to design a forkable core

A forkable core is not a license to abandon governance. It needs sharper governance than a library that simply hopes consumers will not override it.

1. Write guarantees before APIs

For each primitive, document what the system owns: keyboard interaction, focus order, semantics, state transitions, test coverage, and supported themes. Then document what it deliberately does not own: page layout, business validation, routing, analytics, or product-specific content. This turns “flexibility” into a contract.

2. Put brand decisions behind semantic roles

Do not make consumers override #3b82f6 in a component. Give them a role such as --action-background and define the contrast and state behavior around it. Keep primitive values, semantic roles, and component aliases distinct so a brand change does not require rewriting every component.

3. Offer three paths, not one giant component

Provide a ready-made default for common cases, purposeful slots for bounded variation, and low-level primitives for genuinely novel compositions. Track which slots and overrides are used. A repeated escape hatch is evidence about the system’s next useful default, not proof that the consumer should be disciplined harder.

4. Test the boundary where consumers actually work

Component tests are necessary but insufficient. Run accessibility checks on component states, themes, and representative compositions. Test documentation examples. Add lint rules or codemods for deprecated patterns. SGDS’s distinction between component internals and page-level semantics is the right mental model: enforce what the core controls, and make the remaining responsibility visible.

5. Ship context with the code

An agent, designer, or new engineer needs more than a component name. Include the component’s intent, when not to use it, valid composition patterns, accessibility requirements, token roles, and migration guidance in a machine-readable format. Atlassian’s context files, MCP server, templates, and skills make this explicit. This also extends the argument in why component contracts are replacing design-system documentation: the contract should describe decisions, not just display a screenshot.

6. Make “fork” a controlled lifecycle state

Sometimes a product really does need a fork. Define what qualifies: a different platform constraint, a divergent interaction model, or a product boundary that makes shared release cadence unreasonable. Record the fork’s inherited guarantees, its owner, its upgrade path, and the signals that would let it graduate back into the core. A fork with no provenance is a copy; a fork with a contract is an experiment.

The counterargument: central control can be safer

A single branded library is sometimes the responsible choice. A regulated product may need one controlled implementation, one audit trail, and one release process. A small team may not have the staff to maintain themes, adapters, slots, and cross-browser tests. A component with complex security or payment behavior should not become arbitrarily replaceable just to satisfy a styling preference.

The answer is not to make every layer forkable. It is to locate the non-negotiable boundary. Payment fields, authentication flows, and security-sensitive controls may centralize more behavior and presentation than a marketing Card. A design system should classify components by risk, not apply one abstraction policy to all of them.

The cost of the forkable-core model is real: more documentation, contract testing, theme validation, versioning discipline, and contribution tooling. It also introduces decisions that a monolithic package hides. That cost is worthwhile only when multiple products, brands, platforms, or autonomous teams need to move independently. For a single application with one brand and one release train, a smaller local component library may be the better engineering choice.

The decision to make this quarter

Audit five of your most overridden components. For each one, separate the behavior that consumers rely on from the visual values they replace. If the same component has a growing list of props, draw its composition regions. If a copied component has received an accessibility or browser fix more than once, move that behavior into a tested core.

Then ask three questions:

  1. What must never fork? Put it in the core and make it testable.
  2. What should vary by brand or product? Express it as semantic tokens, themes, or slots.
  3. What is still experimental? Keep it local until real usage proves it deserves a stable contract.

The design system’s future is not a choice between central control and unrestricted freedom. It is a better division of ownership. Central teams should protect behavior, accessibility, and intent. Product teams should control expression and composition within explicit boundaries. Agents should receive the same contract humans use to make those decisions.

That is how a system remains coherent without becoming a bottleneck—and adaptable without dissolving into copies.

Ready To Scale
Your Ecommerce?

Let Decipher Tech handle your ecommerce operations end-to-end. Our ECOMAS model means you get a full team of specialists without the overhead of hiring in-house.