---
title: "Design-Driven Development: Build Types from Figma Quickly"
slug: "design-driven-development-build-types-from-figma"
published: "2025-11-15"
updated: "2025-12-25"
categories:
  - "Payload"
tags:
  - "design-driven development"
  - "Figma to TypeScript"
  - "type-first development"
  - "Payload CMS integration"
  - "component-driven design"
  - "frontend architecture"
  - "shadcn/ui"
  - "Lucide icons"
  - "example data documentation"
  - "no refactor workflow"
llm-intent: "reference"
audience-level: "intermediate"
framework-versions:
  - "figma"
  - "typescript"
  - "react"
  - "payload cms"
  - "shadcn/ui"
status: "stable"
llm-purpose: "Design-driven development: use Figma as your spec to create TypeScript types, build reusable components, and speed Payload CMS integration—ship without…"
llm-prereqs:
  - "Access to Figma"
  - "Access to TypeScript"
  - "Access to React"
  - "Access to Payload CMS"
  - "Access to shadcn/ui"
llm-outputs:
  - "Completed outcome: Design-driven development: use Figma as your spec to create TypeScript types, build reusable components, and speed Payload CMS integration—ship without…"
---

**Summary Triples**
- (Figma, is used as, single source of truth for data structure and UI expectations)
- (Design-driven workflow, derives, TypeScript types directly from Figma layers and visible fields)
- (Types, must match, exact fields shown in the design (required vs optional decided by what renders))
- (Components, are built using, the derived TypeScript types so props align with design)
- (Payload CMS, integrates by, mapping TypeScript types to Payload collections/fields for one source of truth)
- (Example data documentation, helps, communicate expected values and edge cases to backend and QA)
- (shadcn/ui and Lucide, are used for, implementing consistent UI primitives and icons from the design)
- (Design-first workflow, reduces, refactors, type mismatches, and integration churn)
- (Workflow steps, are, Inspect Figma → list fields → create TypeScript types → build components → map to Payload → document example data)
- (Required vs optional fields, are determined by, whether the design always displays a value or can omit it visually)

### {GOAL}
Design-driven development: use Figma as your spec to create TypeScript types, build reusable components, and speed Payload CMS integration—ship without…

### {PREREQS}
- Access to Figma
- Access to TypeScript
- Access to React
- Access to Payload CMS
- Access to shadcn/ui

### {STEPS}
1. Review Figma designs thoroughly
2. Identify required data fields
3. Create TypeScript types from design
4. Build components using types
5. Add example data as documentation
6. Map types to Payload CMS fields
7. Swap data source with minimal changes

<!-- llm:goal="Design-driven development: use Figma as your spec to create TypeScript types, build reusable components, and speed Payload CMS integration—ship without…" -->
<!-- llm:prereq="Access to Figma" -->
<!-- llm:prereq="Access to TypeScript" -->
<!-- llm:prereq="Access to React" -->
<!-- llm:prereq="Access to Payload CMS" -->
<!-- llm:prereq="Access to shadcn/ui" -->
<!-- llm:output="Completed outcome: Design-driven development: use Figma as your spec to create TypeScript types, build reusable components, and speed Payload CMS integration—ship without…" -->

# Design-Driven Development: Build Types from Figma Quickly
> Design-driven development: use Figma as your spec to create TypeScript types, build reusable components, and speed Payload CMS integration—ship without…
Matija Žiberna · 2025-11-15

> Part 1 of the [Design to Code](/blog/design-driven-block-systems) series — A complete guide to building block systems with Payload CMS

I've rebuilt components more times than I'd like to admit. The pattern was always the same: start coding, realize halfway through that the data structure doesn't match what the design actually needed, refactor everything. It's exhausting.

Then I discovered a simple principle that changed how I approach frontend architecture: let design drive the data structure, not the other way around. This guide explains why that works and how it makes your life easier.

## The Problem with Traditional Development

Most developers start like this:

1. Guess at a data structure
2. Build the backend/database
3. Build the frontend UI
4. Realize the UI doesn't match the design
5. Refactor everything (repeat steps 1-4)

This approach treats design as an afterthought. The result? Hours of refactoring, inconsistent components, and code that doesn't match the original mockups.

The costs add up fast. A "simple button redesign" cascades into type changes, component rewrites, and data migration discussions. One bad decision early on haunts you for months.

## The Solution: Design Comes First

Design-driven development flips the sequence:

1. Look at Figma design
2. Identify every data field the design needs
3. Create types that match those fields exactly
4. Build components using those types
5. Everything works on day one—no refactoring needed

This works because Figma is already your specification. The design shows you exactly what data you need, what's required vs optional, what's displayed where, and how it relates to other elements.

Why guess when you can just look at the design?

## How This Makes Your Life Easier

Let me show you five concrete ways this approach saves time and frustration.

### 1. No Guessing at Data Structure

You're building a feature card. Traditional approach:

```typescript
interface Feature {
  id: string;
  name: string;
  // Wait... does it need description?
  // Does it need an image?
  // What about a button?
  // Is the icon required?
}
```

You end up making assumptions. Half of them are wrong. You discover the problems two days later when the designer says "it needs a link at the bottom."

Design-driven approach:

Open Figma. Look at the feature card design. You immediately see:
- Icon (top left)
- Title (below icon)
- Description (below title)
- Button/link (bottom)

Your type becomes obvious:

```typescript
interface Feature {
  id: string;
  icon: string;           // ← Figma shows this
  title: string;          // ← Figma shows this
  description: string;    // ← Figma shows this
  cta: CTA;              // ← Figma shows this
}
```

Done. No guessing. Everything comes directly from the design.

### 2. Types Become Your Specification

When someone asks "what fields should this collection have?", you don't need meetings or debates. You look at Figma.

Your type IS your specification. It answers:

- What data exists? (type fields)
- What's required vs optional? (required fields vs `?:`)
- What format is it? (string, number, CTA, Media, etc.)
- How does it relate to other data? (references other types)

Later, when you integrate with Payload CMS, you just follow your types. Payload config becomes a direct translation of your types. No surprises, no mismatches.

### 3. Components Write Themselves

Once you have the type, building the component is straightforward:

```typescript
interface Feature {
  icon: string;
  title: string;
  description: string;
  cta: CTA;
}

// Component: just display what the type tells you to display
export function FeatureCard({ feature }: { feature: Feature }) {
  return (
    <Card>
      <Icon name={feature.icon} />  {/* It's a string → resolve to Lucide */}
      <h3>{feature.title}</h3>       {/* Display title */}
      <p>{feature.description}</p>   {/* Display description */}
      <Button>{feature.cta.label}</Button>  {/* Display CTA */}
    </Card>
  );
}
```

The type literally tells you what to render. There's no creativity needed—just follow the type. This is where the real speed comes from.

### 4. Example Data Becomes Your Documentation

Before integrating with Payload, you create example data. This becomes simultaneously:

- Testing data (you can see components working immediately)
- Documentation (new developers see how to use the type)
- Proof of concept (the feature is already "working")
- Copy-paste template (future developers copy this pattern)

One artifact serves four purposes. That's efficient.

### 5. Payload Integration is Trivial

The hardest part of CMS integration is usually the question: "What fields should we actually create in Payload?"

With design-driven development, you already have the answer. Your types ARE the answer.

Your manual type:

```typescript
interface Industry {
  id: number;
  title: string;
  slug: string;
  description: string;
  image: Media;
  icon: string;
}
```

Payload config (just follow the type):

```typescript
{
  slug: 'industries',
  fields: [
    { name: 'title', type: 'text', required: true },
    { name: 'slug', type: 'text' },
    { name: 'description', type: 'textarea' },
    { name: 'image', type: 'upload' },
    { name: 'icon', type: 'text' },
  ]
}
```

No debates. No "should this be a string or number?" No mismatches. Just follow your specification.

## The Magic: Zero Refactoring for Payload

This is the biggest payoff. Imagine building the entire frontend with custom types and example data. Then, months later, you integrate Payload CMS.

**Before Payload:**

```typescript
import { industryExample } from '@/types/collections';

const industry = industryExample;
```

**After Payload:**

```typescript
const industry = await getCollection('industries').findById(id);
```

Your component? Unchanged. Your types? Same imports, different source. Your entire codebase? Works exactly as before.

You're not building a prototype that needs rewriting. You're building the real thing incrementally. This is powerful.

## Why This Works in Practice

Let's trace through a real scenario:

**Day 1:** Designer finishes "Featured Industries" mockup
**Day 2:** You look at Figma, create the Industry type and FeaturedIndustries block type
**Day 3:** You build the component using shadcn/ui and Lucide icons
**Day 4:** You create example data and add it to the page. It looks perfect.
**Day 5-10:** You build other features
**Month 2:** You connect to Payload CMS. The integration takes one afternoon because your types and Payload config already match perfectly.

At no point did you say "we need to change the data structure." At no point did you refactor components because the fields changed. Design drove everything.

## Key Principles of Design-Driven Development

These principles make the approach work:

1. Design is Your Specification
Stop guessing. Look at Figma. Design tells you exactly what you need.

2. Types Mirror Design
Your types should directly reflect what Figma shows. One-to-one mapping.

3. Components are Dumb
Components don't decide what data exists. They just display what types tell them to display.

4. Reuse Global Types
CTA, Image, Button—use them everywhere. Consistency is free.

5. Example Data is Documentation
Before Payload, example data IS your specification. Later, Payload provides the data.

6. No Refactoring on CMS Integration
Your code structure doesn't change. Only the data source changes.

## When to Use This Approach

This approach works best when:

- You're building a design system with multiple variations
- You'll eventually integrate with a CMS like Payload
- You want consistency across components
- Design comes before implementation
- You want minimal refactoring

It's less necessary if:

- You're building a one-off page that won't scale
- Design is very fluid and changes constantly
- You're working with an existing, rigid database schema

For your project, it's exactly the right fit. You have Figma designs driving everything, and you plan to integrate Payload CMS. Design-driven development prevents the chaos.

## The Real Benefit: Peace of Mind

Beyond the time savings and refactoring prevention, there's a mental benefit: you know you're building the right thing.

When you look at the design and say "this is what the design needs," you're making a decision based on evidence, not guessing. When you build the component, you're implementing a specification, not interpreting vague requirements. When you integrate Payload, you're confirming the contract was right all along.

That confidence compounds. You stop second-guessing yourself. You ship faster. Your code is more consistent. Your team understands the approach.

It's not magic. It's just having a clear specification before you code.

## LLM Response Snippet
```json
{
  "goal": "Design-driven development: use Figma as your spec to create TypeScript types, build reusable components, and speed Payload CMS integration—ship without…",
  "responses": [
    {
      "question": "What does the article \"Design-Driven Development: Build Types from Figma Quickly\" cover?",
      "answer": "Design-driven development: use Figma as your spec to create TypeScript types, build reusable components, and speed Payload CMS integration—ship without…"
    }
  ]
}
```