Design.md: A Solution for Consistent AI-Generated Frontend UI Design
In the era of AI-assisted frontend development, how can we maintain consistency in AI-generated UIs? This article shares our practical experience building a design gallery site based on awesome-design-md, and how to create structured design.md files to guide AI in standardized UI design.
Background
Anyone who has used AI to write frontend code has likely had a similar experience: generating the same page multiple times, each with a different style. Sometimes it's rounded corners, sometimes square corners. Sometimes spacing is 8px, other times 16px. Even the same button looks different across different conversations.
This is not an isolated phenomenon. With the proliferation of AI-assisted development, inconsistency in AI-generated frontend UIs has become a widespread problem. Different AI assistants, different prompts, and even the same assistant across different conversations all produce wildly different interface designs. This brings enormous maintenance costs to product iteration.
The root cause is actually quite simple: the lack of an authoritative design reference document. Traditional CSS stylesheet files can only tell developers "how to implement," but cannot fully convey "why design it this way" and "what design patterns to use in what scenarios." For AI, it needs a clear, structured description to understand design specifications.
At the same time, the open-source community already has some excellent resources. The VoltAgent/awesome-design-md project collects design system documentation from many well-known companies, with each directory containing README.md, DESIGN.md, and preview HTML files. But these are scattered across upstream repositories, making them difficult to quickly browse and compare.
So, can we integrate these resources into a convenient-to-browse design gallery, while also consolidating a structured design.md for AI to use?
The answer is yes. Let me share our solution.
About HagiCode
The solution shared in this article comes from our practical experience in the HagiCode project. HagiCode is an AI-assisted development platform, and during development, we also encountered the problem of inconsistent AI-generated UIs. To solve this problem, we built a design gallery site and created standardized design.md files. This article summarizes this solution.
Before diving into the implementation, here is the final homepage we built. It brings the gallery entry point, the site repository, the upstream repository, and HagiCode context into one screen so the team can align on the same reference before drilling into individual entries.
Analysis
Before writing code, let's break down the technical challenges of this problem.
Content Source Management: How to unify scattered design resources?
The upstream awesome-design-md repository contains a large number of design documents, but we need a way to incorporate it into our project.
Solution: Use git submodule
awesome-design-md-site
└── vendor/awesome-design-md # Upstream resources (git submodule)
This has several benefits:
- Version control: Can lock specific upstream versions
- Offline builds: No need to request external APIs during build
- Content review: Can see specific changes in PRs
Data Standardization: How to unify different document structures?
Different companies' design documents may have different structures. Some are missing preview files, some have inconsistent naming. We need to standardize during the build phase.
Solution: Scan and generate standardized entries at build time
The core module is awesomeDesignCatalog.ts, responsible for:
- Scanning the
vendor/awesome-design-md/design-md/*directory - Validating that each entry contains required files (README.md, DESIGN.md, at least one preview file)
- Extracting and rendering Markdown content to HTML
- Generating standardized entry data
// src/lib/content/awesomeDesignCatalog.ts
export interface DesignEntry {
slug: string;
title: string;
summary: string;
readmeHtml: string;
designHtml: string;
previewLight?: string;
previewDark?: string;
searchText: string;
}
export async function scanSourceEntries() {
// Scan vendor/awesome-design-md/design-md/*
// Validate file integrity
// Generate standardized entries
}
export async function normalizeDesignEntry(dir: string) {
// Extract README.md, DESIGN.md
// Parse preview files
// Render Markdown to HTML
}
Static Site Architecture: How to provide dynamic search while maintaining static deployment?
Since it's a design gallery, search functionality is essential. But Astro is a static site generator—how do we implement real-time search?
Solution: React island + URL query parameter synchronization
// src/components/gallery/SearchToolbar.tsx
export function SearchToolbar() {
const [query, setQuery] = useState('');
// URL synchronization
useEffect(() => {
const params = new URLSearchParams(window.location.search);
setQuery(params.get('q') || '');
}, []);
// Real-time filtering
const filtered = entries.filter(entry =>
entry.searchText.includes(query)
);
return <input value={query} onChange={e => {
setQuery(e.target.value);
updateURL(e.target.value);
}} />;
}
The benefit of this approach is that it preserves the deployability of static sites (can deploy to any static hosting service) while providing an instant filtering user experience.
Design Documentation: How to make AI understand and follow design specifications?
This is the core of the entire solution. We need to create a structured design.md that allows AI to understand and apply our design specifications.
Solution: Reference ClickHouse DESIGN.md structure
ClickHouse's DESIGN.md is an excellent reference. It includes:
- Visual Theme & Atmosphere
- Color Palette & Roles
- Typography Rules
- Component Stylings
- Layout Principles
- Depth & Elevation
- Do's and Don'ts
- Responsive Behavior
- Agent Prompt Guide
Our approach: reference the structure, rewrite the content. Keep the chapter structure of ClickHouse's DESIGN.md, but replace the content with design tokens and component specifications actually used in our project.
Solution
Based on the above analysis, our solution consists of four core modules.
1. Content Ingestion Pipeline
This is the foundation of the entire system, responsible for extracting and standardizing content from upstream resources.
// src/lib/content/awesomeDesignCatalog.ts
export async function scanSourceEntries(): Promise<DesignEntry[]> {
const designDir = 'vendor/awesome-design-md/design-md';
const entries: DesignEntry[] = [];
for (const dir of await fs.readdir(designDir)) {
const entryPath = path.join(designDir, dir);
if (await isValidDesignEntry(entryPath)) {
const entry = await normalizeDesignEntry(entryPath);
entries.push(entry);
}
}
return entries;
}
async function isValidDesignEntry(dir: string): Promise<boolean> {
const requiredFiles = ['README.md', 'DESIGN.md'];
for (const file of requiredFiles) {
if (!(await fileExists(path.join(dir, file)))) {
return false;
}
}
return true;
}
2. Gallery Browsing Interface
The gallery interface includes three main parts:
Homepage: Displays a card grid of all design entries, each card containing:
- Design entry title and description
- Preview image (if available)
- Quick search highlighting
Detail Page: Aggregates and displays complete information for a single design entry:
- README documentation
- DESIGN documentation
- Previews (supports light/dark theme switching)
- Adjacent entry navigation
Navigation: Supports returning to gallery, browsing adjacent entries
The homepage gallery uses a dense card grid so different design-md entries can be compared inside one consistent frame. That makes it much easier to scan brand styles, CTA patterns, and typography at a glance.
Once you open a specific entry, the detail page keeps the design summary and live preview on the same screen, which reduces the cost of jumping between docs, previews, and source files.
3. Search Functionality
Search is based on client-side filtering, using URL query parameters to maintain state:
// src/components/gallery/SearchToolbar.tsx
function SearchToolbar({ entries }: { entries: DesignEntry[] }) {
const [query, setQuery] = useState('');
const [results, setResults] = useState(entries);
useEffect(() => {
const params = new URLSearchParams(window.location.search);
const initialQuery = params.get('q') || '';
setQuery(initialQuery);
filterEntries(initialQuery);
}, []);
const filterEntries = (searchQuery: string) => {
const filtered = entries.filter(entry =>
entry.searchText.toLowerCase().includes(searchQuery.toLowerCase())
);
setResults(filtered);
};
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
setQuery(value);
filterEntries(value);
// Update URL (without triggering page refresh)
const newUrl = value
? `${window.location.pathname}?q=${encodeURIComponent(value)}`
: window.location.pathname;
window.history.replaceState({}, '', newUrl);
};
return (
<div className="search-toolbar">
<input
type="text"
value={query}
onChange={handleChange}
placeholder="搜索设计条目..."
/>
<span className="result-count">{results.length} 个结果</span>
</div>
);
}
4. Design Reference Document (design.md)
This is the core output of the entire solution. We create design.md in the project root directory with the following structure:
In addition to the raw design.md content used by AI, we also place README and DESIGN in the same reading surface so humans can review, copy fragments, and compare the text with the visual preview more efficiently.
# Design Reference for [Project Name]
## 1. Visual Theme & Atmosphere
- Overall style description
- Design philosophy and principles
## 2. Color Palette & Roles
- Primary colors, secondary colors
- Semantic colors (success, warning, error)
- CSS Variables definitions
## 3. Typography Rules
- Font families
- Font size hierarchy (h1-h6, body, small)
- Line height and font weight
## 4. Component Stylings
- Button style specifications
- Form component styles
- Card and container styles
## 5. Layout Principles
- Spacing system
- Grid and breakpoints
- Alignment principles
## 6. Depth & Elevation
- Shadow hierarchy
- z-index specifications
## 7. Do's and Don'ts
- Common mistakes and correct practices
## 8. Responsive Behavior
- Breakpoint definitions
- Responsive adaptation rules
## 9. Agent Prompt Guide
- How to use this document in AI prompts
- Example prompt templates
Practice
Now that you understand the solution, how do you implement it specifically?
Implementation Steps
Step 1: Initialize Submodule
# Add upstream repository as submodule
git submodule add https://github.com/VoltAgent/awesome-design-md.git vendor/awesome-design-md
# Initialize and update submodule
git submodule update --init --recursive
Step 2: Create Content Pipeline
Implement awesomeDesignCatalog.ts, including:
- File scanning and validation logic
- Markdown rendering (using Astro's built-in renderer)
- Entry data extraction
Step 3: Build Gallery UI
Using Astro + React Islands create:
- Homepage gallery layout (card grid)
- Design card component
- Search toolbar
- Detail page layout
Step 4: Write Design Document
Based on ClickHouse DESIGN.md structure, fill in your project's actual design tokens. Update README.md to add a link to design.md.
Considerations
Security: Markdown rendering needs to filter unsafe HTML. Astro's built-in renderer filters script tags by default, but XSS risks still need attention.
Performance: Large numbers of iframe previews may affect first-screen loading. It's recommended to use loading="lazy" for lazy-loading preview content.
Maintainability: design.md needs to stay synchronized with code implementation. It's recommended to add checks in CI to ensure CSS variables are consistent between documentation and code.
Accessibility: Ensure color contrast meets WCAG AA standards (at least 4.5:1).
AI Usage Guide
After creating design.md, how do you get AI to actually use it? Here are some practical tips:
Tip 1: Explicitly reference in prompts
Please refer to the design.md file in the project root directory and use the design specifications defined therein to implement the following components:
- Button: Use primary color, 8px border radius
- Card: Use elevation-2 shadow level
Tip 2: Require AI to reference specific CSS variables
Implement a navigation bar with requirements:
- Background color using --color-bg-primary
- Border using --color-border-subtle
- Text using --text-color-primary
Tip 3: Include design.md content in system prompt
If your AI tool supports custom system prompts, you can add the core content of design.md directly.
Testing Strategy
Content Pipeline Testing:
- Missing file scenarios (missing README.md or DESIGN.md)
- Format error scenarios (Markdown parsing failure)
- Empty directory scenarios
Search Function Testing:
- Empty result handling
- Special characters (such as Chinese, emoji)
- URL synchronization verification
UI Component Testing:
- Light/dark theme switching
- Responsive layout
- Preview loading state
Deployment Process
# 1. Update submodule to latest version
git submodule update --remote
# 2. Rebuild site
npm run build
# 3. Deploy static assets
npm run deploy
It's recommended to automate submodule updates and build deployment, so the CI process can be automatically triggered when the upstream repository updates.
Summary
The problem of inconsistent AI-generated UIs encountered by HagiCode during development is essentially a lack of structured design reference documents. By building a design gallery site and creating standardized design.md files, we successfully solved this problem.
The core value of this solution lies in:
- Unified Resources: Integrating scattered design system documentation
- Structured Specifications: Presenting design specifications in an AI-understandable form
- Continuous Maintenance: Keeping content updated through git submodule
If you're also using AI for frontend development, I suggest trying this solution. Creating a structured design.md not only improves the consistency of AI-generated code, but also helps maintain unified design specifications within the team.
References
- VoltAgent/awesome-design-md - Design system documentation collection
- ClickHouse DESIGN.md - Design document structure reference
- Astro Official Documentation - Static site generation framework
- HagiCode Source Code - Actual implementation of this solution
If this article helps you:
- Give it a like to help more people see it
- Come to GitHub and give us a Star: github.com/HagiCode-org/site
- Visit the official website to learn more: hagicode.com
- Watch the 30-minute practical demo: www.bilibili.com/video/BV1pirZBuEzq/
- One-click installation experience: docs.hagicode.com/installation/docker-compose
- Desktop quick installation: hagicode.com/desktop/
- Public beta has started, welcome to install and experience
Original Article & License
Thanks for reading. If this article helped, consider liking, bookmarking, or sharing it.
This article was created with AI assistance and reviewed by the author before publication.
- Author: newbe36524
- Original URL: https://docs.hagicode.com/go?platform=devto&target=%2Fblog%2F2026-04-08-design-md-consistent-ui%2F
- License: Unless otherwise stated, this article is licensed under CC BY-NC-SA. Please retain attribution when sharing.




Top comments (0)