Design tokens, component libraries, and the case against generic AI interfaces.
The Prompt Engineering Project March 14, 2025 10 min read
Quick Answer
An AI design system provides consistent, reusable components specifically designed for AI-powered interfaces. We built ours because standard design systems lack patterns for streaming text, confidence indicators, loading states unique to inference, and prompt-driven interactions. A dedicated AI design system ensures visual coherence while handling the unique UX challenges that language model outputs create.
Most AI products look the same. Open any ten AI-powered applications launched in the last two years and you will find the same visual language: the same rounded corners, the same gradient accents, the same chat-bubble interfaces, the same default Tailwind color palette. This is not a coincidence. It is the natural consequence of an industry that treats design as a downstream concern -- something you bolt on after the model works, using whatever component library ships fastest.
The Prompt Engineering Project made a different choice. Before we wrote a single prompt, before we configured a single model, we built a design system. Not a theme. Not a component library downloaded from npm. A complete, opinionated design system with tokens, components, principles, and constraints -- all authored from scratch to serve a specific product vision.
This is the story of why we made that decision, what we built, and what it taught us about the relationship between design craft and AI product quality.
The Problem: Generic AI Interfaces
The homogeneity of AI product design has a clear cause: speed pressure. When the core value proposition is "we have a working AI feature," every hour spent on design feels like an hour not spent on the model. Teams reach for shadcn/ui, install Tailwind with default settings, pick a color from the palette, and ship. The result works. It just looks like everything else.
This is the "default aesthetic" -- competent, inoffensive, and utterly generic. It signals nothing about the product's personality, values, or attention to craft. When your interface looks like every other AI product, you are implicitly telling users that your product is interchangeable with every other AI product. For a tool that demands trust and sustained engagement, that is a costly signal to send.
80%
AI apps use default Tailwind
3
Component libs dominate
0
Design tokens customized
1hr
Avg. design time invested
The deeper problem is that generic design begets generic thinking. When you accept the defaults for visual design, you tend to accept the defaults for interaction design, information architecture, and content strategy. The interface becomes a container rather than a craft object. And in AI products specifically, where the interface mediates between human intent and machine behavior, the quality of that mediation layer matters enormously.
The Decision: Invest in Design First
We chose to invest in a proper design system before building features for a reason that goes beyond aesthetics: a design system is a decision-making framework. Every token, every component, every constraint eliminates a category of future decisions. "What color should this button be?" is not a question anyone needs to answer if the button component already knows. "How much padding goes around this section?" is not a debate if the spacing scale is defined.
For an AI project specifically, a design system serves an additional purpose: it provides machine-readable contracts for AI-generated interfaces. When an AI assistant generates a UI component, it can reference design tokens rather than inventing arbitrary values. The design system becomes part of the prompt's context -- a structured vocabulary that constrains AI output the same way it constrains human output.
A design system is not a cost center. It is a decision-elimination engine. Every token defined is a thousand micro-decisions you never have to make again.
The bet was straightforward: spend two weeks building a design system now, or spend two hours per feature fighting design inconsistency forever. The math favors upfront investment. It always does, and teams that skip it always regret it.
The Implementation: tokens.css as the Source of Truth
The foundation of our design system is a single file: tokens.css. This file contains every design decision expressed as CSS custom properties. Colors, typography, spacing, radii, shadows, gradients, motion curves -- all defined once, referenced everywhere. No magic numbers in component files. No hex codes scattered across stylesheets. One file, one truth.
The choice of CSS custom properties over a JavaScript theme object was deliberate. Custom properties work across every rendering context -- server components, client components, CSS modules, inline styles. They require no build step, no runtime overhead, and no framework coupling. They are readable by both humans and machines. And they cascade naturally, making theme variants (dark mode, compact mode, high contrast) trivially composable.
Color Architecture
Our color system uses a semantic layering approach. Raw color tokens (--pri-600) define the palette. Semantic tokens (--light-text, --dark-surface, --dark-border) map raw colors to interface roles. Components reference semantic tokens exclusively. This means we can change the entire color palette by modifying raw tokens without touching a single component. It also means dark mode is not a separate theme -- it is the same components referencing different semantic tokens.
One of our earliest and most controversial design decisions was banning emoji entirely from the product interface. No decorative emoji in headings. No emoji bullets in lists. No emoji reactions in feedback. This was not about disliking emoji -- it was about establishing a clear principle: every visual element in the interface should be intentionally designed, not borrowed from a platform-dependent glyph set.
Emoji render differently on every operating system. An icon that looks clean on macOS may look cartoonish on Windows or missing on older Android devices. By replacing emoji with purpose-designed SVG icons, we gained complete control over visual consistency across platforms. Every icon is the same weight, the same optical size, the same level of detail, regardless of where it renders.
Instead of
Use emoji for visual hierarchy and personality in the interface
Try this
Use purpose-designed SVG icons for consistent cross-platform rendering
But the no-emoji rule signals something deeper than cross-platform consistency. It signals that this project takes visual craft seriously enough to reject convenient defaults. It is a forcing function: every place where a team would normally drop in an emoji, we are instead forced to ask "what does this element need to communicate, and what is the right visual treatment for that communication?" The constraint drives better design decisions.
This philosophy extends beyond emoji. We do not use stock illustrations. We do not use generic icon packs without customization. Every visual element is either designed for this specific product or deliberately omitted. Restraint is a design tool, and one of the most powerful ones available.
Design Tokens as Machine-Readable Contracts
Here is where the design system connects back to prompt engineering and AI infrastructure. When an AI generates a UI component, it needs to produce values for colors, spacing, typography, and other visual properties. Without a token system, the AI invents these values -- producing hex codes that are close to but not exactly right, spacing values that approximate but do not match the grid, font sizes that work but do not belong to the typographic scale.
With a token system, the AI has a constrained vocabulary. Instead of generating arbitrary values, it references tokens: var(--pri-600) instead of #1db954, var(--sp-8) instead of 32px, var(--font-mono) instead of 'JetBrains Mono'. The token system becomes part of the prompt context -- a structured set of named values that the model can reference, producing output that is automatically consistent with the design system.
prompt-context.ts
// Design tokens injected into AI prompts for UI generation
const designContext = {
colors: {
primary: 'var(--pri-600)',
primaryLight: 'var(--pri-400)',
surface: 'var(--dark-surface)',
text: 'var(--dark-text)',
textSecondary: 'var(--dark-text-sec)',
border: 'var(--dark-border)',
},
spacing: {
xs: 'var(--sp-1)', // 4px
sm: 'var(--sp-2)', // 8px
md: 'var(--sp-4)', // 16px
lg: 'var(--sp-8)', // 32px
xl: 'var(--sp-16)', // 64px
},
typography: {
body: "font-family: var(--font-body); font-size: var(--text-base);",
code: "font-family: var(--font-mono); font-size: var(--text-sm);",
heading: "font-family: var(--font-body); font-weight: 700;",
},
rules: [
'Never use raw hex colors. Always reference token variables.',
'Never use arbitrary spacing values. Use the spacing scale.',
'Never use emoji. Use SVG icons or plain text.',
'Border radius: 8px for cards, 12px for modals, 9999px for badges.',
],
}
Injecting design tokens into AI prompts is a form of context engineering. The tokens serve as constraints that reduce the search space for valid outputs, making the model more likely to produce correct results on the first attempt. Fewer possible values means fewer possible mistakes.
What We Learned
Building a design system for an AI project taught us several things that we did not expect.
First, the design system accelerated AI development, not slowed it down. When prompts have a constrained design vocabulary to work with, they produce usable output more consistently. Less iteration. Fewer corrections. Better first-pass results. The upfront investment in tokens and components paid for itself within the first week of AI-assisted development.
Second, the discipline of design tokens improved our prompts. The practice of naming every value forced us to articulate design intent explicitly. That same practice -- naming things precisely, constraining options deliberately, documenting decisions clearly -- is exactly what makes prompts effective. Design system thinking and prompt engineering thinking share the same underlying skill: turning implicit knowledge into explicit specification.
Third, users notice craft even when they cannot articulate it. Early testers consistently described the interface as "professional" and "trustworthy" without being able to point to any specific design decision that created that impression. The cumulative effect of consistent spacing, deliberate color choices, purposeful typography, and restrained use of visual elements creates a perception of quality that no single element produces on its own. This is what a design system provides: not any one good decision, but the infrastructure for making thousands of good decisions consistently.
The discipline required to build a design system is the same discipline required to write good prompts: turning implicit intent into explicit, testable specification.
Key Takeaways
1
Generic AI interfaces signal interchangeable products. A custom design system signals craft, trust, and intentional decision-making.
2
Use CSS custom properties as the foundation. They work across all rendering contexts, require no runtime overhead, and are readable by both humans and machines.
3
Design tokens serve as machine-readable contracts for AI-generated UI. Injecting tokens into prompts constrains the output space and improves first-pass quality.
4
Constraints like the no-emoji rule are forcing functions for better design decisions. Restraint is a design tool, not a limitation.
5
Design system thinking and prompt engineering thinking share the same core skill: converting implicit intent into explicit, testable specifications.