How to Implement Code Connect and Code to Canvas Features with OpenAI Plugins

Code Connect and Code to Canvas establish a bidirectional bridge between Figma design files and React components by generating declarative .figma.ts templates and programmatically constructing Figma nodes via the use_figma MCP API.

The OpenAI/plugins repository provides a declarative toolchain for automating the design-to-code handoff. Learning how to implement Code Connect and Code to Canvas features enables development teams to maintain live, synchronized connections between Figma design systems and React, Vue, or Web Component libraries without manual translation.

Understanding the Bidirectional Workflow

Code Connect and Code to Canvas represent opposite directions of the same integration pipeline, both leveraging the Figma MCP toolchain (use_figma, get_code_connect_suggestions, get_context_for_code_connect).

What is Code Connect?

Code Connect uses the figma-code-connect skill to generate .figma.ts template files. These templates reside alongside your components and tell Figma's inspector how to render code snippets for a selected design element. The workflow maps published Figma components to their code-side counterparts by parsing property schemas and generating type-safe examples.

What is Code to Canvas?

Code to Canvas employs the figma-use skill to provide low-level use_figma API access. Starting from a JSX/TSX file, this workflow programmatically creates Figma pages, auto-layout frames, component instances, and design tokens. It builds the visual representation when the source of truth lives in the codebase.

Shared Foundation

Both workflows rely on identical property type mappings (TEXT, BOOLEAN, VARIANT, INSTANCE_SWAP, SLOT) and honor the same validation rules defined in plugins/figma/skills/figma-code-connect/SKILL.md and plugins/figma/skills/figma-use/SKILL.md.

Implementing Code Connect: The Six-Step Process

To generate a valid .figma.ts template, follow the implementation pattern documented in the source code.

Parse the Figma URL

Extract the fileKey and nodeId from the Figma URL. The URL must contain a node-id query parameter pointing to the specific component node you intend to map.

Discover Unmapped Components

Call get_code_connect_suggestions with excludeMappingPrompt:true to identify components lacking templates. If the response reports no unmapped components, the mapping is already complete for that selection.

Fetch Property Schemas

Invoke get_context_for_code_connect to retrieve the exact set of Figma property types for the target component. This returns structured data defining which props are TEXT, BOOLEAN, VARIANT, INSTANCE_SWAP, or SLOT.

Locate the Code Component

Read figma.config.json to resolve import aliases, then search the source tree (e.g., src/components/**/*.tsx) for a component whose props interface matches the Figma property list from the previous step.

Generate the Template File

Create a file named <ComponentName>.figma.ts adjacent to your component. The template must include:

  • A header comment with the original Figma URL and source path
  • const instance = figma.selectedInstance
  • Property extraction using typed methods: instance.getString(), instance.getEnum(), instance.getBoolean(), instance.getInstanceSwap(), instance.getSlot()
  • An exported object with example (using figma.code tagged templates), imports, a unique id, and optional metadata

Validate the Output

Read the generated file back and verify that every property from the schema appears in the template. Confirm the generated JSX respects the component's Props interface and contains no hard-coded children. Consult plugins/figma/skills/figma-code-connect/references/api.md for exact method signatures.

Implementing Code to Canvas: Reverse Engineering Designs

When starting from code and building the Figma UI, use the workflow from plugins/figma/skills/figma-use/SKILL.md.

Load Component Metadata

Begin by calling get_context_for_code_connect (the same method used in Code Connect) to load the component's property metadata. This ensures the Figma properties you will set align with the code component's interface.

Initialize the Page Structure

Create or select a Figma page using await figma.createPage(). You must use await figma.setCurrentPageAsync(page) to switch to it, and this must be the only page switch per use_figma call.

Construct Auto-Layout Containers

Prefer figma.createAutoLayout over figma.createFrame to generate correctly nested, responsive containers. Configure itemSpacing, paddingTop, paddingBottom, paddingLeft, and paddingRight in the options object.

Instantiate Components

If the component exists in a team library, pull it using await figma.importComponentByKeyAsync(key). Otherwise, use figma.createComponent followed by figma.createInstance. Append the instance to your container with container.appendChild(instance).

Populate Properties and Variables

Set properties via instance.setProperties(). For design systems using Figma variables, create collections with figma.variables.createLocalVariableCollection(), then bind them to fills, strokes, or text colors.

Return Node IDs

Every use_figma script must return the IDs of created nodes: return { createdNodeIds: [node.id] }. This enables subsequent parallel calls to reference the newly built structure.

Critical Constraints and Validation Rules

Both workflows enforce strict rules listed in the "Pre-Flight Checklist" within plugins/figma/skills/figma-use/SKILL.md:

  • No UI notifications: Never call figma.notify.
  • Await all async operations: Every promise must be awaited.
  • Color range: Use 0-1 float values, not 0-255 integers.
  • Page switching: Only switch pages using await figma.setCurrentPageAsync.
  • Template safety: Never concatenate template strings; always use tagged template interpolation: figma.code`${snippet}`.

Practical Implementation Examples

Minimal Code Connect Template for a Button Component

The following TypeScript template maps a Figma Button to a React implementation, handling text, enums, booleans, and nested icon instances:

// url=https://www.figma.com/design/QiEF6w564ggoW8ftcLvdcu/MyDesignSystem?node-id=4185-3778
// source=src/components/Button.tsx
// component=Button
import figma from 'figma'
const instance = figma.selectedInstance

const label = instance.getString('Label')
const variant = instance.getEnum('Variant', {
  'Primary': 'primary',
  'Secondary': 'secondary',
})
const size = instance.getEnum('Size', {
  'Small': 'sm',
  'Medium': 'md',
  'Large': 'lg',
})
const disabled = instance.getBoolean('Disabled')
const icon = instance.getInstanceSwap('Icon')
let iconCode
if (icon && icon.type === 'INSTANCE') {
  iconCode = icon.executeTemplate().example
}

export default {
  example: figma.code`
    <Button
      variant="${variant}"
      size="${size}"
      ${disabled ? 'disabled' : ''}
      ${iconCode ? figma.code`icon={${iconCode}}` : ''}
    >
      ${label}
    </Button>
  `,
  imports: ['import { Button } from "primitives"'],
  id: 'button',
  metadata: { nestable: true },
}

Source: plugins/figma/skills/figma-code-connect/SKILL.md

Code to Canvas Script Building a Button Instance

This use_figma script creates a new page with an auto-layout container and populates a Button component instance:

const fileKey = 'QiEF6w564ggoW8ftcLvdcu'
const page = await figma.createPage()
await figma.setCurrentPageAsync(page)

const container = figma.createAutoLayout('VERTICAL', {
  name: 'DemoScreen',
  itemSpacing: 12,
  paddingTop: 24,
  paddingBottom: 24,
  paddingLeft: 24,
  paddingRight: 24,
})
page.appendChild(container)

const buttonComp = await figma.importComponentByKeyAsync('abc123def456')
const btnInstance = buttonComp.createInstance()
container.appendChild(btnInstance)

btnInstance.setProperties({
  variant: 'primary',
  size: 'md',
  label: 'Click me',
  disabled: false,
})

return { createdNodeIds: [page.id, container.id, btnInstance.id] }

Source: plugins/figma/skills/figma-use/SKILL.md

Essential Source Files and References

File Path Purpose
plugins/figma/skills/figma-code-connect/SKILL.md Complete guide for Code Connect URL parsing, property discovery, template generation, and validation.
plugins/figma/skills/figma-use/SKILL.md Authoritative use_figma API documentation, page-switch rules, and incremental workflow patterns.
plugins/figma/skills/figma-code-connect/references/api.md Method signatures for instance.getString, instance.getEnum, instance.getBoolean, and other template APIs.
plugins/figma/skills/figma-code-connect/references/code-connect-setup.md Project configuration requirements including MCP server setup and TypeScript types.
plugins/figma/skills/figma-use/references/gotchas.md Common pitfalls applicable to both workflows, including color range errors and async handling.
plugins/figma/skills/figma-use/references/plugin-api-standalone.d.ts Definitive TypeScript typings for the Figma Plugin API.

Summary

  • Code Connect generates .figma.ts templates using the figma-code-connect skill to map Figma components to code snippets.
  • Code to Canvas uses the figma-use skill and use_figma API to programmatically build Figma files from code components.
  • Both workflows require parsing Figma URLs, fetching property schemas via get_context_for_code_connect, and respecting strict validation rules.
  • Templates must use figma.code tagged templates, never string concatenation.
  • All use_figma scripts must await async operations, avoid figma.notify, and return created node IDs.

Frequently Asked Questions

What is the difference between Code Connect and Code to Canvas?

Code Connect starts from a Figma design and generates code-side .figma.ts templates that allow the Figma inspector to display the corresponding React (or other framework) code. Code to Canvas starts from a code component and uses the use_figma API to construct or update the visual representation in Figma, including pages, frames, and component instances.

How do I handle complex component properties like icons or slots?

For nested components (like icons), use instance.getInstanceSwap('PropertyName') in your template, then conditionally render the result. For slots, use instance.getSlot(). In Code to Canvas, set these via instance.setProperties(), passing the appropriate component key or variable ID.

What are the most common implementation errors when using the Figma MCP API?

The most frequent mistakes include forgetting to await async calls like figma.setCurrentPageAsync, using 0-255 integer color values instead of 0-1 floats, calling figma.notify (which is forbidden), and concatenating template strings instead of using figma.code`...` tagged templates. Always consult plugins/figma/skills/figma-use/references/gotchas.md before debugging.

Can I use these features with design systems that aren't built in React?

Yes. While the examples use React/TypeScript syntax, the property type mappings (TEXT, ENUM, BOOLEAN, etc.) are framework-agnostic. You can generate .figma.ts templates for Vue, Svelte, Web Components, or any framework by adjusting the example and imports fields to match your target syntax, as long as the component property schema aligns with the Figma component's interface.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →