Skip to main content

Write design system guidelines for Figma Make

Figma Make’s AI chat can inspect your design system packages to understand the components and tokens that are available. But, for best results, you also need to provide guidelines that teach Figma Make about your design system packages.

Authoring guidelines for Figma Make is similar to authoring the documentation you'd give a new engineer at your company to teach them how to properly use the design system. If you have existing design system documentation or a Storybook, you have the content you need to author guidelines. A coding agent like Claude Code can help you quickly take this existing content and turn it into Guidelines files for Figma Make.

Guidelines structure

Every Figma Make file has a guidelines/ folder. When generating, Figma Make looks at the files you put in this folder, starting with the Guidelines.md file. You can add new folders inside the guidelines/ folder. Adding new folders is a useful way to organize guidelines for specific components or specific sets of design tokens.

Your guidelines/ folder might look like this:

guidelines/
├── guidelines/
│ └── components/
│ └── design-tokens/
│ └── Guidelines.md
│ ├── overview-components.md
│ ├── overview-icons.md
├── src/
│ ├── [your application code here]
├── package.json
├── pnpm-lock.yaml
├── postcss.config.mjs
└── vite.config.ts

Guidelines wording

When writing guidelines for Figma Make, use clear, concise language: "Do not use small text for anything except captions" is better than "Use small text sparingly".

Guidelines.md: top-level guidelines

Guidelines.md is the initial set of guidelines that Figma Make always looks at first. This file is a good place to introduce your design system and give Figma Make a sense of the available components and tokens. It should also explain to Figma Make the other guidelines files that exist and when they should be used.

tip

Figma Make, like all AI products, tends to work better when it has only the context that's relevant for its current task. Providing instructions in Guidelines.md helps Figma Make select the other detailed guidelines files most appropriate for its task.

Example

guidelines/Guidelines.md
This project has access to a custom Design System called FPL that's installed via an npm package. Files in the guidelines directory show how to use FPL.

Always read:
- All files with a name that starts overview-
- All files in the design-tokens folder

Read the files in the guidelines/components directory when you want to use the component with that name. For example, if you want to use Toast, read guidelines/components/toast.md. Additional context can be found by reading the code for the corresponding component in /node_modules/.

## Component Usage Guidelines - READ THIS FIRST

IMPORTANT: Always prefer to use components from FPL if they exist. For example, prefer to use a Button component from FPL, rather than regular button components.

IMPORTANT: Follow these steps IN ORDER before writing any code:

Step 1: Read Overview Files (REQUIRED)
Read ALL files with a name that starts with "overview-" in the guidelines directory:
overview-setup.md
overview-components.md
overview-icons.md
(And any other overview-*.md files)

Step 2: Read Design Tokens (REQUIRED)
Read ALL files in the design-tokens/ folder. Do NOT skip this step.

Step 3: Plan what components you need to use (REQUIRED)

Step 4: Read Component Guidelines BEFORE Using Components (REQUIRED)
BEFORE using ANY component, you MUST read its guidelines file first:
Using Button? → Read guidelines/components/button.md FIRST
Using Toast? → Read guidelines/components/toast.md FIRST
Using Input? → Read guidelines/components/input.md FIRST

Step 5: Plan what icons you need to use (REQUIRED)
Before using ANY icon, you must check to see if that icon exists in the FPL package. If it doesn't, pick a different icon and verify the new icon.

DO NOT write code using a component until you have read its specific guidelines.

Overview-*.md: overview guidelines

Overview files are where you can introduce Figma Make to specific aspects of your design system. Common overview files include:

  • overview-components.md to explain which components are available and any common usage patterns that apply to all components
  • overview-icons.md to explain the icon system available in your design system

Every design system is different. To help Figma Make be as successful as possible with your design system, use these files to educate Figma Make the same way you'd teach an engineer who's new to your design system.

tip

If your design system is split into multiple packages, use overview files to explain what each package contains and how the packages interact.

Example

guidelines/overview-components.md
## Components

Always prefer components from the FPL package (imported from @fpl/components) if they are available. Each component has a guidelines file that contains helpful examples and additional context for you to use. You must follow all relevant instructions.

Here are the guidelines files and additional guidelines for the FPL components:

| Component | Overview | Guidelines file |
|----------|----------|----------|
| Badges | Status alerts or labels | [badge.md](components/badge.md) |
| Banners | Message bar with important information/announcements | [banner.md](/banner.md) |
| Buttons | Various clickable button components | [button.md](/button.md) |
...
| Tab | Organizes multiple panels with panel selector | [tab.md](/tab.md) |
| TextArea | Simple text input component, used for longer form, multiline input | [textarea.md](/textarea.md) |
| Toast | Brief alert or notification component | [toast.md](/toast.md) |

IMPORTANT: do not specify a className property on any FPL components, as this will break the component. You should avoid overriding styling. Where strictly necessary (e.g. a button background color), use a style object property.

## General Component Usage and Best Practices

### Common Props

Most FPL components accept these common props:
- `htmlAttributes`: Object for passing native HTML attributes like `data-testid`, `data-tooltip`, `aria-*`, `data-*`
- `recordingKey`: String for interaction testing
- `disabled`: Boolean to disable the component
- `className`: String for additional CSS classes (use sparingly)

### Controlled vs Uncontrolled

- **Controlled**: Component receives `value` and `onChange` props, parent manages state
- **Uncontrolled**: Component manages own state, use `defaultValue` for initial value
- Prefer controlled for most cases in modern React

### Sizing

- Most components support `size` prop: `"md"` (default), `"lg"`
- Buttons: Button (24px), ButtonLarge (32px), ButtonWide (full width)
- Inputs: `size="md"` (24px), `size="lg"` (32px)

### Select vs Input vs RadioInput

- Use `Select` for 4-20 predefined options
- Use `Input` for freeform values
- Use `RadioInput` for 2-4 mutually exclusive options
- Consider combobox for >20 options or dynamic data

### Popover vs Callout vs ToggleTip

- **Popover**: Steals focus, for important info requiring attention
- **Callout**: No focus steal, for supplementary info
- **ToggleTip**: Toggle to show/hide, for contextual help
```

````md title="guidelines/overview-icons.md"
### Icon Library

FPL provides 1,093 Icon24* (24px) icons and 309 Icon16* (16px) icons. All icons are React components imported from `@fpl/icons`.

IMPORTANT: Always look in the node_modules directory to check which icons exist. You must confirm an icon exists before using it.
**Icon Sizes**:

- `Icon24*`: 24px icons for buttons, menus, and most UI elements
- `Icon16*`: 16px icons for badges, small indicators, and compact UI

**Usage Pattern**:

```typescript
import {
Icon24Plus,
Icon24Settings,
Icon24Close,
Icon24AiAssistant
Icon16Warning
} from '@fpl/icons'

// In components
<IconButton aria-label="Add item">
<Icon24Plus />
</IconButton>

<Badge variant="warningFilled" iconPrefix={<Icon16Warning />}>
Warning
</Badge>
```

- Many components have iconPrefix props which should be used for icons, rather than adding them as children (which will look broken). Check the component's props before using an icon.
- Never modify the strokeWidth of an icon as this looks bad

**Finding Icons**:

- Total available: 1,093 Icon24 icons, 309 Icon16 icons
- Icon names are kebab-case in files but PascalCase when imported. Example: `icon-24-arrow-up.tsx``Icon24ArrowUp`
- Check the icons directory for complete list

design-tokens/: design token guidelines

To create polished outputs, Figma Make needs to know how to use the tokens that specify your colors, typography, spacing, radii, etc. You can teach Figma Make about your tokens by creating guidelines in a design-tokens/ folder. The files you create depend on the types of tokens that your design system provides. We commonly see tokens for colors, typography, and spacing, but you can add guidelines for any token type used by your design system.

In the file for each type of tokens, you should cover:

  1. An overall design philosophy of how these tokens are used.
  2. Descriptions of overarching groups of tokens, including their naming and usage patterns.
  3. Lists of specific tokens along with examples and descriptions of their proper usage.
  4. Higher level examples of how different tokens are used together.

Example

guidelines/design-tokens/colors.md
# Color design tokens

## Naming pattern

FPL uses semantic color tokens following this pattern: `--color-{category}-{role}-{prominence}-{interaction}`
'category' is required; the remaining parts are optional. For instance, --color-bg-brand-hover has category, role, and interaction, but not prominence.

Use borders or background colors to separate sections.

### Quick Decision Tree to find a token

**Need a background color?**
→ Start with `--color-bg-`
→ Add role if semantic meaning needed
→ Use `-hover` or `-pressed` for interactions

**Need text on that background?**
→ If solid semantic color → use `--color-text-on{role}`
→ If tertiary/light tint → use `--color-text-{role}`
→ If default/neutral → use `--color-text`

**Need an icon color?**
→ Usually matches the text color
→ Same "on-" rules apply

**Need a border?**
→ Start with `--color-border-`
→ Add role/state as needed
→ Use `-strong` for prominent outlines

## Categories

* **bg**: Anytime you need a background or background-color
* **text**: Anytime you need a color property for text
* **icon**: For fill, stroke, or icon color CSS custom properties
* **border**: For border, outline, border-color properties
* **gauge**: Specifically for progress bars, loading indicators, status meters

## Roles

### Semantic/Status Roles

These communicate specific meanings in the UI:
- **`brand`** - Primary accent color (blue in Figma, purple in FigJam)
- Use for: Primary buttons, links, brand-colored elements
- Example: `--color-bg-brand`, `--color-text-brand`
- **`danger`** - Errors, destructive actions (red)
- Use for: Error messages, delete buttons, warnings requiring immediate attention
- Example: `--color-text-danger`, `--color-bg-danger`
...
- **`selected`** - Selection states (light blue/purple)
- Use for: Selected items, active states, focus indicators
- Example: `--color-bg-selected`, `--color-border-selected`
- **`info`** - Informational (blue)
- Use for: Informational banners, neutral alerts
- Example: `--color-bg-info`

### "On-" Roles

Content for text/icons that sit ON colored surfaces:
- **`onbrand`** - Content on brand-colored backgrounds (white)
- **`ondanger`** - Content on danger-colored backgrounds (white)
...
- **`onsuccess`** - Content on success-colored backgrounds (white)
- **`onwarning`** - Content on warning-colored backgrounds (dark)

```css
/* ✅ CORRECT - Solid colored backgrounds */
.primaryButton {
background: var(--color-bg-brand); /* Blue background */
color: var(--color-text-onbrand); /* White text */
--color-icon: var(--color-icon-onbrand);
}

.dangerButton {
background: var(--color-bg-danger); /* Red background */
color: var(--color-text-ondanger); /* White text */
}

/* ❌ WRONG - Same-role tokens clash */
.dangerButton {
background: var(--color-bg-danger); /* Red */
color: var(--color-text-danger); /* Also red - invisible! */
}
```

**Rule:** If the background has a semantic color (brand, danger, success, warning), the content needs the "on-" version.

EXCEPTION: Do not use ON roles for light-tinted (usually tertiary) background colors:

```css
/* ✅ CORRECT - Tertiary (light tint) backgrounds */
.errorBanner {
background: var(--color-bg-danger-tertiary); /* Light red tint */
color: var(--color-text-danger); /* Dark red text */
}

.warningBanner {
background: var(--color-bg-warning-tertiary); /* Light yellow */
color: var(--color-text-warning); /* Dark text */
}

/* ❌ WRONG */
.errorBanner {
background: var(--color-bg-danger-tertiary); /* Light red */
color: var(--color-text-ondanger); /* White - invisible! */
}
```

**Rule:** Tertiary backgrounds are light tints, so they need regular-colored text for contrast.

### Product/Context-Specific Roles

- **`design`** - Design mode/files (blue)
- Use for: Design file indicators, design-specific features
- Example: `--color-bg-design`, `--color-icon-design`
- **`handoff`** - Dev mode/handoff features (green)
- Use for: Developer handoff features, dev mode indicators
- Example: `--color-bg-handoff`, `--color-text-handoff`
- **`measure`** - Measurement tools (red)
- Use for: Measurement indicators, spacing tools
- Example: `--color-bg-measure`, `--color-icon-measure`
- **`assistive`** - Assistive features (pink)
- Use for: Accessibility features, assistive tools
- Example: `--color-bg-assistive`, `--color-text-assistive`

### UI Context Roles

- **`menu`** - Menu items (dark grey)
- Use for: Dropdown menus, context menus
- Example: `--color-bg-menu`, `--color-text-menu`
- **`toolbar`** - Toolbar elements (dark grey)
- Use for: Top toolbar, floating toolbars
- Example: `--color-bg-toolbar`, `--color-icon-toolbar`
- **`tooltip`** - Tooltips (dark grey)
- Use for: Tooltip backgrounds and content
- Example: `--color-bg-tooltip`, `--color-text-tooltip`

### State/Appearance Roles

- **`disabled`** - Disabled/inactive states (grey)
- Use for: Disabled buttons, inputs, inactive elements
- Example: `--color-bg-disabled`, `--color-text-disabled`
- **`inverse`** - Inverse colors (dark on light, light on dark)
- Use for: Elements that need to contrast with the background
- Example: `--color-bg-inverse`, `--color-text-oninverse`
- **`elevated`** - Elevated surfaces (slightly brighter)
- Use for: Raised cards, popovers, elevated panels
- Example: `--color-bg-elevated`, `--color-bg-elevated-hover`
- **`transparent`** - Transparent/subtle backgrounds
- Use for: Ghost buttons, subtle hover states
- Example: `--color-bg-transparent`, `--color-bgtransparent`

## Prominence

- **`secondary`** - Secondary emphasis (lighter/less prominent)
- **`tertiary`** - Tertiary emphasis (lightest/least prominent)
- **`strong`** - Strong emphasis (darker/more prominent)

## Interaction states

- **`hover`** - Hover state
- **`pressed`** - Active/pressed state

## Background colors

### Creating hierarchy

**color-bg**
Our default background color

**color-bg-secondary**
Our secondary background color for most containers.

**color-bg-tertiary**
Our tertiary background color for containers that need to sit within a secondary background.

### Common interaction states

**color-bg-hover**
A light grey hover fill color behind icons, and selectable elements.

**color-bg-selected**
A light blue selected fill color for selected elements.

**color-bg-disabled**
A light grey background fill color for elements that are not interactive (for example, a disabled button). Note, in these cases we tweak any text or icons to use color-text-ondisabled, or color-icon-ondisabled.

### Common Hues

Most often, our common hues will be used with the (default) background color, a -hover state, and a -secondary background color that can be used for containers that sit on top.

Note, when using text or icons on top of a tinted bg, we should typically use the -on version of a token (ex: color-text-ondanger)

**color-bg-brand**
Blue or purple fill colors for backgrounds like a blue primary button.

**color-bg-danger**
Red fill color behind destructive buttons, and error banners.

**color-bg-warning**
Yellow fill color for warning banners

**color-bg-success**
Green fill color for confirmation banners and buttons.

**color-bg-assistive**
Pink fill color for assistive UI

### Tertiary backgrounds

We also have -tertiary versions of these background colors, which are intended to be the "lightest" version of a hue. These are designed to work with our default color-text and color-icon colors.

### Special UI Elements

**color-bg-toolbar**
The dark fill color of our editor toolbar

**color-bg-toolbar-hover**
The hover state for elements in the toolbar

**color-bg-toolbar-selected**
The blue selection state for elements in the toolbar

**color-bg-menu**
The dark fill color of our menus (which are darker than our toolbar)

**color-bg-tooltip**
The dark fill color of our tooltips (which are darker than our toolbar)

guidelines/design-tokens/typography.md
## Typography Tokens

FPL uses typography tokens organized around t-shirt sizes (large, medium, small) to create multiple levels of hierarchy. The system includes body text and headings with optional "strong" variants for emphasis.

Always use Medium Body size for body text. Only use small very sparingly, as it is hard to read. Make sure to use varying sizes, corresponding to the level of heirarchy. For example, heading text should be styled larger than body text.

### Design Philosophy

- T-shirt sizing (large, medium, small) provides intuitive hierarchy
- Strong variants available for body text to create emphasis without changing size
- All headings use strong weight by default
- Font sizes and line heights are optimized for UI density and readability
- Typography tokens include font family, size, weight, line height, and letter spacing as a complete style package

### Font Families

**font.family.display**
- Value: Whyte (with system fallbacks)
- Usage: Display text for expressive moments and important announcements

**font.family.default**
- Value: Inter (with system fallbacks)
- Usage: All standard UI text including headings and body text

**font.family.mono**
- Value: Roboto Mono (with fallbacks)
- Usage: Code and monospace content

### Font Weights

**font.weight.default**
- Value: 450 (400 for Korean)
- Usage: Standard body text weight

**font.weight.strong**
- Value: 550 (500 for Korean)
- Usage: Emphasized text and all headings

Note: Weights automatically adapt for Korean text to ensure proper rendering.

### Display Text

Always use Medium Body size for body text. Only use small very sparingly, as it is hard to read.

#### Display

To create continuity with our logged out marketing views, we sparing use Whyte for onboarding and other heavily branded moments.

Large display size for expressive moments and important announcements

.example {
font-family: var(--text-display-font-family);
font-size: var(--text-display-font-size);
font-weight: var(--text-display-font-weight);
letter-spacing: var(--text-display-letter-spacing);
line-height: var(--text-display-line-height);
}

### Heading Tokens

#### Headings

##### Large

- Usage: Primary page title within large views, largest heading size

.example {
font-family: var(--text-heading-large-font-family);
font-size: var(--text-heading-large-font-size);
font-weight: var(--text-heading-large-font-weight);
letter-spacing: var(--text-heading-large-letter-spacing);
line-height: var(--text-heading-large-line-height);
}
...

### Body Text Tokens

#### Body

##### Large

- Usage: Large display size usually saved for expressive moments, important announcements, and multiline text. Has a "strong" variant for additional emphasis.

.example {
font-family: var(--text-body-large-font-family);
font-size: var(--text-body-large-font-size);
font-weight: var(--text-body-large-font-weight);
letter-spacing: var(--text-body-large-letter-spacing);
line-height: var(--text-body-large-line-height);
}

.example {
font-family: var(--text-body-large-strong-font-family);
font-size: var(--text-body-large-strong-font-size);
font-weight: var(--text-body-large-strong-font-weight);
letter-spacing: var(--text-body-large-strong-letter-spacing);
line-height: var(--text-body-large-strong-line-height);
}
...

### Token Structure

Typography tokens are composite values that include:
- Font family reference
- Font size
- Font weight
- Line height
- Letter spacing

Use the complete token rather than individual properties to ensure consistency.

### Implementation

Tokens are defined in `fpl/tokens-raw/typography.json` and compiled to CSS. Apply full typography tokens using CSS variables or utility classes. Example: `font-size: var(--text-body-small-font-size)`.

### Selection Guidelines

**For headings:**
- Use heading.large for page titles in large views
- Use heading.medium for section headers
- Use heading.small for subsection headers

**For body text:**
- Use body.medium as the default for most UI elements (inputs, buttons, labels)
- Use body.large for multiline content and emphasized text blocks
- Use body.small for compact UI like badges, avatars, and metadata
- Add -strong variants for emphasis without changing size

components/: component guidelines

To help Make full use of components from your design system, especially more complex components that require a particular style of usage or complex configuration, you can provided detailed dcoumentation.

In the file for each component, you should cover:

  1. When to use the component, including the other components it's commonly used with or within
  2. The semantic purpose of the component
  3. Examples of correct & incorrect usage patterns
  4. The API of the component, including its properties

Example

guidelines/components/tabs.md
### Tabs

**Purpose**: Organize content into multiple panels accessed via tabs.

**Structure**: Use `Tabs.useTabs()` or `Tabs.useManagedTabs()` hook, then render `Tabs.TabStrip` with `Tabs.Tab` children and `Tabs.TabPanel` components. Prefer `Tabs.useTabs()`, as it is simpler.

**Usage Notes**:
- Add a container with padding around the TabStrip component. It does not have its own padding and does not usually look good without padding.
- If a TabStrip has a border above or below, you MUST add vertical padding around the TabStrip.
- Do not add icons inside Tabs.

**Tabs.useTabs Hook**:
- Args: Object where keys are tab IDs and values are `true`
- Returns: `[tabProps, manager]`
- Each tabProps[key] has props to spread onto corresponding Tab and TabPanel

**Tabs.useManagedTabs Hook**:
- Args: Three args here: tabIds (object where keys are tab IDs and values are `true`), activeTab (string represent the ID of the active tab), and setActiveTab (function that will be called to set the active tab)
- Returns: `[tabProps, manager, { selectedTab, setSelectedTab }]`

**Tabs.TabStrip Props**:
- `manager`: Manager from hook
- `children`: `<Tabs.Tab>` components

**Tabs.Tab Props**:
- Spread props from `tabProps.keyName`
- `children`: ReactNode (tab label)
- `disabled`: Boolean

**Tabs.TabPanel Props**:
- Spread props from `tabProps.keyName`
- `children`: ReactNode (panel content)

**Example**:
```typescript
function TabsExample() {
const [tabProps, manager] = Tabs.useTabs({
design: true,
prototype: true,
inspect: true,
})

return (
<>
<Tabs.TabStrip manager={manager}>
<Tabs.Tab {...tabProps.design}>Design</Tabs.Tab>
<Tabs.Tab {...tabProps.prototype}>Prototype</Tabs.Tab>
<Tabs.Tab {...tabProps.inspect}>Inspect</Tabs.Tab>
</Tabs.TabStrip>

<Tabs.TabPanel {...tabProps.design}>
Design content
</Tabs.TabPanel>
<Tabs.TabPanel {...tabProps.prototype}>
Prototype content
</Tabs.TabPanel>
<Tabs.TabPanel {...tabProps.inspect}>
Inspect content
</Tabs.TabPanel>
</>
)
}
```