skip to content

How would you roll out a new design-system lint rule, such as banning a deprecated component, across forty product repositories without breaking everyone's builds?

level: seniorimportance: should knowfreq 32%

answer

  1. measure before you enforce
  2. warn, then block new, then block all
  3. baseline the existing violations
  4. a shared config, versioned
  5. a date tied to removal

basics

~10 s

Ship the rule as a warning and measure; then block only new violations against a per-repository baseline; then burn the baseline down and block everything by a date tied to the component's removal.

solid answer

~50 s

I would never switch on an error-level rule across forty repositories in one release: builds that were green turn red without anyone changing their code. Instead: **measure** — ship the rule as a warning in the shared lint configuration and collect violation counts per repository, which also tests the rule for false positives. **Block new** — record each repository's existing violations as a baseline and fail CI only on new ones, so the problem stops growing immediately. **Burn down** — give teams the replacement, migration guidance and the removal date, and track counts centrally. **Block all** — when the baseline reaches zero, or at the announced date tied to the component's removal, promote the rule to an error. Because a new error-level rule in a shared configuration can fail consumers' builds, many teams release that step as a MAJOR version under semantic versioning.

go deeper

for a junior

Recall that a new blocking rule can fail builds without anyone changing code, so rules are introduced gradually, starting as warnings.

for a middle

Explain the four stages — measure, block new, burn down, block all — and why a per-repository baseline lets you stop growth before the cleanup is done.

for a senior

Show how you would run the rollout across many teams: false-positive fixes in stage 1, migration guidance and tooling, a date tied to removal, and releasing the configuration change with the right version signal.

for a principal

Weigh how fast the system can enforce change against the product teams' capacity, and when a deadline should move because the replacement, not the team, is the problem.

## The problem with switching a rule on A design system usually ships its lint rules as a **shared configuration** that every product repository installs. Adding a new rule at error level to that configuration and releasing it means that, the next time forty repositories update, some of their builds fail — though nobody in those teams changed anything. Teams respond predictably: pin the old configuration, disable the rule, or add suppressions in bulk. All three defeat the rule's purpose and cost the system goodwill. The goal is to get to **enforced everywhere** without a day when everything breaks. ## A staged rollout | Stage | What the rule does | Purpose | |---|---|---| | 1. Measure | Warns only; CI reports counts centrally | Size the problem; find false positives | | 2. Block new | Fails CI on violations beyond each repository's baseline | Stop the problem growing | | 3. Burn down | Same as stage 2, with the baseline tracked and falling | Remove existing uses team by team | | 4. Block all | Error level, no baseline | Enforce the end state | ### Stage 1: measure The warning-only release answers questions you cannot answer from the system team's desk: - How many uses exist, and where are they concentrated? - Does the rule flag things it should not — a wrapper around the replacement, test fixtures, generated code? - Which teams have the most work, and do they know it yet? Fix false positives now. A rule that cries wolf at stage 4 will be suppressed in bulk. ### Stage 2: block new Record each repository's current violations as a **baseline** and fail CI only on violations beyond it. From this moment the problem stops growing, which is the most important step, and it costs teams nothing today. ### Stage 3: burn down Enforcement without help is just pressure. Teams need: 1. The **replacement** and a short guide showing the old usage next to the new. 2. **Migration tooling** where the change is mechanical. 3. The **date** after which the rule becomes an error — tied to when the deprecated component is removed, so the rule and the removal tell one story. 4. A **central view** of remaining counts per team, so progress is visible and stragglers are known early. ### Stage 4: block all When baselines reach zero, or at the announced date, promote the rule to error level with no baseline. By then, very few repositories should notice. Before promoting: - confirm the remaining counts are zero, or agree reasoned exceptions for the stragglers; - announce the release and the date again, in the same channel as the deprecation; - keep the rule's message pointing at the replacement, since the error will be the first thing a late team reads. ## Releasing the configuration The shared lint configuration is a versioned package, and its consumers deserve the same care as consumers of the components. Under semantic versioning, a MAJOR version signals incompatible changes. Many teams therefore treat **adding an error-level rule** as a breaking change and release it as a MAJOR version, while adding a warning is released as a MINOR version. Either way, the release notes name the rule, why it exists, the replacement and the timeline. ## Review as well as CI Lint and CI catch uses mechanically, but review still matters during the rollout. A **bot comment** on a change that adds a new use of the deprecated component, linking the replacement, often works better than a failed build during stages 1 to 3 — it teaches at the moment of writing. Human reviewers can then spend their attention on whether the replacement is used correctly. ## An example in an e-signature product The system is deprecating an old file-upload component in favour of a new one with better keyboard support and progress reporting. The e-signature product's document-upload screens use the old one in six places. In stage 1, the team sees a warning and a count of six. In stage 2, adding a seventh fails CI. In stage 3, the team migrates the six using the guide, the baseline falls to zero, and when the system removes the old component in its next major release, the rule's promotion to error changes nothing for them.

  • Why block new violations before the old ones are fixed?
    Because it stops the problem growing immediately at almost no cost to teams. Without it, the burn-down races against new uses being added every week; with it, every migrated use is permanent progress, and the final switch to error level becomes a formality rather than a cliff.
  • What do you do about a team that cannot migrate before the deadline?
    Find out why. If the replacement lacks something they need, that is a system gap to close, and the deadline may need to move. If it is capacity, agree a reasoned, time-limited exception visible to the system team, rather than letting them pin an old configuration and silently fall behind every later rule.

saying these in an interview costs you the question

  • Add the rule at error level in the next release; teams will adapt.
  • A warning-only rule is pointless because everyone ignores warnings.
  • Existing violations must all be fixed before any enforcement starts.
  • Adding an error-level rule to a shared config is a patch-level change.
  • Teams that pin an old lint configuration are simply not following process.