本文へ移動
cccskills
無料GitHub で公開

stitch-react-components

Converts a Stitch screen, a local HTML file, or a URL into modular Vite + React components — TypeScript, theme-mapped Tailwind, dark mode via CSS variables, and clean component architecture. Use this for Vite/React apps without App Router. For Next.js 15 App Router, use stitch-nextjs-components instead. Only the Stitch route needs an API key.

インストール方法を見る

含まれるファイル(5)

  • SKILL.md9.8 KB
  • references/tailwind-to-react.md3.9 KB
  • resources/architecture-checklist.md1.5 KB
  • resources/component-template.tsx1008 B
  • scripts/fetch-stitch.sh1.3 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Stitch → Vite / React Components

Constraint: Only use this skill when the user explicitly mentions "Stitch" and React (Vite, CRA, or just "React app" without Next.js).

You are a frontend engineer converting Stitch mobile/desktop designs into clean, modular React components using Vite + TypeScript. This skill targets plain React apps — not Next.js App Router. For Next.js, use stitch-nextjs-components instead.

When to use this skill vs. Next.js

ScenarioUse
User says "React app", "Vite", "CRA"stitch-react-components
User says "Next.js", "App Router", "SSR"stitch-nextjs-components
User wants shadcn/ui components added afterstitch-react-components → then stitch-shadcn-ui
User wants server-side rendering or file-based routingstitch-nextjs-components

Prerequisites

An HTML source. Any one of these works:

  • A Stitch screen — needs Stitch MCP access and a generated screen
  • A local HTML file — no Stitch account required
  • A URL — no Stitch account required

Also:

  • Node.js + npm/pnpm
  • Vite + React project initialized: npm create vite@latest my-app -- --template react-ts

Step 1: Resolve the source

Everything downstream reads one file: temp/source.html. Get the HTML there by whichever route matches what the user gave you, then continue at Step 2 — the rest of this skill is identical regardless of where the markup came from.

From a Stitch screen:

  1. Namespace discovery — list_tools to find the Stitch MCP prefix
  2. Fetch metadata — [prefix]:get_screen with numeric projectId and screenId
  3. Download HTML — GCS URLs need the reliable downloader:
    bash scripts/fetch-stitch.sh "[htmlCode.downloadUrl]" "temp/source.html"
    
  4. Visual audit — check screenshot.downloadUrl before rewriting. Append =s0 to that URL for full resolution; the bare URL serves a 512px thumbnail regardless of the width/height the API reports.

From a local HTML file:

mkdir -p temp && cp "path/to/design.html" temp/source.html

From a URL:

bash scripts/fetch-stitch.sh "https://example.com/page" "temp/source.html"

Despite the name, that script is a generic hardened downloader — follows redirects, retries transient failures, handles gzip, and fails loudly on an empty result. It does not care whether the URL points at Stitch.

From a screenshot: there's no upload route — the Stitch MCP API has no image-upload tool. Either recreate the design from a text prompt via stitch-mcp-generate-screen-from-text, or hand-write the HTML and use the local-file route above.

Only the Stitch route needs an API key. Converting a local file or a URL works with no Google account at all.

Step 2: Project structure

src/
├── components/           ← One file per component
│   └── [Name].tsx
├── data/
│   └── mockData.ts       ← Static content (never in components)
├── theme/
│   ├── tokens.ts         ← Design token constants
│   └── useTheme.ts       ← Dark mode hook
├── types/
│   └── index.ts          ← Shared TypeScript types
├── App.tsx               ← Root component
└── main.tsx              ← Entry point

Step 3: Extract design tokens

Resolve tokens from whatever the HTML actually gives you, in this order:

  1. Inline tailwind.config in <head> (what Stitch emits) — use it directly if present.
  2. CSS custom properties (:root { --color-primary: ... }) — common in hand-written and templated HTML.
  3. A linked or inline stylesheet — parse declared colors, font-families, radii, spacing.
  4. Last resort — derive tokens from the most frequent computed values in the markup (dominant background, text color, accent, heading/body font, border radius), and tell the user what you inferred so they can correct it.

The URL route only downloads the single HTML response — externally-linked stylesheets may not come along for the ride. If none of the above resolves a token, say so instead of inventing a palette.

// src/theme/tokens.ts
export const lightTokens = {
  background: '#FFFFFF',
  surface:    '#F4F4F5',
  primary:    '#6366F1',
  primaryFg:  '#FFFFFF',
  text:       '#09090B',
  textMuted:  '#71717A',
  border:     '#E4E4E7',
} as const

export const darkTokens = {
  background: '#09090B',
  surface:    '#18181B',
  primary:    '#818CF8',
  primaryFg:  '#09090B',
  text:       '#FAFAFA',
  textMuted:  '#A1A1AA',
  border:     '#27272A',
} as const

export type ThemeTokens = typeof lightTokens
// src/theme/useTheme.ts
import { useEffect, useState } from 'react'
import { lightTokens, darkTokens, type ThemeTokens } from './tokens'

/**
 * Returns current theme tokens based on system color scheme.
 * Listens for system-level dark/light mode changes.
 */
export function useTheme(): ThemeTokens {
  const [isDark, setIsDark] = useState(
    () => window.matchMedia('(prefers-color-scheme: dark)').matches
  )

  useEffect(() => {
    const mq = window.matchMedia('(prefers-color-scheme: dark)')
    const handler = (e: MediaQueryListEvent) => setIsDark(e.matches)
    mq.addEventListener('change', handler)
    return () => mq.removeEventListener('change', handler)
  }, [])

  return isDark ? darkTokens : lightTokens
}

Step 4: Component conversion rules

Layout mapping

HTML/CSS→ React / Tailwind
display:flex; flex-direction:column<div className="flex flex-col gap-4">
display:flex; flex-direction:row<div className="flex items-center gap-2">
justify-content:space-between<div className="flex justify-between">
display:grid; grid-template-columns:1fr 1fr<div className="grid grid-cols-2 gap-4">
overflow-y:scroll<div className="overflow-y-auto">
Long listitems.map(item => <Card key={item.id} {...item} />)
<img><img src="..." alt="..." className="object-cover">

Tailwind class mapping

Use the source HTML's Tailwind classes directly in JSX where they don't reference custom tokens. Map custom tokens to CSS variables:

// Source HTML: bg-primary → CSS variable → Tailwind arbitrary value
// OR: use inline style with token value

// Option A — Tailwind arbitrary value (if custom tokens in tailwind.config)
<div className="bg-[--color-primary] text-[--color-primaryFg]">

// Option B — inline style with useTheme()
const theme = useTheme()
<div style={{ backgroundColor: theme.primary, color: theme.primaryFg }}>

Component template

// src/components/StitchComponent.tsx

/**
 * Props for StitchComponent — all data via props, never fetched inside.
 */
interface StitchComponentProps {
  /** Primary heading text */
  title: string
  /** Supporting description — optional */
  description?: string
  /** Primary action callback */
  onAction?: () => void
}

/**
 * StitchComponent — [describe purpose in one sentence]
 */
export function StitchComponent({
  title,
  description,
  onAction,
}: Readonly<StitchComponentProps>) {
  const theme = useTheme()

  return (
    <div
      className="rounded-xl border p-4 gap-2 flex flex-col"
      style={{
        backgroundColor: theme.surface,
        borderColor: theme.border,
      }}
    >
      <h3 className="text-base font-semibold" style={{ color: theme.text }}>
        {title}
      </h3>

      {description ? (
        <p className="text-sm" style={{ color: theme.textMuted }}>
          {description}
        </p>
      ) : null}

      {onAction ? (
        <button
          onClick={onAction}
          className="rounded-lg px-4 py-2 text-sm font-medium transition-opacity hover:opacity-90"
          style={{ backgroundColor: theme.primary, color: theme.primaryFg }}
          type="button"
        >
          Action
        </button>
      ) : null}
    </div>
  )
}

Step 5: Architectural rules

  • One component per file — no single-file spaghetti
  • Static data in src/data/mockData.ts — never hardcoded in JSX
  • Shared types in src/types/index.ts
  • Every component has Readonly<ComponentNameProps> interface
  • No hardcoded hex colors — use useTheme() or CSS variables
  • No any types

Step 6: Integration with shadcn/ui

After converting the design to base React components, you can layer in shadcn/ui:

npx shadcn@latest init    # Set up shadcn in your Vite project
npx shadcn@latest add button card input dialog

Then use stitch-shadcn-ui skill to replace raw HTML elements with shadcn components while preserving the design tokens.

Troubleshooting

IssueFix
Tailwind classes not applyingCheck tailwind.config.js includes ./src/**/*.{ts,tsx} in content
Dark mode not togglingVerify useTheme() is called at component level, not hoisted
Images not showingAdd explicit width and height or use className="w-full h-auto"
Type error on propsEnsure Readonly<> wrapper and all required props are provided

References

  • resources/component-template.tsx — Boilerplate component
  • resources/architecture-checklist.md — Pre-ship checklist
  • references/tailwind-to-react.md — Token + class mapping guide (source HTML → React/Tailwind)
  • scripts/fetch-stitch.sh — Reliable GCS HTML downloader
  • stitch-shadcn-ui — Add shadcn/ui components after base conversion
  • docs/tailwind-reference.md — Tailwind utility class lookup

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Audits Stitch-generated components for WCAG 2.1 AA accessibility issues and applies fixes — semantic HTML, ARIA attributes, keyboard navigation, focus management, and screen reader support.

日本語の概要は準備中です。原文の説明を表示しています。

gabelul/stitch-kit452026年7月21日 更新

Adds a purposeful animation layer to Stitch-generated components — CSS transitions, Framer Motion (React/Next.js), or Svelte transitions. Always respects prefers-reduced-motion.

日本語の概要は準備中です。原文の説明を表示しています。

gabelul/stitch-kit452026年7月21日 更新

Analyzes a Stitch project's screens and synthesizes a natural-language DESIGN.md — visual atmosphere, color palette with hex values, typography rules, and Stitch-ready prompt snippets. Use this before stitch-loop or any multi-page build to establish design consistency.

日本語の概要は準備中です。原文の説明を表示しています。

gabelul/stitch-kit452026年7月21日 更新

Extracts a Stitch design and generates production code artifacts — CSS custom properties with dark mode tokens, a Tailwind v4 @theme block, and a semantic design system document. Run this before framework conversion skills.

日本語の概要は準備中です。原文の説明を表示しています。

gabelul/stitch-kit452026年7月21日 更新

Converts a Stitch screen, a local HTML file, or a URL into clean, platform-agnostic HTML5 + CSS — semantic markup, CSS custom properties for theming, dark mode via prefers-color-scheme, mobile-first responsive, zero framework dependencies. Works in browsers, WebViews, Capacitor, and Ionic. Only the Stitch route needs an API key.

日本語の概要は準備中です。原文の説明を表示しています。

gabelul/stitch-kit452026年7月21日 更新

Conversational design ideation agent that researches trends, explores visual directions, and refines ideas through adaptive questioning — then produces a rich PRD document and auto-generates Stitch screens. Your design buddy that thinks deeply before designing.

日本語の概要は準備中です。原文の説明を表示しています。

gabelul/stitch-kit452026年7月21日 更新

gabelul のスキルをすべて見る

このスキルの問題を報告する