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 design-system compliance of a UI component. It combines four independent dimensions: how complex the component’s API is, how complete its variant grid is, how large its theoretical state space is, and how well its visual values are tokenized.
A CHI of 100 represents an ideal component: lean API, complete variant coverage, and fully tokenized anatomy. A CHI near 0 indicates a component that is overloaded, undertokenized, or combinatorially bloated — making it hard to maintain and risky to evolve.
The CHI is calculated automatically on every sync and displayed in the Audit (CHI) tab of each component’s detail panel.
Why Does Grails Include the CHI?
Design systems accumulate complexity silently. Properties added ad hoc, variant states that were never cleaned up, and style values hardcoded in anatomy frames — none of these feel dramatic in isolation, but their combined effect erodes a system’s reliability over time. The CHI exists to give teams an objective, auditable signal before that complexity becomes a production risk.
The CHI is especially useful for:
- Design leads — identify which components need a refactor sprint before they block engineers.
- Engineers — understand the maintenance overhead of a component before adopting it in code.
- Product managers — monitor the overall health of the design system over time.
Status Ranges
| Score | Status | Meaning |
|---|---|---|
| ≥ 95 | ✨ OPTIMAL | The component is lean, well-tokenized, and fully maintainable. |
| 60 – 94 | ✅ GOOD | Healthy component with minor room for improvement. |
| 30 – 59 | ⚠️ MONITOR | Complexity is elevated. Watch for growth before it becomes a burden. |
| < 30 | 🔴 POOR | 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 metrics. Each metric has a specific weight:
| Metric | Abbrev. | Weight |
|---|---|---|
| Property Overload | PO | 20% |
| Design Coverage | DC | 15% |
| API Surface | AS | 25% |
| Token Adherence | TA | 40% |
Each metric’s penalty is capped at 1.5× its weight to prevent a single extreme value from collapsing the entire score. The final CHI is 100 − (sum of all penalties), clamped to the 0–100 range.
Metrics
PO — Property Overload
What it evaluates: The number of props the component exposes relative to a healthy ceiling of 15 properties. An API with more than 15 properties is hard to document, hard to test, and risky to change — each new property multiplies the possible states that consumers can invoke.
Penalty grows: linearly as the prop count exceeds 15 (capped at 1.5×).
How to fix it: Group related props (e.g., collapse
paddingTop+paddingBottominto a singlepaddingprop). Prune rare configurations that no real consumer uses. Favor composition over configuration by providing focused sub-components instead of a single mega-component.
DC — Design Coverage
What it evaluates: The ratio of physically designed variants to the theoretical variant grid — the complete set of combinations derivable from Variant-type properties. It penalizes gaps in the grid, which signal incomplete or internally inconsistent component sets.
A component with size (sm/md/lg) and state (default/hover/disabled) has 9 theoretical combinations. If only 6 are designed, DC flags the 3 missing ones as structural debt.
How to fix it: Complete the missing combinations in the variant grid. Alternatively, refine the component’s API to make impossible states logically unreachable — for example, by making two properties mutually exclusive through a single combined property.
AS — API Surface
What it evaluates: The total combinatorial complexity of the component’s API, accounting for all interactive property types — Variant, Boolean, and Slot/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 Slot multiplies it by the number of accepted values. AS captures this theoretical complexity growth even when the physical variant count looks reasonable.
How to fix it: Reduce the total number of options across all property types. Critically evaluate every Boolean toggle and every Slot — each one doubles or multiplies the space of states that consumers can accidentally put the component into.
TA — Token Adherence
What it evaluates: The percentage of visual style values in the component’s anatomy that are bound to a design token or Figma Style, rather than hardcoded as inline values. TA is the metric with the highest weight (40%) because untokenized values create drift — they won’t respond to theme changes, mode switches, or design system updates.
TA counts every evaluable style value in the anatomy (padding, margin, corner radius, stroke weight, fill color, text color, background color, and typography) and calculates:
TA % = tokenized values / (tokenized + raw hardcoded values) × 100| TA Score | Status |
|---|---|
| 100% | ✨ OPTIMAL — every evaluable value is tokenized |
| 75–99% | ✅ GOOD — minor raw values present |
| 40–74% | ⚠️ MONITOR — significant hardcoded values |
| < 40% | 🔴 POOR — most values are hardcoded |
How to fix it: Open the component in Figma and apply design tokens (variables) or Figma Styles to fill colors, text styles, spacing values, and border radii. After re-syncing via the plugin, the TA score will update automatically.
When the CHI is Not Available
Component has no properties
The CHI is only calculated for components that have at least one Figma property defined. Icon-only frames or purely visual assets with no API surface are excluded. This is intentional — they have no structural complexity to measure.
Component needs re-sync
If you open the Audit tab and see a “CHI score available after re-sync” message, the component was last synced before the current CHI engine was deployed. Re-syncing from the Figma plugin will recalculate all four metrics and update the score automatically.