---
title: "Design Comparison"
sidebarTitle: "Design Comparison"
description: "Compare your coded components with their Figma design: deeepSpace renders your code in a real browser, measures it, and lists every difference in size, spacing, color, typography and content."
keywords: "design vs code comparison, figma code comparison, visual regression design system"
icon: "git-compare"
---

deeepSpace renders each component from your code in a real browser, in every variant you designed in Figma, and compares it with the design: sizes, spacing, colors, borders, corner radius, typography, text, icons, and a pixel comparison of the whole component.

## Before you begin

- **React** components (`.tsx`, `.ts`, `.jsx`, `.js`). Vite, Next.js, webpack and Create React App projects are supported, with or without Storybook.
- The component is pushed from Figma with the latest **deeepSpace Figma plugin**.
- The Figma component is **linked to its code component** in deeepSpace: on the component page, the **Details** panel → **Code** → **Link the code** (or **Match components** on the Components page, to link them all at once). Every component your files export can be linked, including parts that live next to a main component (a `TableRow` beside `Table`).
- Your project's dependencies are installed (`npm install`, `pnpm install`…): the CLI builds your components with them.

## How it runs

1. Run `deeep sync`. After syncing your components, the CLI builds them into a small preview app with your project's own settings (path aliases, Tailwind/PostCSS, CSS modules, Sass, fonts, global styles and providers) and uploads it **privately** to deeepSpace.
2. deeepSpace renders every Figma variant of each linked component in a sandboxed browser, then compares it with the design.
3. Open the component in deeepSpace: each variant shows how closely the code matches it. A comparison usually takes about a minute.

The sync output ends with one of:

| Message | Meaning |
|---|---|
| **Design comparison started** | Your build was uploaded; results appear in a minute or so. |
| **Design comparison up to date** | Nothing changed since the last comparison. |
| **Design comparison skipped** | The build couldn't be made; the message says why. Your component sync itself succeeded. |

<Note>
A component that fails to build (a missing import, for example) is **set aside**: the sync output names it and the reason, and every other component is still compared.
</Note>

The preview page is the default. If it can't be built and the project has Storybook, the CLI uses your Storybook instead, opening each component's story with the design's values as story args.

## Reading the results

Everything is on the component page.

- **Score**: the pill at the top, such as *87% · Close to the design*, is how closely the component matches its design across all variants. Green from 95%, orange from 80%, red below. Click it to open the variant that needs the most work.
- **Variants**: every variant designed in Figma, as cards, each with its own score and number of differences. Filter them by Figma property. Move the mouse across a card to swipe between the design and your rendered code.
- **One variant**: click a card to open it. Switch between **Design**, **Code** (your component, rendered), **Side by side** and **Swipe** (drag the line between the design and the code). Use <kbd>←</kbd> <kbd>→</kbd> or the strip at the bottom to move between variants, and <kbd>Esc</kbd> to go back to all of them.
- **Differences**: each one is a numbered pin on the image and a line in the panel on the right, in plain words: *Font size: 16px in design, 14px in code*. Click a pin or a line, or use <kbd>↑</kbd> <kbd>↓</kbd>: the spot is outlined, the rest of the image fades, and its values show next to it.
  - **High** and **Medium** differences are the ones you can see. **Minor** ones (a color or size that isn't a design token, details barely visible) are folded into one line; **Show** lists them and pins them too.
  - A difference caused by another one (a button is narrower because its font is smaller) is listed under its cause, not as a separate difference.
  - The same difference on repeated elements (five accordion titles) is one difference, *in 5 places*.
- **How it's rendered** (in the panel of a variant): the exact code rendered, for example `<Button variant="secondary" size="sm">Label</Button>`, and how each Figma property was turned into a prop. You can correct it.
- **What's checked** (in the panel of a variant): what was matched and checked, and what isn't checked yet.

Use **Compare again** (the **Details** panel → **Code**) to run the comparison now, even if nothing changed.

## When something isn't right

| You see | What to do |
|---|---|
| **Your code couldn't be rendered** for a variant | Open the variant → **How it's rendered**: a Figma value may need a different prop or value. Edit the row; your correction applies from the next comparison, which starts right away. |
| The wrong code component is compared | The **Details** panel → **Code** → **Change**, then pick the right one. |
| A difference that isn't real | Select it, then **Not right?**: it is stored for review and doesn't change the result. |
| *Font "…" is not in the code build* | Your project's build doesn't load a font the design uses, so text is drawn with a fallback and its size differences barely count. Load the font in your app's global styles or root layout. |
| **The comparison failed** | It is retried automatically. If it still fails, the page says why: use **Compare again**. |

Mappings come from your **Figma Code Connect** files when you have them, otherwise from matching names. Your corrections always win.

## Known limits

The comparison doesn't check everything yet. Knowing what it can't see keeps a result from being read as more (or less) than it is.

| Limit | What you'll see |
|---|---|
| **Animations, transitions, loading and skeleton states** | These variants are listed but not compared yet. |
| **Other screen sizes** | Each variant is compared at the width it has in Figma only. |
| **Shapes drawn in CSS only** (`::before` / `::after`, such as a switch's knob or a custom check mark) | Their size and color aren't measured. The pixel comparison still sees them: a difference there shows as *looks different in this area*. |
| **Sample content that only exists in the design** (a modal's example paragraph, a card's placeholder text) | Text the design shows is passed to your component's text props automatically. When the component has no prop for it (the page fills it in), the code renders without it and it shows as missing: mark it **Not right?** if that's expected. |
| **Parts that only work inside their parent** (form fields that need their form, resizable panels that need their group) | The preview places a part inside its parent automatically when it can. When it can't, the part fails to render or looks different on its own: compare the parent component instead. |
| **Storybook rendering** | When the comparison renders from your Storybook (the fallback, or `"source": "storybook"`), only components with a story are compared. The preview page has no such limit. |

## Settings

Add an optional `compare` block to `deeep.json`:

```json deeep.json
{
  "compare": {
    "enabled": true,
    "source": "auto",
    "css": ["src/styles/globals.css"],
    "head": "compare-head.html",
    "wrapper": "src/test/Providers.tsx",
    "decorators": true,
    "stories": { "Button": "components-button--primary" }
  }
}
```

| Key | Default | Meaning |
|---|---|---|
| `enabled` | `true` | `false` turns the comparison build off for this project. |
| `source` | `"auto"` | `"preview"` or `"storybook"` forces one way of rendering; `"auto"` uses the preview page and falls back to Storybook. |
| `css` | detected | Global stylesheets to load, when the CLI doesn't find them in your app's entry, root layout or Storybook preview. |
| `head` | detected | An HTML file with extra `<head>` tags (font links, for example). |
| `wrapper` | detected | A component that wraps every render (theme or providers). By default your Storybook decorators are reused. |
| `decorators` | `true` | `false` stops reusing your Storybook decorators. |
| `stories` | automatic | For Storybook rendering, the story to use per component name. |

## Privacy

Your build is uploaded privately and only used to render your components. Comparison images are visible only to people with access to your project. Old builds and images are cleaned up automatically.
