Livestream: Building landing pages with AI | 4/3

Announcing Visual Copilot - Figma to production in half the time

Builder logo
builder.io
Contact SalesGo to App

Livestream: Building landing pages with AI | 4/3

Announcing Visual Copilot - Figma to production in half the time

Builder logo
builder.io

Blog

Home

Resources

Blog

Forum

Github

Login

Signup

×

Visual CMS

Drag-and-drop visual editor and headless CMS for any tech stack

Theme Studio for Shopify

Build and optimize your Shopify-hosted storefront, no coding required

Resources

Blog

Get StartedLogin

Component mappings in React involve creating .mapper.tsx or .mapper.jsx files that connect Figma components to your React code components. These mappings define how Figma component properties translate to React component props.

A component mapping file links a specific Figma component to a React component in your codebase. To identify the Figma component, you can use either:

  • componentKey: A unique identifier for the Figma component
  • url: The Figma URL that points to the component (more human-readable)

Both methods achieve the same result, but the URL approach is often more convenient for manual creation.

These mapping files are just normal files in your repository that can be created manually. However, for convenience, we also provide a CLI command to generate them more easily with AI assistance.

Once this files exist in your project, we use npx builder.io@latest figma publish to publish them to your Builder Space.

The CLI provides a more convenient approach with AI assistance to help you bootstrap mappings more quickly. Note that either approach, manual or CLI, lead to the same result, creating [componentName].mapper.tsx files in your project.

The CLI-based workflow leverages AI to automatically generate appropriate mappings between your Figma designs and code components. It analyzes the Figma component, your code components, and any additional documentation to figure out the best mapper function.

To complete the mapping process, do the following:

Use the Builder Figma Plugin

Open the Builder Figma Plugin and navigate to the Design System tab. The plugin scans your selection and identifies unmapped components.

Select components in Figma

Select the components you want to map to your code components.

Generate the CLI command

In the Design System tab of the plugin, you'll see a list of unmapped components along with a CLI command. This command includes the Figma IDs for all unmapped components. Copy this command by clicking the copy icon.

# Example command
npx builder.io@latest figma generate --token [TOKEN]

Run the command

Open your terminal in your project directory and paste the command. When you run it, the CLI will:

  • Look up the Figma components based on their IDs
  • Scan your codebase for potential matching components

Select local components

The CLI will display a list of code components found in your project and prompt you to select which ones should be mapped to your Figma components. Use the arrow keys to navigate and press Enter to select a component.

Select a code component to map ❖ PrimaryButton
❯ ★ Button from '@/components/ui/button'
  Card from '@/components/ui/card'
  ⏭️  Skip (Ctrl+C)
  🏗️  Scaffold Mapper (Generate interface only)
  📦 External npm package

The CLI suggests the best matches first (marked with ★), based on name similarity. If your component is in an external package, select that option to choose from installed packages.

Add documentation (Optional)

The CLI will ask if you want to provide a documentation URL for your component. For optimal results, provide a URL to documentation that includes actual code examples showing how to use the component:

Providing a docs URL for Button can drastically improve results: (Ctrl+C to skip)
> https://mui.com/components/buttons/

Adding a documentation URL significantly improves the quality of generated mappings, as the AI can learn from the component’s official API documentation. For best results, provide URLs to pages that contain actual code examples of how to use the React component, showing props, event handlers, and common patterns.

Documentation with practical code samples is much more valuable than pages with only theoretical explanations or API references without examples.

Review AI-generated mappings

The CLI uses AI to suggest appropriate mappings between your Figma and code components. It will show you the suggested mapping code:

import { figmaMapping } from "@builder.io/dev-tools/figma";
import { Button } from "@/components/ui/button";

figmaMapping({
  componentKey: "9ca66d3a1f5b2c4e7d8a0b9f",
  mapper(figma) {
    return (
      <Button
        variant={figma.Variant?.toLowerCase()}
        size={figma.Size?.toLowerCase()}
        disabled={figma.State === "Disabled"}
      >
        {figma.$textContent || figma.Text || "Button"}
      </Button>
    );
  },
});

Refine the mapping

If needed, you can provide natural language feedback to improve the mapping:

How does the mapping look? Reply "good", or provide feedback (Ctrl+C to exit)
> The button should use figma.Label for the text content instead of $textContent

The AI will update the mapping based on your feedback and show you the revised code. You can continue this feedback loop until you’re satisfied with the mapping.

You can give specific instructions like “Map the ‘Color’ property to the ‘color’ prop” or “Use the first child as the icon.”

Save the mapping

Once you're satisfied with the mapping, the CLI will ask where to save it:

Where do you want to save the new mapping? (Ctrl+C to exit)
> src/mappings/Button.mapper.tsx

The default location is usually src/mappings/[ComponentName].mapper.tsx, but you can specify any valid path within your project.

Publish the mapping

After creating one or more mappings, publish them to your Builder Space:

npx builder.io figma publish

This will display:

Searching for mapping files...
Found 3 mapping files

Validating mappings...

You are about to publish 3 mapping files to your Builder.io space.
Do you want to continue? (Y/n)
> Y

Publishing mappings to Builder.io...
✓ Published 3 mapping files successfully

Your mappings are now available in the Builder Figma plugin

If you encounter issues during the mapping process, review the following recommendations.

Component not found

If the CLI can't find your component, it will offer to scaffold a basic mapping:

No matching components found for 'CustomButton'.
Do you want to scaffold a basic mapping? (Y/n)
> Y

Authentication problems

If you encounter authentication issues, you can forcefully re-authenticate with the command:

npx builder.io figma auth --force

Mappings not working in Figma

Verify that the CLI and Figma plugin are using the same Builder.io space, and try republishing with the verbose flag, like so:

npx builder.io figma publish --verbose

TypeScript errors during publishing

If the publish command fails with TypeScript errors or validation issues, you can bypass these checks using the --force flag:

npx builder.io figma publish --force

You’ll see a warning, but the CLI will proceed with publishing:

TypeScript errors in src/mappings/Button.mapper.tsx:
 • Cannot find name 'ButtonProps'
 • Property 'variant' does not exist on type '{}'

Local mappings contain some errors, but --force flag was used, skipping.

This is particularly useful when:

  • You’re dealing with complex TypeScript types the CLI doesn’t understand
  • The errors are in parts of the code that won’t affect the mapping functionality
  • You need to publish quickly and plan to fix the issues later

While --force allows you to publish despite errors, it’s best practice to fix the underlying issues when possible, as they might cause problems when using the Figma plugin.

Instead of relying on AI to generate the mapping, create the mapping file yourself by completing the following steps.

Create a mapper file

Create a file with the naming convention [componentName].mapper.tsx in your project. Many developers use a dedicated mappings directory to organize these files, for example: src/mappings/Button.mapper.tsx.

Import required dependencies:

import { figmaMapping } from "@builder.io/dev-tools/figma";
import YourComponent from "@/path/to/your/component";

Define your mapping function:

This is where you’ll write the logic that transforms Figma properties into React component props. You need to identify your Figma component using the url parameter:

// Using the URL approach (more human-readable)
figmaMapping({
  url: "https://www.figma.com/file/abc123/Design-System?node-id=456:789",
  mapper(figma) {
    return (
      <YourComponent prop1={figma.Property1} prop2={figma.Property2}>
        {figma.$children}
      </YourComponent>
    );
  },
});

The URL approach is often preferred for manual mapping because it’s more human-readable, easier to obtain directly from Figma, and provides a direct link back to the visual component.

Test your mapping

Run your local development server with Devtools enabled to test your mapping.

Publish your mapping

Use the CLI command to publish your manually created mapping:

npx builder.io figma publish
  1. Open your Figma design file
  2. Select the component you want to map
  3. Right-click on the selection
  4. Choose "Copy Link To Selection" from the context menu
  5. Paste the URL into your mapping file

While both componentKey and url methods work for identifying Figma components, the URL approach has several advantages when manually creating mappings:

  1. Ease of Access: You can easily obtain the URL directly from Figma's UI by right-clicking a component and selecting "Copy Link To Selection"
  2. Human Readability: URLs contain readable information about the Figma file name and design context, making them more maintainable
  3. Direct Reference: The URL provides a clickable link back to the exact component in Figma, making it easier to check the design when updating mappings
  4. Contextual Information: The URL contains information about the file structure and location of the component, which aids in documentation

The componentKey approach, while less human-readable, is more concise and is what the CLI uses internally when generating mappings.

The mapping function has access to a rich set of properties and methods through the figma parameter. These properties and methods are included below.

Returns an array of all direct child nodes of the current Figma design.

figmaMapping({
  componentKey: "button-component-key",
  mapper(figma) {
    return <Button>{figma.$children}</Button>;
  },
});

Retrieves the text content from the current Figma design node or its text children.

figmaMapping({
  componentKey: "button-component-key",
  mapper(figma) {
    return <Button>{figma.$children[1].$textContent}</Button>;
  },
});

Maps a specific child node of the current Figma component by its layer name.

figmaMapping({
  componentKey: "dialog-component-key",
  mapper(figma) {
    return <div>{figma.$findOneByName("dialog")}</div>;
  },
});

Finds the first node that meets specified criteria through a callback function.

figmaMapping({
  componentKey: "page-component-key",
  mapper(figma) {
    return <div>{figma.$findOne((node) => node.name === "Heading")}</div>;
  },
});

Traverses all child nodes and applies a function to each one.

figmaMapping({
  componentKey: "content-component-key",
  mapper(figma) {
    return figma.$visit((node) => {
      if (node.name === "Header") {
        return <h1>{node.$textContent}</h1>;
      } else if (node.name === "Content") {
        return node.$textContent;
      }
    });
  },
});
figmaMapping({
  componentKey: "button-component-key",
  mapper(figma) {
    return (
      <Button
        color={figma.Color?.toLowerCase()}
        size={figma.Size?.toLowerCase()}
        type={figma.Variant?.toLowerCase()}
      >
        {figma.$children}
      </Button>
    );
  },
});
figmaMapping({
  componentKey: "hero-component-key",
  mapper(figma) {
    const heading = figma.Heading;
    const supportingText = figma.$findOneByName("Supporting Text").$textContent;
    const navigation = figma.$findOneByName("Navigation");

    return (
      <Hero
        heading={heading}
        supportingText={supportingText}
        navigation={navigation}
      />
    );
  },
});
figmaMapping({
  componentKey: "button-component-key",
  mapper(figma) {
    // Use the text from the 2nd child ($children is zero indexed)
    const text = figma.$children[1].$textContent;

    return <Button>{text}</Button>;
  },
});

Another option is to retrieve children by their layer name:

figmaMapping({
  componentKey: "button-component-key",
  mapper(figma) {
    const text = figma.$findOneByName("Label").$textContent;

    return <Button>{text}</Button>;
  },
});
figmaMapping({
  componentKey: "button-component-key",
  mapper(figma) {
    // Make an array to hold the CSS class names
    const classes = ["button"];

    // If figma.variant is 'primary', add the 'button-primary' class
    if (figma.variant === "primary") {
      classes.push("button-primary");
    }

    // Return a button with className applied
    return <button className={classes.join(" ")}>{figma.Text}</button>;
  },
});

For complex layouts or special case handling, you can create a generic mapper:

figmaMapping({
  genericMapper(figma) {
    if (figma.$name === "Grid row") {
      return <Grid>{figma.$children}</Grid>;
    } else if (figma.$name === "Section") {
      return <section>{figma.$children}</section>;
    }
    return undefined;
  },
});

Here's a more complex example mapping a table component:

figmaMapping({
  componentKey: "29938639a346fd304f89cbbdd9377064ac6426c1",
  mapper(figma) {
    // Extract columns data
    const columns =
      figma.$children?.map((column) => {
        const header = column.$findOneByName("Header")?.$textContent ?? "";
        return { name: header, uid: header.toLowerCase() };
      }) ?? [];

    // Extract rows data
    const firstColumn = figma.$children?.[0];
    const rowsFrame = firstColumn?.$findOneByName("Rows");
    const rowCount = rowsFrame?.$children?.length ?? 0;

    // Create rows data structure
    const rows = Array.from({ length: rowCount }, (_, rowIndex) => {
      const rowData = {};
      figma.$children?.forEach((column) => {
        const rowItem = column.$findOneByName("Rows")?.$children?.[rowIndex];
        const cellContent =
          rowItem?.$findOneByName("Row item")?.$textContent ?? "";
        const columnId =
          column.$findOneByName("Header")?.$textContent?.toLowerCase() ?? "";
        rowData[columnId] = cellContent;
      });
      return { id: rowIndex, ...rowData };
    });

    return (
      <TableView
        aria-label="Table"
        isQuiet={figma.Style === "Quiet"}
        selectionMode={
          figma["Selection Column"] === "True" ? "multiple" : "none"
        }
      >
        <TableHeader columns={columns}>
          {(column) => <Column>{column.name}</Column>}
        </TableHeader>
        <TableBody items={rows}>
          {(item) => <Row>{(columnKey) => <Cell>{item[columnKey]}</Cell>}</Row>}
        </TableBody>
      </TableView>
    );
  },
});

For a complete end-to-end example of Figma component mappings in a real application, check out the Cloudscape Demo Repository. This repository showcases how to implement component mappings in a Next.js project with a real-world design system.

For more information on the available parameters and options for the figmaMapping function, refer to the API Reference.

If you're working with Angular instead of React, check out the Creating Angular Mappings guide.

Was this article helpful?

Product

Visual CMS

Theme Studio for Shopify

Sign up

Login

Featured Integrations

React

Angular

Next.js

Gatsby

Get In Touch

Chat With Us

Twitter

Linkedin

Careers

© 2020 Builder.io, Inc.

Security

Privacy Policy

Terms of Service

Get the latest from Builder.io

By submitting, you agree to our Privacy Policy

  • Platform Overview

  • Integrations

  • What's New

  • Figma to Code Guide

  • Composable Commerce Guide

  • Headless CMS Guide

  • Headless Commerce Guide

  • Composable DXP Guide

  • Design to Code

  • Blog

  • Knowledge Base

  • Community Forum

  • Partners

  • Templates

  • Success Stories

  • Showcase

  • Resource Center

    Glossary

© 2025 Builder.io, Inc.

Security

Privacy Policy

SaaS Terms

Security & Compliance

Cookie Preferences

Gartner Cool Vendor 2024