Architecture Comparison: Dual vs iris vs iX

Side-by-side comparison of the three CSS architectures. Dual is the POC. iris is the current production system. iX is Siemens Industrial Experience.

Direction: the Dual column is a proof of concept, not a shipping target. iris-core adopts Dual's concepts additively under the iris namespace (dual-output from one source, SUIT classes, a component-token tier) and draws status colors from iX — no separate dual package ships. See research/README.md.

§1 — Size & Scope

MetricDual POCiris-coreiX
Components615116
CSS bundle size51.8 KB (full preset) · 35.1 KB variables-only · +23 KB WC JS185 KB (monolithic)~350 KB (theme + components)
CSS variables322 (--dual-*)~663 (--iris-*)~2,400 (--theme-*)
Token layers3 (ref → semantic → component)2 (base → semantic)3 (core → theme → component)
Component token varscolor-only, per component (button 9, card 5, …)~1 per component25+ per component
JS runtime requiredOptional (WC path only)Yes (Stencil WCs)Yes (Stencil WCs)

§2 — Architecture Comparison

FeatureDualirisiX
CSS-only usage (no JS) ✓ Light-DOM classes ✗ Shadow-encapsulated only ✗ Requires Stencil runtime
Web component output ✓ Same SCSS source ✓ Primary delivery ✓ Primary delivery
Per-component CSS files ✓ Per build output ✗ Monolithic iris.css ◐ In dist/collection/ (unexported)
Component-level token overrides ✓ --dual-button-fill etc. ✗ Global theme only ✓ --theme-button--* vars
CSS variable theming ✓ .dual-theme-dark ✓ .iris-ui-theme-dark ✓ .theme-dark class
SCSS pre-compile override ✓ $var before @use ✗ No public SCSS API ✓ SCSS mixins/vars
Naming convention SUIT CSS (PascalCase) None (mixed kebab) BEM-like (kebab-case)
Utility classes ✓ 93 (u-* SUIT) ◐ 84 typography only ✗ None shipped
Grid system ✓ 49 classes (FlexGrid + CssGrid) ✗ ✗
Token source format JSON (DTCG-inspired) Figma → SCSS SCSS maps → CSS vars

§3 — Token Architecture

AspectDualirisiX
Reference layer 296 JSON tokens (iris + iX sources) ~150 SCSS vars in base-variables/ SCSS maps in theme/core/
Semantic layer 73 tokens per mode, mode-aware (light/dark/sand/wireframe/dark-brand) ~180 vars per theme file ~600+ --theme-color-* vars
Component layer Per-component _variables.scss (color-only) Absent (1 var max) SCSS @mixin setVars per component
Semantic → Reference traceability ✓ ref() in JSON ◐ SCSS $var references ✗ Compiled away
Mode support Light, Dark, Sand, Wireframe, Dark-brand Light, Dark, Sand, Wireframe, Dark-brand Classic Dark, Classic Light
Status colors From iX (alarm, success, warning, info, critical, neutral) Own set (green, red, orange, yellow) Full set + states + hover/active variants

§4 — Component Authoring Pattern

AspectDualirisiX
Source format SCSS + template.html SCSS (in Stencil component) SCSS (in Stencil component)
Build tool Node.js (sass + custom build-wc.mjs) Stencil compiler Stencil compiler
Namespace parameter $namespace switches output Hardcoded per component Hardcoded per component
Adding a component Create folder + template + SCSS → done Stencil boilerplate + TypeScript Stencil boilerplate + TypeScript + tests
Template co-location template.html next to SCSS TSX in component file TSX in component file

§5 — Delivery & Consumption

AspectDualirisiX
Consumer can use CSS classes OR web components OR SCSS @use Web components only Web components (+ framework wrappers)
Tree-shaking CSS Per-file imports (button.css, card.css) All-or-nothing (iris.css) Lazy-load per component (Stencil)
Framework wrappers Not needed (CSS classes work everywhere) @siemens-iris/iris-react, iris-vue, iris-angular @siemens/ix-react, ix-angular, ix-vue
Override mechanism CSS var (runtime) + SCSS var (compile) CSS var (global theme only) CSS var + SCSS mixin

§6 — Key Differentiators

Dual AdvantageWhat it enables
CSS-only consumption pathNo JS dependency, works in any framework/CMS, instant adoption
Same source → dual outputWC and CSS classes stay in sync by construction, not discipline
Component-level token overridesScope color changes to one component without affecting others
JSON token traceabilityEvery semantic value traces back to a named reference token
SUIT CSS namingClear, collision-free naming without tooling — readable in DevTools
Dynamic WC generationtemplate.html → zero-config web component (no Stencil/TypeScript)
Per-file CSS deliveryImport only what you use — no 185KB monolithic bundle

§7 — Standardized Benchmarks & Adoption Impact

Package benchmarks measured on the same axes across all three systems. Dual figures are the real built dist/ outputs; iris/iX figures are their shipped bundles. Adoption-impact rows are estimates (labeled) of what iris-core changes to adopt the Dual POC concepts, not measured values.

Measured — bytes on the wire (CSS, uncompressed)

Load tierDual POCiris-coreiX
Variables only35.1 KB (preset/variables-only.css)n/a (no variables-only entry)~13 KB (theme file, vars-heavy)
Foundation (vars + base + utilities + grid)51.7 KB (preset/foundation.css)185 KB (whole iris.css)~13 KB theme + component CSS in JS
Full (everything enabled)51.8 KB (preset/full.css)185 KB~350 KB (theme + all components)
Per-granular-layervariables 35.1 · base 3.3 · utilities 6.0 · grid 7.5 KBnot separable (monolith)per-component in JS chunks
Web-component JS23.0 KB (6 components, components.js)bundled per Stencil chunkbundled per Stencil chunk

Measured — structural quality gates (POC, verified at build)

GateDual POCWhy it matters for adoption
--dual-* declarations322 across 5 modes + per-breakpointper-mode scopes are not duplication — one mode loads at a time
variablePrefix assertion0 foreign custom properties (build fails on drift)guarantees the namespace contract iris-core needs
Config-gated layers4 granular + 3 preset barrels from one configsize becomes a consumer choice, not a fixed cost
Reference aliases in dist0 (--dual-ref-* never ship)resolved values only — no runtime alias indirection

Estimated — iris-core adoption impact estimates, not measured

What adopting each Dual POC concept into iris-core is estimated to change. These are planning estimates from the build plans (P1–P7), not measured outcomes — the KPI scorecard in P1 is where measured deltas will be recorded.

Dual concept adoptedEstimated iris-core impactBaseline it moves
Config-gated dist (granular + presets)a consumer can drop from the 185 KB monolith to a variables-only / foundation tier — estimated 60–80% reduction for a tokens-only consumer185 KB single entry → tiered entries
Dual-output (one SCSS → shadow + light DOM)adds a CSS-only consumption path with no new authoring burden (same source); estimated zero net component-source growthWC-only → WC + CSS classes
Component-token tier (color-only)adds a scoped override surface iris-core lacks today; estimated ~5–10 color vars per component~1 override var → per-component set
SUIT class namingreadable, collision-free light-DOM classes; estimated no runtime cost (naming only)mixed kebab → .Iris-* SUIT
Structural gates (P1)!important +0, specificity +0, ≤ +50 selectors — a hard ceiling on the CSS the adoption addsungated → gated at CI

The KB budget is deliberately not a fixed target — delivered size is a config outcome (see the config-gated dist tiers above). P1 keeps the structural gates and drops a fixed KB budget; P4/P5 make size a consumer choice.


Related: Dual CSS Overview • Dual-Output Architecture • Token Architecture • iris CSS Overview • iX CSS Overview