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,182 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. 131 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,182 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,182 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,182 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 — 120-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")— 120-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.