design systems
Enterprise design system at scale
A platform serving millions had no shared component language. We built one — without breaking anything in production.
- Role
- Lead UX Engineer
- Platform
- Fortune 200 Banking Platform
- Timeline
- 2021–2023
- Team
- 4 engineers · 3 designers · 2 accessibility specialists
200+
from 0
Templates governed
~0
from 47
WCAG violations
Eliminated
for standard authoring
Dev dependency
Problem
A fragmented enterprise banking platform had no shared component language — three business units building the same components independently, 47 WCAG violations accumulating, and marketing dependent on engineering for routine content updates.
Approach
Diagnosed the system as a governance problem, not a component shortage. Extended AEM Core Components via delegation pattern, moved compliance-critical properties out of author dialogs into template policies, reorganized ClientLib dependency graph for deterministic loading.
Outcome
200+ templates governed under a unified system. Accessibility violations at launch: near zero. Author autonomy for standard content publishing restored. Zero production regressions across all rollouts.
The problem
Three business units. Three component implementations. Forty-seven WCAG violations. Every campaign page gated by an engineering sprint.
A Fortune 200 banking platform had grown organically — consumer banking, credit cards, and lending each operating with their own frontend conventions. The result wasn't chaos, exactly. It was something worse: redundancy that looked reasonable until you needed to govern it.
Fragmented ecosystem
3 business units. Independent implementations. 47 WCAG violations. Every campaign required engineering. Accessibility QA discovered post-launch.
Governed platform
200+ templates under a single governed system. Author autonomy for standard content. Accessibility enforced at component level. Zero production regressions.
Three forces made this unignorable simultaneously: an internal accessibility audit, a mandate to accelerate digital delivery, and sustained pressure to reduce engineering dependency in content workflows.
System architecture
The instinct was to build more. The right move was to build less.
An audit revealed the platform already had the components — they'd just been solved three times, differently. The mandate became: consolidate, not create. Extend Adobe's Core Components rather than rebuild them. Move governance to the policy layer, not the dialog layer.
"The challenge wasn't building components. It was introducing governance without disrupting production."
AEM component architecture — layered system model
Adobe Experience Manager
Content repository · JCR · Sling
AEM Core Components
HTL templates · Sling Models · Policies
Design System Layer
Custom components · Token APIs · ClientLibs
Authoring Experience
Dialog APIs · Policies · Editable templates
Frontend Delivery
HTL rendering · ClientLib bundling · CDN
The critical architectural decision: authors control content. The system controls structure. Heading hierarchy, ARIA roles, and semantic constraints moved out of author dialogs and into component policies — properties authors couldn't accidentally misconfigure.
Key decisions
Challenge → Decision → Outcome
Challenge
Decision
Outcome
Fragmented component implementations across 3 BUs
Consolidate via AEM Core Component extensions — build once, govern everywhere
Single component registry
consistent rendering across all business units
Authors misconfiguring heading levels and ARIA roles
Move governance-critical properties from dialogs to policies
Zero accessibility failures from misconfiguration since rollout
CSS cascade collisions between legacy and modernized ClientLibs
Reorganize ClientLib categories by architectural role, not business unit
Deterministic loading order
eliminated specificity escalation
Legacy components co-existing with modernized ones
Delegation pattern — new components wrap existing ones
Backward-compatible rollout
zero content migration required
Decision
Extend AEM Core Components — do not rebuild from scratch
Core Components have solved the hard accessibility and rendering edge cases across years of production use. Extending them kept us aligned with Adobe's update cadence and reduced our long-term maintenance surface significantly.
Tradeoff: Less visual flexibility on some components. Significantly smaller maintenance burden over time.
Decision
Reorganize ClientLib categories to enforce deterministic loading order
CSS loading order was inconsistent across template configurations — an assumption that held in isolation but failed at composition scale. A component belonging to multiple BU categories produced unpredictable cascade behavior.
Alternative: CSS specificity escalation. Rejected: a maintenance trap that compounds with every release.
Outcomes
Accessibility, authoring efficiency, and engineering maintainability aren't competing priorities. Designed correctly at the system level, they reinforce each other.
200+
Templates governed
~0
WCAG violations at launch
Eliminated
Dev dependency for standard authoring
0
Production regressions
Campaign delivery that previously required engineering became self-service for standard configurations. Marketing timelines gated by sprint cycles moved into author-controlled workflows.
Reflection
Instrument before optimizing. We diagnosed from audits and estimates rather than production telemetry. Earlier instrumentation would have identified the ClientLib cascade failure before it became a QA problem — and would have let us sequence component work by actual usage patterns rather than assumed priority.
Define the deprecation contract before the first component ships. Legacy and modernized components co-existed longer than the system needed them to. The deprecation timeline was negotiated per-component rather than defined structurally — which meant each removal was a separate conversation instead of an expected phase of the process.