Python design system generator: ux-skill v2's 5-parallel-search engine.
Generating a complete design system from a brief (style philosophy, color palette, type pairing, motion presets, component picks, brand exemplars) used to require a designer, a moodboard, and a week. ux-skill v2 runs that decision in Python, deterministically, in seconds.
The architectural premise
A design system recommendation isn't one decision. It's five, made in parallel and merged. The five lanes are independent enough to search separately, but interdependent enough that the merge step matters. ux-skill v2 implements this as a Python recommender with five concurrent search functions over 11 structured manifests (1,243 entries total).
The output is a single design-system object: a chosen style philosophy, a palette with named tokens, a type pairing with ramps, a motion profile, a component pick list, and brand exemplars to reference. Plus a generated tokens.css file you can drop into Tailwind or any CSS-vars-driven framework.
The five parallel lanes
Each lane runs as an independent Python function. The five are dispatched concurrently with asyncio.gather. Total wall time on a modern machine is ~200ms for the search step, ~50ms for the merge. The slowest part of a recommendation is usually the discovery step before it (interactive 10-field intake); the search itself is faster than a typical HTTP call.
How the merge works
Each lane returns a ranked list of candidates with compatibility scores against the brief. The merge step does three things:
- Cross-lane compatibility check. A neon-cyberpunk style with an editorial serif pairing fails the cross-check. The merger picks combinations the manifest has flagged as coherent.
- Brand spec overlay. If the brief mentions a brand by name (Apple, Stripe, Linear, Figma, Tesla, BMW…) or matches a brand's industry-tone signature, the merger overlays the brand's DESIGN.md tokens. 160 brand specs available.
- Component pick. Given style + palette + type, the merger picks compatible components from the 148-entry catalog. Editorial-modern gets long-form layouts and quote pulls; dashboard-dense gets data tables and KPI cards.
The merge produces a single recommendation object with the picks, the rationale (why each was chosen), and an alternates list (the runners-up in each lane, in case the user wants to swap).
The minimal example
Three lines after install. The Python API mirrors the CLI 1:1.
The system object exposes:
system.style: name, philosophy, do/don't rules, exemplar brands.system.palette: named tokens (canvas, surface, ink, body, muted, primary, semantic colors), WCAG scores.system.type: display + body pairing, weight ramps, size ramps, line-heights, language coverage.system.motion: easing curves, duration ramps, hierarchy preset, reduced-motion fallback.system.components: the 148-entry catalog filtered to compatible picks.system.brand: overlaid brand DESIGN.md if one applied.system.alternates: runners-up in each lane.system.to_tokens_css(): generates atokens.cssstring.system.to_tailwind_config(): generates atailwind.config.jssnippet.system.to_dict(): JSON-serializable for handoff or storage.
Example output: AI-dev-tool brief
Real recommendation for a representative brief. Inputs were "AI developer tool, dark editorial, technical credibility, latency-sensitive, English." The merger overlaid Linear's brand spec because the trust-tone signature matched the dev-credibility vector.
#07080a, ink #07080a, accent #818cf8. WCAG AA on all text-on-surface pairs.
The merge surfaced one specific decision worth flagging: the candidate dark-minimal-mono tied with saturated-cinema on the style score. The tiebreaker was the "technical credibility" signal: saturated-cinema's per-scene accents read more as editorial confidence than minimal-mono's restraint, so it won by 0.04 on the cross-lane compatibility score. That kind of decision is the merge step earning its keep.
The 1,243 entries, listed
For transparency, the breakdown of the catalog:
- 84 design styles (industries.json overlay)
- 176 color palettes (palettes.json)
- 70 type pairings (typography.json)
- 57 motion presets (motion.json)
- 148 components (components.json)
- 184 industry rules (industries.json)
- 112 UX laws (laws.json: Fitts, Hick, Miller, Gestalt principles, etc.)
- 35 chart types (charts.json)
- 25 tech stacks (stacks.json)
- 35 anti-pattern rules (antislop.json)
- 72 brand DESIGN.md specs (brands/*.md, indexed)
Total: 1,243 entries. All MIT-licensed. All extensible: the manifests are plain JSON; fork-and-extend is the supported path for adding your own styles or brand specs.
Why 5 lanes, not 1?
A single combined search is the obvious alternative: one query, one ranked result. It loses because design-system fit is multi-dimensional. A palette can be perfect for the industry but wrong for the type pairing. A motion preset can be coherent with the style but break under reduced-motion accessibility. Single-search collapses the dimensions and produces "close enough" recommendations that don't survive scrutiny.
Parallel lanes preserve the dimensions and let the merge step decide explicitly which trade-offs to make. The merger is also where the brand-spec overlay happens: you can't overlay a brand language on a recommendation that hasn't yet committed to a palette and type pairing.
Single search compresses five decisions into one. The merge step is where the decisions get explicit, the trade-offs get named, and the alternates get preserved.
What this isn't
Be specific about the limits:
- Not a code generator. The recommendation is a system. To generate component code, pair with
/ux-design,/ux-component, or your IDE's code-gen capability inside the recommended system. - Not a moodboard. The recommendation is structured, not visual. To see what it looks like, generate a sample page; for visual variants, swap palette and re-generate.
- Not deterministic on close calls. The merge step is deterministic given the same brief, but two slightly different briefs can swap the top-2 result (as in the example above). This is a feature: the recommendation honors brief signal.
- Not infinite. 1,243 entries covers most working briefs, but if your brief is "1960s Soviet constructivism applied to a quantum-computing dashboard," the recommender will return a closest-fit with a confidence flag, not a custom system.
About the catalog depth claim
ui-ux-pro-max-skill is the comparator here. Their recommender pioneered the 5-parallel-search architecture (we adopted it directly) and has ~600 structured entries. ux-skill v2 extends to 998. The architecture is shared; the depth is ours.
The 998 number is not the moat. The moat is the four nets new (145-rule deterministic linter, 92 named brand specs, 57 motion presets, 148-component catalog) that don't exist in ui-ux-pro-max's recommender.
Beyond the recommendation
The recommender is one node in a larger pipeline. After recommend(), the next Python calls are:
uxskill.generate(system, page="landing"): emit code for a target surface using the recommended system.uxskill.lint(code, threshold="high"): 145-rule anti-slop pass on the generated code.uxskill.fix(code, lint_result): apply lint fixes inline.uxskill.critique(code, system): taste-level review citing named UX laws and brand exemplars.uxskill.case_study(system, code): auto-generated handoff doc.
Each function returns a structured object; each accepts the previous step's output. The pipeline is composable in plain Python, not just inside an IDE's slash-command interface.
Three lines, the install
From pip install to a working recommendation:
The recommendation runs in ~250ms on a modern machine. The tokens.css output is ready to drop into Tailwind, Vanilla Extract, CSS modules, or any framework that reads CSS custom properties.