Tutorial · 9 min read

Design System Migration: From Code to Figma Components

Your codebase already encodes your design system — every token, every component, every spacing value. Here's how to extract it into a native Figma library without rebuilding from scratch.

HF

HTML to Figma Team

Design system migration from code to Figma is the process of extracting an existing design system encoded in HTML and CSS into a native Figma component library. Rather than rebuilding from a blank canvas, you capture the browser's computed output — resolved colors, spacing, and typography — and import it into Figma using a tool like html2design. The result is a Figma library that accurately reflects what is already live in production, with design tokens derived directly from your CSS.

The Problem: Design Drift Between Code and Figma

Design drift is what happens when the code and the design file stop describing the same product. It starts small: a developer tweaks a button padding to fix a layout issue and doesn't update Figma. A designer iterates on a card component in Figma but the changes never make it to a developer ticket. Within months, the Figma file and the live product are two different things.

The root cause is almost always a missing migration step. A company builds a product in code first — or iterates so quickly that design files fall behind — and never formalizes the design system in Figma. Later, when the team grows and designers need editable files, they find themselves staring at a blank Figma canvas while the actual system lives entirely in a stylesheet.

Common signs of design drift: designers recreating components from screenshots instead of a library, developers getting "the specs are in Figma" on work that was never actually designed there, and onboarding taking weeks because new designers have to reverse-engineer the live product instead of reading a component library.

The solution is not to freeze the codebase and rebuild Figma from scratch — that takes months and the result is immediately out of date. The better path is to extract the design system that already exists in your code and import it into Figma with full fidelity.

Step 1: Audit Your Codebase for Design Tokens

Before touching Figma, spend an hour auditing your CSS for the raw material of your design system. You're looking for three categories of tokens:

Token Type Where to Find It Figma Equivalent
Colors CSS custom properties (--color-primary), Sass/Less variables, Tailwind config, Bootstrap theme overrides Color Variables or Color Styles
Spacing Base spacing scale (--spacing-4: 1rem), padding/margin values used across components Number Variables
Typography Font-family declarations, type scale (--text-sm, --text-lg), font-weight and line-height values Text Styles
Radii & shadows Border-radius values (often a small set: 4px, 8px, 16px, full), box-shadow declarations Number Variables, Effect Styles

If your codebase uses CSS custom properties on :root, you can extract the full token list in seconds by opening DevTools, selecting the <html> element, and scanning the Computed panel. Every -- prefixed variable is a potential Figma Variable.

/* What you find in DevTools: Computed > CSS Properties */
--color-primary: #2563EB;
--color-primary-dark: #1E40AF;
--color-surface: #F9FAFB;
--spacing-base: 1rem;
--spacing-sm: 0.5rem;
--spacing-lg: 1.5rem;
--font-sans: 'Inter', system-ui, sans-serif;
--text-sm: 0.875rem;
--text-lg: 1.125rem;
--radius-md: 0.5rem;
--radius-lg: 1rem;

Step 2: Build a Token Reference Page

The most reliable way to extract design tokens into Figma is to create a single HTML page that renders every token visually — a color palette, a spacing scale, a typography specimen, a shadow gallery. This page becomes your import document for html2design.

The page doesn't need to be pretty. Its only job is to render every token as a visible element so the browser computes the styles. Here's the minimum structure:

<!-- Colors -->
<div class="token-row">
  <div style="width:48px;height:48px;background:var(--color-primary);border-radius:8px"></div>
  <span>color-primary</span>
</div>

<!-- Spacing -->
<div style="height:var(--spacing-base);background:#E5E7EB;width:100%"></div>

<!-- Typography -->
<p style="font-size:var(--text-lg);font-family:var(--font-sans)">Large Text</p>

Once the token reference page is open in your browser, open DevTools, select the root element, and copy its outerHTML. Then paste it into html2design in Figma. You'll get a single frame with all your tokens rendered at their exact computed values — the right blue, the right 16px spacing, the right font rendered in its actual weight.

Use this frame as the source of truth to register Color Variables, Number Variables, and Text Styles in Figma. You can inspect each rendered element with the Figma eyedropper and match values exactly.

Step 3: Identify and Prioritize Components

A design system component inventory is a list of every distinct UI component in your codebase ranked by how often it appears. You don't need to import everything at once — start with the components that block the most design work.

Priority 1 — Atoms

Buttons, inputs, badges, labels, icons

These are used everywhere and their styles (padding, border-radius, color, font-weight) are the most frequently referenced in design work. Import all states: default, hover, focus, disabled.

Priority 2 — Molecules

Cards, form fields, dropdowns, modals, alerts

Composed of atoms. Import the full rendered component, including any nested elements — html2design preserves the entire layer hierarchy. Cards with headings, metadata, and actions import as nested Figma groups.

Priority 3 — Organisms

Navigation, hero sections, data tables, footers

Large, complex layouts. Import these last. They're useful for page-level design work but not needed for the core component library to be functional.

Step 4: Import Components with HTML to Figma

For each component, the workflow is the same three steps: render in browser → copy outerHTML → import into Figma.

  1. Open your component in a browser — a Storybook story, a local dev server, or a staging environment
  2. Open DevTools (F12 or Cmd+Option+I) and navigate to the Elements panel
  3. Right-click the root element of the component and select Copy > Copy outerHTML
  4. Open Figma, launch the html2design plugin
  5. Paste the outerHTML into the plugin and click Import
  6. A new Figma frame appears with the component rendered at pixel-perfect fidelity

Capturing component states: DevTools' Force element state feature lets you trigger :hover, :focus, and :active without JavaScript. Right-click the element in the Elements panel, select Force state, and check the desired pseudo-class. The rendered state is now stable — copy the outerHTML while that state is active. You'll get a separate Figma frame for each state, which you can set up as Component Variants.

Handling interactive components (dropdowns, modals)

Some components only render their full DOM when triggered by user interaction. For dropdowns, open the dropdown first, then open DevTools and copy the outerHTML of the parent before closing it. For modals, trigger the modal open, then use DevTools to find the .modal or [role="dialog"] element while it's still visible and copy it. If the component dismisses before you can copy, add pointer-events: none to the backdrop in DevTools to freeze it in place.

Step 5: Organize Components in Figma

Raw imported frames are useful but not yet a design system. To make them a publishable Figma library, you need to convert frames to Components and organize them with a consistent naming convention.

The standard naming pattern that matches most codebases is:

Category / ComponentName / VariantName

Button / Primary / Default
Button / Primary / Hover
Button / Primary / Disabled
Button / Secondary / Default
Input / Text / Empty
Input / Text / Filled
Input / Text / Error
Card / Default
Badge / Success
Badge / Warning

To convert an imported frame to a Figma Component: select the frame, then press Cmd+Alt+K (macOS) or Ctrl+Alt+K (Windows). Add it to a dedicated Design System page in your Figma file, then publish that file as a Figma Library so other files can use the components.

Binding components to tokens

After importing components, connect their fills, strokes, and text to the Figma Variables you created from your token reference page. Select a button's background fill, click the Variable picker, and map it to color-primary. This step is manual but it pays off immediately — when a token value changes in your design file, every bound component updates automatically.

Extracting Design Tokens from CSS: Detailed Reference

If your codebase doesn't use CSS custom properties, you can still extract tokens from the computed CSS values in DevTools. Here's what to look for across common CSS frameworks:

Framework Token Location Extract Method
Plain CSS :root { --token: value } in main stylesheet DevTools → Elements → <html> → Computed → filter --
Tailwind tailwind.config.js theme object Build a token reference page using @apply or inline classes; import with html2design
Bootstrap $primary, $font-size-base, etc. in compiled CSS Inspect any Bootstrap-styled element; colors and spacing resolve to exact values in Computed panel
CSS-in-JS (styled-components) Theme object passed via ThemeProvider React DevTools → find ThemeProvider component → inspect theme prop for full token map

When to Migrate vs. Build from Scratch

Extracting a design system from code is the right choice in most cases, but not all. Use this decision guide:

The hybrid approach works well for growing teams: the migrated library unblocks designers immediately (they stop recreating components from screenshots) while the fresh components give them room to iterate on the next version of the system without touching the live production layer.

Keeping Code and Figma in Sync After Migration

Migration is not a one-time event. To prevent drift from building back up, establish a lightweight maintenance cadence:

  1. Token change: when a CSS custom property changes, update the corresponding Figma Variable. If your team uses a design token pipeline (Style Dictionary, Theo), consider exporting Figma Variables JSON from that same source of truth.
  2. Component change: when a component's visual appearance changes in code, re-import it via html2design and update the Figma Component. Schedule a monthly review of the 10 most-used components to catch drift early.
  3. New component: whenever a new component ships in code, add importing it to Figma to the definition of done for that ticket. This prevents the migration backlog from rebuilding.

FAQ

Can I extract design tokens from a production website I don't own the source for?

Yes — you can read computed CSS values from any website you can open in a browser. DevTools shows the computed value of every CSS property on every element, regardless of whether you have the source code. This is useful for auditing a competitor's design system or capturing a client's existing site before a redesign. html2design works from outerHTML, which includes all inline computed styles — no source access required.

What if my codebase has no token system and uses hardcoded values?

That's the most common situation. Import a representative set of components first, then use the Figma Edit > Find/Replace tool to find every instance of a common value (e.g., the hex code #2563EB) and replace it with a Color Variable. The migration becomes a token consolidation exercise — you're discovering the tokens that were implicit in the code and making them explicit in Figma.

Does html2design work with server-side rendered pages?

Yes. html2design works from rendered HTML, which the browser has already produced regardless of how it was generated — Next.js SSR, Rails, PHP, static HTML. The source of the markup doesn't matter. What matters is that the browser has rendered it with full styles applied, which you capture via DevTools' outerHTML copy.

How do I handle icons in the design system migration?

SVG icons copy cleanly. When you copy a component's outerHTML that contains inline SVGs, the full SVG markup comes along. html2design imports SVG elements as Figma vector nodes — fully editable, preserving paths, fills, and dimensions. If your icon library renders SVGs via CSS mask-image or background images, DevTools' Computed panel shows the resolved image URL; you can download the SVG and import it into Figma as a standalone icon.

Key Takeaways


Related Articles

Try it now

Migrate your design system in hours, not weeks

Install html2design from the Figma Community. Paste any component's outerHTML. Get editable Figma layers with exact token values — no rebuilding from scratch.

Install from Figma Community →

$12/mo · $96/yr · Cancel anytime

← Back to Blog