Skip to content

DNA — the helixui theme engine

DNA — Design Nucleotide Allele. It’s how helixui names its theme system.

A DNA is a complete theme genome — eight genes, one allele each. You can clone DNAs, mutate them, breed two parents into a child, or run generations of breeding over a population. Dominant alleles win in crossover; recessive alleles still surface occasionally. That’s where surprise looks come from across generations.

Live demo: /showcase/dna-lab — every component on the page renders under a DNA you can mutate live.

Genes (8)

GeneTraitSample alleles
accentBrand hue (drives the OKLCH 50–900 ramp)blue, violet, cyan, green, orange, crimson…
chromaSaturation multiplier across the brand rampmuted, standard, vibrant
lightnessLight / dark / autolight, dark, auto
radiusCorner-radius scale factorsharp, subtle, standard, rounded, extreme
densitySpacing scale factorcompact, comfortable, spacious
typographyFont family + scalesans, grotesk, rounded, serif, mono
surfaceShadow / depth treatmentflat, elevated, glassy
motionAnimation duration scalesubtle, standard, lively

Each allele has a dominance score (1–10) and an optional recessive flag. The full registry lives in @helixui/dna/src/alleles.ts.

API

import {
wildtype, PRESETS,
clone, mutate, compose, evolve,
express,
type DNA,
} from '@helixui/dna';
const a = wildtype(); // base DNA
const b = PRESETS.botanic(); // a preset
const c = mutate(a, { gene: 'accent', allele: 'crimson' });
const child = compose(a, b); // cross two DNAs
const next = evolve([a, b, c, child]); // run a generation
const { cssVars, dataTheme } = express(child); // → CSS custom properties

Apply a DNA to a subtree via <HelixUIDNAProvider> (from @helixui/core):

import { HelixUIDNAProvider, Button } from '@helixui/core';
<HelixUIDNAProvider dna={child}>
<Button>This button renders under the bred DNA.</Button>
</HelixUIDNAProvider>

Inheritance rules

When two DNAs cross, for each gene:

  1. Higher dominance wins. Ties are decided by coin flip.
  2. Recessive surfacing. If the loser allele is flagged recessive, it takes the locus ~15% of the time anyway. That’s how visual surprises emerge.
  3. Mutation. A small per-gene mutation rate (default ~4%) replaces the winner with a random other allele.

Tune all three per call (compose(a, b, { mutationRate: 0.2 }) or evolve(pop, { fitness: contrastScore })).

Why DNA changes are instant

helixui tokens ship in two layers:

  1. Primitives (color.brand.500, space.4, radius.md, font.size.md, shadow.md) — concrete CSS variable values.
  2. Semantic aliases (color.bg.action.brand.default = {color.brand.500}) — emitted as var(--helixui-color-brand-500) in the built CSS.

When DNA’s express() overrides a primitive (e.g. --helixui-color-brand-500), every semantic that references it follows through the cascade automatically. No re-render. No recomputation. Just a style mutation on the DNA provider’s wrapping div.

Phenotype

express(dna) produces:

  • A color ramp generated with oklch(L% C H) from the accent and chroma genes (10 shades, 50–900).
  • Spacing tokens scaled by density.spacing.
  • Radius tokens scaled by radius.factor.
  • Font family + size scale from typography.
  • Shadow set per surface.style (flat / elevated / glassy).
  • Motion duration tokens (--helixui-motion-duration-*).
  • A data-theme attribute when lightness is light or dark.
{
'--helixui-color-brand-500': 'oklch(56% 0.16 234)',
'--helixui-color-brand-600': 'oklch(47% 0.155 234)',
'--helixui-radius-md': '11.20px',
'--helixui-space-4': '20.00px',
'--helixui-font-family-sans': "'Geist', 'Space Grotesk', …",
'--helixui-shadow-md': '0 4px 6px -1px rgb(0 0 0 / 0.1), …',
'--helixui-motion-duration-normal': '200ms',
/* …38 vars total… */
}

Persistence

A DNA is a plain JSON-serialisable object. To persist a user’s chosen theme, JSON.stringify(dna) to localStorage / your backend; JSON.parse to restore. Allele values are inert data — no functions or class instances.