DEV Community

Hagicode
Hagicode

Posted on • Originally published at docs.hagicode.com

Design.md: A Solution for Consistent AI-Generated Frontend UI Design

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.

GitHub - HagiCode-org/site

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.

Awesome Design MD Gallery homepage overview

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)
Enter fullscreen mode Exit fullscreen mode

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:

  1. Scanning the vendor/awesome-design-md/design-md/* directory
  2. Validating that each entry contains required files (README.md, DESIGN.md, at least one preview file)
  3. Extracting and rendering Markdown content to HTML
  4. 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
}
Enter fullscreen mode Exit fullscreen mode

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);
  }} />;
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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.

Awesome Design MD Gallery card grid

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.

Awesome Design MD Gallery design detail preview

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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.

Awesome Design MD Gallery README and DESIGN document view

# 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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


If this article helps you:

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.

Top comments (0)