BetaPublic beta — Read the release notes
Documentation
← Blog

Building on Solid 2: Architecture Decisions

Solidiom is built exclusively on Solid 2. This article explains why, and how the framework’s reactive primitives inform our component architecture.

Why Solid 2

Solid’s fine-grained reactivity model eliminates the virtual DOM diffing overhead that other frameworks carry. For a component library focused on accessibility and performance, this matters:

  • No wasted renders — only the exact DOM nodes affected by a state change update
  • Predictable timing — effects run synchronously after state changes, making focus management reliable
  • Small runtime — no reconciler overhead means smaller bundles per primitive
  • Composition over inheritance — signals and stores compose naturally without provider hell

Reactive Accessibility

Traditional component libraries fight their framework to manage focus. When a dialog opens, the library must ensure focus moves into the dialog after it renders. In React, this requires refs, effects, and careful timing. In Solid 2, the DOM is updated synchronously:

function openDialog() {
  setOpen(true)
  // DOM is already updated — focus management is immediate
  dialogRef.focus()
}

This synchronous model is why every Solidiom primitive can guarantee its keyboard contract without race conditions.

Signal-Driven State Machines

Each interactive primitive is modeled as a state machine driven by signals:

  • Disclosureopen signal drives accordion, dialog, popover, tooltip
  • Selectionvalue signal drives tabs, select, radio-group, listbox
  • NavigationactiveIndex signal drives menu, combobox, tree
  • Validationvalidity signal drives field, input, form controls

The state machine is the primitive. Styling is a separate layer (recipes) that reads the same signals via data attributes.

Primitives as Boundaries

Solidiom draws a hard boundary between primitives and styled components:

  • Primitives own behavior: state machines, keyboard handling, ARIA attributes
  • Recipes own appearance: colors, spacing, typography, animations
  • Templates own composition: how primitives and recipes combine into pages

This separation means you can swap styling profiles (CSS, Tailwind, UnoCSS) without touching behavior, and upgrade primitives without breaking your design.

What This Means for Consumers

  1. No React compatibility layer — Solidiom is Solid-native, not a port
  2. No runtime overhead — primitives compile to direct DOM operations
  3. Predictable bundle sizes — each primitive is independently tree-shakeable
  4. Future-proof — when Solid 2 reaches stable, Solidiom moves with it