Skip to content

Themes are genomes

May 25, 2026

Every design system I’ve worked on described “a theme” the same way: a function that returns an object of colors. Pick a palette; the system swaps your primary color and calls it a day.

That works fine if your design system only has one face. It doesn’t if your product has multiple — different brands inside one company, or a configurator users can fiddle with, or a marketing surface that needs to feel different from the admin surface even though the design language is the same.

helixui’s theme model — DNA, short for Design Nucleotide Allele — is the bet that themes should compose like living things, not config files.

22 genes

A helixui DNA is 22 genes. Each gene is a single decision:

  • accent — brand hue. 9 alleles (blue, violet, cyan, green, lime, orange, pink, crimson, gold).
  • chroma — saturation multiplier. 3 alleles (muted, standard, vibrant).
  • lightness — light, dark, or auto.
  • radius — sharp to extreme (5 alleles).
  • density — compact, comfortable, spacious.
  • typography — sans, grotesk, rounded, serif, mono.
  • surface — flat, elevated, glassy.
  • motion — subtle, standard, lively.
  • 14 more (neutralTilt, successHue, headingFamily, lineHeight, borderWidth, easing, …).

Each gene’s alleles have a dominance score (1–10) and an optional recessive flag.

import { wildtype, PRESETS, compose, mutate } from '@helixui/dna';
const a = PRESETS.studio(); // cyan, compact, grotesk, flat
const b = PRESETS.botanic(); // green, spacious, rounded, elevated
const child = compose(a, b); // crossover — see below

Crossover

When you breed two DNAs:

  1. For each gene, the higher-dominance allele wins.
  2. Ties go to a coin flip.
  3. If the loser is recessive, it surfaces ~15% of the time anyway.
  4. There’s a small per-gene mutation rate (~4%) — sometimes a fresh allele replaces both.

That’s a genetic algorithm. It’s deliberate. Recessive expression and mutation are what produce themes that surprise — looks the parents didn’t have, that you wouldn’t have arrived at by configuration.

Why this matters

Three reasons.

One token system, many faces. Your app, your docs, your customer portal, your marketing site, your admin dashboard — all can express different DNA off the same primitive tokens. The cascade does the work. You write components against semantic tokens (color.bg.action.brand.default) and they stay on-brand under any DNA.

Themes you can persist and share. A DNA serializes to a short JSON shorthand: { basePreset: 'wildtype', mutations: [{ gene: 'accent', value: 'violet' }] }. The DNA Lab on our site encodes the full current DNA as a URL hash — so when you breed a theme you like, the address bar is already a shareable link.

Brand experimentation that takes minutes, not weeks. “What if the admin was dark and the marketing was warm?” Before: a week with the brand team. With DNA: thirty seconds.

Terminal window
npx @helixui/dna breed studio noir --seed 42 --output shorthand

What’s not a gene

Anything that should be a layout decision, not a brand decision:

  • Number of columns in a grid.
  • Component density at the section level.
  • Whether sidebars are open by default.

Those are component props. Genes are the system-wide axes that should change together. Twenty-two of them is enough to express most brand surfaces; not so many that you lose the plot.

Try it

The DNA Lab is a live sandbox. Click “Roll” until you find something interesting. Hit the ”🔗 Share” button to copy a URL. Tweet it; the next person opens your theme.

Or breed offline:

Terminal window
npx @helixui/dna breed studio noir --seed 42

The output is a JSON DNA you can paste into any helixui-powered app. The DNA + the cascade do the rest.


Open questions: should the gene set grow (we said no to “icon weight” three times); should breed support more than two parents (no, it changes the math); should mutation rate be exposed in the lab UI (yes, coming).