Architectural Rules for Modular React Component Generation from Stitch Designs: The Complete Guide

The stitch::react-components skill enforces strict architectural rules—including component granularity, logic isolation, and type safety—to transform Stitch designs into modular, production-ready React codebases compatible with Vite, Tailwind, and React Router.

Converting visual designs into maintainable code requires disciplined architecture. The google-labs-code/stitch-skills repository defines precise architectural rules for modular React component generation from Stitch designs to ensure generated codebases remain scalable, type-safe, and consistent with modern React patterns. These rules, specified in Phase 3 of the skill documentation, mandate specific file structures, data patterns, and validation gates that every component must satisfy.

Enforce Granular Component Architecture

Atomic Design and File Organization

Every reusable UI pattern must reside in its own file under src/components/. The skill mandates component granularity where atomic elements compose into larger composite structures, preventing monolithic page files. As defined in plugins/stitch-build/skills/react-components/SKILL.md, component file names must exactly match the exported component name—such as Button.tsx or Card.tsx—to guarantee IDE auto-import support and discoverability.

Props Interface Requirements

Every component must export a Readonly props interface named <ComponentName>Props. These interfaces enforce immutability and are validated via npm run validate. The Type safety rule in Phase 3 requires this pattern for all components, including page-level views.

// src/components/Card.tsx
export interface CardProps {
  readonly title: string;
  readonly description: string;
  readonly imageUrl: string;
}

export const Card: React.FC<CardProps> = ({ title, description, imageUrl }) => (
  <div className="card">{/* … */}</div>
);

Isolate Business Logic in Custom Hooks

All event handling, pagination, filtering, and state management must be extracted to src/hooks/. Following the Logic isolation rule from Phase 3 of [SKILL.md](https://github.com/google-labs-code/stitch-skills/blob/main/plugins/stitch-build/skills/react-components/SKILL.md), hook files must follow the use... naming convention to clearly indicate encapsulated business logic.

// src/hooks/usePagination.ts
import { useState } from "react";

export function usePagination<T>(items: T[], pageSize: number) {
  const [page, setPage] = useState(0);
  const pageCount = Math.ceil(items.length / pageSize);
  const pagedItems = items.slice(page * pageSize, (page + 1) * pageSize);
  return { page, setPage, pageCount, pagedItems };
}

Decouple Static Data from Components

The Data decoupling rule mandates that all hard-coded strings, image URLs, and data arrays live exclusively in src/data/mockData.ts. Components import these values rather than embedding literals, ensuring pure, reusable presentation logic that remains easy to update and localize.

// src/data/mockData.ts
export const HERO_TEXT = "Build a DeFi portfolio dashboard";
export const CARDS = [
  { title: "Bitcoin", value: "$23,456", icon: "/icons/btc.svg" },
  // …
];
// src/components/Hero.tsx
import { HERO_TEXT } from "../data/mockData";

export const Hero = () => <h1>{HERO_TEXT}</h1>;

Wire Navigation with React Router

Replace all <a href="#"> tags with React Router <Link> components. The architecture requires the top logo to use <Link to="/"> for desktop navigation, while bottom and sidebar items implement active-state handling via useLocation() to ensure proper SPA behavior.

// src/components/TopAppBar.tsx
import { Link } from "react-router-dom";

export const TopAppBar = () => (
  <header className="flex items-center p-4">
    <Link to="/" className="font-bold text-xl">
      MyApp
    </Link>
    {/* …other nav items… */}
  </header>
);

Apply Tailwind Styling and Dark Mode Standards

Design tokens extracted to resources/style-guide.json during Phase 2 must drive all styling decisions. Component class names reference these tokens using Tailwind utilities, with every color class receiving the dark: prefix for automatic dark mode support. Never use raw hex values in component files; always map through the design tokens as specified in [react-tailwind.md](https://github.com/google-labs-code/stitch-skills/blob/main/plugins/stitch-design/skills/extract-design-md/references/react-tailwind.md).

// src/components/Button.tsx
export const Button = ({ children }: { readonly children: React.ReactNode }) => (
  <button className="bg-primary text-white dark:bg-primary-dark hover:bg-primary-light">
    {children}
  </button>
);

Validate Against the Architecture Checklist

Before production, components must pass the quality gate defined in plugins/stitch-build/skills/react-components/resources/architecture-checklist.md. The npm run validate command checks for structural integrity, type safety, and styling conventions. Any missing Props interface, hard-coded hex color, or logic embedded in JSX causes immediate validation failure, ensuring only architecturally sound code enters the repository.

End-to-End Implementation: From Design to Component

Transforming a Stitch design into a validated React component follows this strict workflow:

1. Extract Design Tokens

Run the extraction utility to populate the style guide before writing components.

npm run extract-tokens   # populates resources/style-guide.json

2. Define Static Data

Centralize all content in the mock data layer.

// src/data/mockData.ts
export const CARD_DATA = [
  {
    title: "Bitcoin",
    description: "Leading cryptocurrency",
    imageUrl: "/assets/btc.svg",
  },
];

3. Build the Component and Page

Implement the atomic component with proper typing and consume it in page views.

// src/components/Card.tsx
export interface CardProps {
  readonly title: string;
  readonly description: string;
  readonly imageUrl: string;
}

export const Card: React.FC<CardProps> = ({ title, description, imageUrl }) => (
  <div className="p-4 bg-white dark:bg-gray-800 rounded-card shadow">
    <img src={imageUrl} alt={title} className="h-12 w-12" />
    <h2 className="font-sans">{title}</h2>
    <p>{description}</p>
  </div>
);
// src/pages/Home.tsx
import { Card } from "../components/Card";
import { CARD_DATA } from "../data/mockData";

export const Home = () => (
  <section className="grid gap-4">
    {CARD_DATA.map((c) => (
      <Card key={c.title} {...c} />
    ))}
  </section>
);

4. Configure Routing

Wire components into the application router.

// src/App.tsx
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import { Home } from "./pages/Home";
import { TopAppBar } from "./components/TopAppBar";

export const App = () => (
  <Router>
    <TopAppBar />
    <Routes>
      <Route path="/" element={<Home />} />
      {/* additional routes… */}
    </Routes>
  </Router>
);

5. Execute Validation

Run the architecture validator to ensure compliance.

npm run validate src/components/Card.tsx
npm run validate src/pages/Home.tsx

Summary

  • Component granularity: Each UI pattern lives in its own file under src/components/ following atomic design principles.
  • Logic isolation: All state and business logic must reside in src/hooks/ using the use... naming convention.
  • Data decoupling: Static content belongs exclusively in src/data/mockData.ts, never embedded in components.
  • Type safety: Every component exports a Readonly props interface validated by npm run validate.
  • Navigation standards: Use React Router <Link> components exclusively, with the top logo linking to /.
  • Styling compliance: Reference resources/style-guide.json tokens and apply dark: prefixes for all color classes.

Frequently Asked Questions

What is the stitch::react-components skill?

The stitch::react-components skill is a code generation module within google-labs-code/stitch-skills that converts Stitch design exports into modular React applications. It enforces a three-phase workflow: design extraction, token generation, and component architecture, ensuring outputs are compatible with Vite, Tailwind CSS, and React Router while maintaining strict TypeScript standards.

Why must all props interfaces be Readonly?

The Readonly<T> requirement prevents accidental mutation of component inputs, enforcing unidirectional data flow patterns essential for React optimization and predictability. This rule, defined in Phase 3 of SKILL.md, allows the npm run validate checker to enforce immutability contracts across the entire component library.

How does the validator enforce architectural rules?

The validator script reads the quality gate specifications from architecture-checklist.md and scans source files for compliance. It checks for the presence of exported Props interfaces, verifies that no hard-coded hex values exist in component files, ensures hooks are stored in src/hooks/, and confirms that navigation uses React Router <Link> components rather than anchor tags.

Where should design tokens be stored in a Stitch-generated project?

Design tokens extracted from Stitch HTML reside in resources/style-guide.json at the project root. These tokens map to Tailwind configuration values, and the architectural rules prohibit referencing raw color values or spacing units directly in components—all styling must derive from this centralized token file to ensure theme consistency and dark mode support.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →