In a design system, what should a product engineer do when a shared component lacks a variant their feature needs?
answer
- check before you ask
- docs, variants, usage guidelines
- describe the need, not the pixels
- bridge with public system parts
- keep the gap visible and reversible
basics
~20 sCheck the docs for an existing variant or guidance first, then raise the gap through the contribution process, and meanwhile build a local composition from system tokens and primitives instead of forking or overriding the shared component.
solid answer
~40 sFirst confirm the gap is real: the docs may show an existing variant, a documented composition, or a usage guideline saying the pattern is deliberately unsupported. If it is a genuine gap, open a proposal that describes the **user need and context**, not just a mock, so the system team can classify it as a fix, an enhancement or a new component and say who builds it. While that is pending, bridge locally by composing system tokens and primitives, in a clearly labelled local place linked to the proposal, so it can be swapped out later. What you avoid is overriding the shared component's internals, copying its source, or building silently: those break on later releases, never receive fixes, and hide the need from the team that could solve it once for everyone.
go deeper
Recall the order: check the docs, raise the gap through the contribution route, and bridge with a local composition of system parts rather than overriding or copying the shared component.
Explain why overrides and copies break: they depend on internals the system may change in any release, and they never receive fixes. Show how a good proposal lets the system team classify the request.
Show judgement under deadline pressure: a labelled local composition linked to the proposal, a plan to swap it out, and adding your evidence to an existing request instead of filing a duplicate.
Frame consumer-reported gaps as the system's main signal of what to build next, and explain how silent workarounds make a system look adopted while product UI drifts away from it.
## The situation A **design system** is a shared set of design decisions, tokens, components and guidance that many product teams consume. Sooner or later a product engineer hits a gap: the shared component does almost what the feature needs, but not quite. On an online learning platform, for example, a course page may need a progress bar that shows completed modules as separate segments, while the system's progress bar only shows one continuous fill. How the engineer handles that gap decides whether the system gets better or quietly erodes. The short version: **confirm the gap, raise it through the contribution process, and bridge it locally without damaging the shared component.** ## Step 1: confirm the gap is real Many apparent gaps are not gaps. Before asking for anything, check: - **The documentation's variants and examples.** The need may already be met by a variant, a size or a documented composition of existing parts. - **The usage guidelines.** The docs may say the pattern is deliberately unsupported, for instance because it failed usability or accessibility review. That is an answer, not an oversight. - **Open proposals and requests.** Another team may already be asking for the same thing; adding your use case to theirs is worth more than a duplicate request. - **Whether the need is really inside the component.** Sometimes the feature needs different content or layout around the component, not a change to the component itself. ## Step 2: raise it through the contribution process If the gap is genuine, tell the system team through whatever route the **contribution guidelines** name, usually a short proposal or issue. A useful proposal describes the **problem and its context**, not a finished design: 1. The user need and where it appears (the course page, the lesson list). 2. What the current component cannot express, with a screenshot or a rough drawing. 3. How many screens or teams might need it, if known. 4. The deadline pressure, so the system team can plan honestly. This lets the system team classify the request: a **fix** if the component is failing its own spec, an **enhancement** if it needs a new option, or a **new component** if the need is different in kind. It also lets them say whether they will build it, want the requesting team to build it under their review, or recommend keeping it local. ## Step 3: bridge locally without breaking the system Features rarely wait for a system release, so the engineer often needs something now. The safe bridge is **composition from public system parts**: build the segmented bar in the product's own code out of the system's tokens and smaller primitives, keep it in a clearly named local location, and link it to the proposal so it can be replaced when the system version ships. ## What not to do | Tempting move | Why it is tempting | What it costs | |---|---|---| | Override the shared component's internal styling | Fast, one small change | Breaks silently when a later release restructures the internals | | Copy the component's source into the app | Full control | A fork that never receives the system's fixes, including accessibility fixes | | Hard-code the mock's raw values | Matches the design file exactly | Misses theme and brand changes that tokens would carry | | Build locally and tell nobody | No process overhead | The system team never learns about the need; the next team builds it again | The common thread is **invisibility**: each of these hides the need from the people who could solve it once for everyone, and each creates code that diverges further with every system release. Internal structure and private styling are not part of a component's public contract, so the system team is free to change them without warning. ## Why this matters beyond one feature A design system improves largely through the gaps its consumers report. Consumers who silently work around it make the system look complete while product UI drifts away from it. Consumers who raise gaps give the system team evidence about what to build next and which components are too rigid. The engineer's job is neither to wait for the system nor to bypass it, but to keep the gap **visible and reversible**: raise it, bridge it with system parts, and swap in the shared version when it arrives. The same behaviour applies on every platform the system serves. A native mobile team facing a missing variant in the mobile component set follows identical steps: check the docs, propose, compose locally from the system's tokens and primitives, and replace the local version once the shared one ships.
- When is it acceptable to wrap a shared component rather than compose a new local one?When the need is extra behaviour or content around the component, not a change inside it. A wrapper that uses only the component's public options and adds surrounding layout stays compatible with future releases. It becomes risky when it reaches into internal structure or restyles private parts, because those are not part of the component's contract and can change in any release.
- The system team says the requested variant is out of scope. What now?Ask why: the pattern may be excluded for usability or accessibility reasons, and an alternative may already exist. If the need still stands, keep a local composition built from system tokens and primitives, own it in the product codebase, and label it as local so nobody mistakes it for a system component. Revisit the request if other teams report the same need.
saying these in an interview costs you the question
- Overriding the shared component's internal styling is a quick and safe fix.
- Copying the shared component's source into the app is a harmless shortcut.
- A feature must be blocked until the system ships the missing variant.
- A missing variant means the design system simply does not apply to this feature.
- A gap is only worth reporting once you can hand over a finished design.