How to Implement Dark Mode in Stitch-to-React Conversion: A Complete Guide

You implement dark mode in Stitch-to-React conversion by capturing the design with a dark class using the snapshot.ts script, configuring Tailwind to use darkMode: ["class"], and ensuring every generated component applies dark: variants to all color utilities.

When converting Stitch designs to React components, implementing dark mode requires coordination between the extraction script, Tailwind configuration, and component generation rules. The google-labs-code/stitch-skills repository provides specific tools and constraints that automate this process across the static HTML extraction and React component generation phases. This guide explains how to leverage the --html-class flag, class-based Tailwind configuration, and mandatory dark-variant rules to produce components that automatically respond to theme changes.

Capture the Design with Dark Mode Classes

The first step involves capturing the design using the snapshot.ts script with the --html-class flag. This script, located at plugins/stitch-design/skills/extract-static-html/scripts/snapshot.ts, extracts a full-page HTML snapshot and can inject any class onto the <html> element during capture.

When you supply dark as the value for --html-class, the page renders itself in its dark theme before extraction. This ensures that the captured HTML includes the dark palette color tokens that the React components will later reference.

npx tsx snapshot.ts \
  --url http://localhost:5173/dashboard \
  --output .stitch/dashboard.html \
  --html-class dark

According to the source code at lines 50-57 in snapshot.ts, this flag handles the class injection during the snapshot process, forcing the design to render with dark mode activated (equivalent to Tailwind’s data-theme="dark" behavior).

Configure Tailwind for Class-Based Dark Mode

The React component skill requires Tailwind’s darkMode setting to be configured as ["class"]. This setting, documented in plugins/stitch-build/skills/shadcn-ui/resources/setup-guide.md at line 172, instructs Tailwind to apply dark: utility classes only when an ancestor element (typically <html>) carries the dark class.

Update your tailwind.config.js to enable this behavior:

module.exports = {
  darkMode: ["class"],   // Required for Stitch-to-React conversion
  content: ["src/**/*.{tsx,ts,js,jsx}"],
  theme: {
    extend: {
      colors: {
        primary: "var(--color-primary)",
        "primary-dark": "var(--color-primary-dark)",
        // Additional tokens synchronized from style-guide.json
      },
    },
  },
};

This configuration ensures that the generated components respond dynamically to the presence of the dark class at runtime.

Apply Dark Variants to Component Classes

The react-components skill enforces a strict dark-mode rule: all color utilities in generated components must use Tailwind’s dark-mode variants. This requirement is defined in plugins/stitch-build/skills/react-components/SKILL.md at lines 78-80.

When generating components, you must replace every plain color utility (e.g., bg-primary) with a dark-mode pair:

// Correct implementation with dark variants
export const Card = () => (
  <div className="rounded-lg bg-surface p-4 shadow-sm dark:bg-surface-dark">
    <h2 className="text-primary dark:text-primary-dark">
      Card title
    </h2>
    <p className="text-muted dark:text-muted-dark">
      Supporting text
    </p>
  </div>
);

The skill’s validator flags any missing dark: variants during the build process, ensuring visual parity between light and dark themes in the final React output.

Step-by-Step Implementation Workflow

Follow this workflow to ensure dark mode works end-to-end in your Stitch-to-React conversion:

  1. Snapshot the design with dark mode – Run the snapshot.ts script with --html-class dark to capture the design already rendered in dark mode. This attaches the dark class to the <html> element in the extracted HTML.

  2. Import the snapshot – The react-components skill reads the generated HTML via the MCP get_screen flow and extracts the embedded Tailwind configuration, including dark-mode color tokens.

  3. Synchronize Tailwind configuration – Overwrite resources/style-guide.json with the tokens extracted from the snapshot (Phase 2 of the skill). This file holds the color definitions, including dark variants, that components reference.

  4. Enable class-based dark mode – Verify that your tailwind.config.js contains darkMode: ["class"] to ensure Tailwind responds to the dark class on <html>.

  5. Generate components – Execute the component generation step using resources/component-template.tsx, which includes placeholders for Tailwind classes.

  6. Validate dark variants – Ensure every color utility in the generated JSX uses dark: prefixes. The skill validator will catch any omissions.

  7. Test the implementation – Start the development server and toggle the dark class on <html> using document.documentElement.classList.toggle('dark') to verify that all components respect the dark palette.

Summary

Implementing dark mode in Stitch-to-React conversion requires three coordinated actions:

  • Capture with --html-class dark using the snapshot.ts script to extract dark-themed color tokens
  • Configure darkMode: ["class"] in tailwind.config.js to enable class-based dark mode detection
  • Apply dark: variants to every color class in generated components, as enforced by the react-components skill rules

By following these steps and referencing the extracted tokens in resources/style-guide.json, you create React components that automatically switch between light and dark themes when the dark class is toggled on the document root.

Frequently Asked Questions

How do I toggle dark mode at runtime in the generated React components?

You can toggle dark mode by adding or removing the dark class from the <html> element. Implement a theme switcher that calls document.documentElement.classList.toggle("dark") to switch between themes instantly. Since the components use Tailwind's dark: variants and the configuration uses darkMode: ["class"], the UI updates immediately without requiring page reloads or additional JavaScript logic inside individual components.

What happens if I forget to add dark: variants to a color class?

The react-components skill includes a validator that flags any color utilities missing their dark: counterparts during the build process. According to the skill documentation at plugins/stitch-build/skills/react-components/SKILL.md, applying dark: variants to all color classes is mandatory. If you bypass this validation, components will display light-mode colors even when the dark class is present, breaking visual consistency.

Where are the dark mode color tokens stored after extraction?

The dark mode color tokens are stored in plugins/stitch-build/skills/react-components/resources/style-guide.json. During Phase 2 of the skill workflow, this file is synchronized with the tokens extracted from the HTML snapshot captured with the --html-class dark flag. The generated components reference these tokens (e.g., var(--color-primary-dark)) to ensure they match the original design's dark palette.

Can I use the media strategy instead of class for dark mode in Stitch-to-React?

No, the Stitch-to-React conversion specifically requires the class strategy. The shadcn-ui setup guide in plugins/stitch-build/skills/shadcn-ui/resources/setup-guide.md explicitly specifies darkMode: ["class"] because the workflow depends on programmatically toggling the dark class on the <html> element. Using the media strategy would prevent the snapshot script from capturing the design in dark mode and break the component generation logic that relies on class-based dark variant detection.

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 →