Component Health Index (CHI)
What is the Component Health Index?
The Component Health Index (CHI) is a mathematical score — ranging from 0 to 100 — that evaluates the structural quality and maintainability of a UI component based on the complexity of its configuration.
A CHI of 100 represents an ideal, lean component: simple API, complete variant grid, no bloat. A CHI near 0 indicates an overloaded component with too many properties, variants, or property combinations that make it impossible to maintain reliably over time.
Why Does Grails Include CHI?
Design systems are living systems. As components evolve through many sync cycles, they tend to accumulate complexity: properties that were added ad hoc, variant states that were never cleaned up, or an API surface that has grown beyond what any engineer can actually use. The CHI exists to give teams an objective, auditable signal about the health of each component before that complexity becomes a production risk.
The CHI is especially useful to:
- Design leads — identify which components need a refactor sprint.
- Engineers — understand the maintenance overhead of a component before adopting it.
- Product managers — track the overall health of the design system over time.
Score Ranges
| Score | Status | Meaning |
|---|---|---|
| ≥ 70 | ✅ Healthy | The component is lean and maintainable. |
| 40 – 69 | ⚠️ Monitored | Complexity is elevated. Watch for growth. |
| ≤ 39 | 🔴 Bloated | Structural complexity is unsustainable. Refactor recommended. |
How the Score is Calculated
The CHI starts at a perfect score of 100 and deducts penalty points based on four independent sub-metrics. Each metric has a specific weight:
| Metric | Weight |
|---|---|
| VDR — Variant Density Ratio | 25% |
| POF — Property Overload Factor | 30% |
| CEI — Combinatorial Exhaustiveness Index | 25% |
| ASAS — API Surface Area Score | 20% |
A high penalty in one metric doesn’t necessarily make the component bloated — the other metrics can compensate. The score reflects the combined structural fingerprint of the component.
Sub-metrics
VDR — Variant Density Ratio
What it evaluates: The absolute number of physically designed variants in Figma compared to a healthy ceiling of 8 variants. It determines whether too many states are being manually designed instead of being handled programmatically.
Exceeding 8 variants starts applying a progressive penalty. The more variants added beyond that threshold, the steeper the deduction.
How to fix it: Consolidate visually similar variants using variables and tokens instead of duplicating frames. If a group of variants represents a fundamentally different component semantically, consider extracting it into its own standalone component.
POF — Property Overload Factor
What it evaluates: The number of props/properties the component exposes compared to a critical limit of 15 properties (also called the “Apropcalypse” threshold). It measures how complex the component’s API is to understand and consume in code.
An API with more than 15 properties becomes hard to document, hard to test, and risky to change — because every new property multiplies the possible states consumers can invoke.
How to fix it: Group related properties (e.g., collapse
paddingTop+paddingBottominto a singlepaddingprop), prune rare configurations that no real consumer uses, and favor composition over configuration by providing focused sub-components instead of a single mega-component.
CEI — Combinatorial Exhaustiveness Index
What it evaluates: The coverage of the physically designed variant grid compared to the theoretically possible combinations derived from Variant-type properties only. It penalizes missing states (gaps in the grid), which signals an incomplete or internally inconsistent component set.
A component with size (sm/md/lg) and state (default/hover/disabled) has 9 theoretical combinations. If only 6 are designed, the CEI flags the 3 missing ones as structural debt.
How to fix it: Complete the variant grid with the missing combinations. Alternatively, refine the component’s API to make impossible combinations logically unreachable — for example, by making two properties mutually exclusive through a single combined property.
ASAS — API Surface Area Score
What it evaluates: The total combinatorial complexity of the component’s API, accounting for all property types — Variant, Boolean, and Instance Swap. It highlights the risk of “combinatorial explosion” even for states that aren’t physically drawn as variants.
Every Boolean property doubles the potential state space. Every Instance Swap multiplies it by the number of accepted components. ASAS captures this theoretical complexity growth even when the physical variant count (VDR) looks reasonable.
How to fix it: Reduce the total number of options across all property types. Critically evaluate every Boolean toggle and instance swap slot — each one doubles or multiplies the space of states your consumers can accidentally put the component into.