- Code Connect
- Overview
- Create Code Connect template files (
- .figma.ts
- ) that map Figma components to code snippets. Given a Figma URL, follow the steps below to create a template.
- Note:
- This project may also contain parser-based
- .figma.tsx
- files (using
- figma.connect()
- , published via CLI). This skill covers
- templates files only
- —
- .figma.ts
- files that use the MCP tools to fetch component context from Figma.
- Prerequisites
- Figma MCP server must be connected
- — verify that Figma MCP tools (e.g.,
- get_code_connect_suggestions
- ) are available before proceeding. If not, guide the user to enable the Figma MCP server and restart their MCP client.
- Components must be published
- — Code Connect only works with components published to a Figma team library. If a component is not published, inform the user and stop.
- Organization or Enterprise plan required
- — Code Connect is not available on Free or Professional plans.
- URL must include
- node-id
- — the Figma URL must contain the
- node-id
- query parameter.
- TypeScript types
- — for editor autocomplete and type checking in
- .figma.ts
- files
- @figma/code-connect/figma-types
- must be added to
- types
- in
- tsconfig.json
- :
- {
- "compilerOptions"
- :
- {
- "types"
- :
- [
- "@figma/code-connect/figma-types"
- ]
- }
- }
- Step 1: Parse the Figma URL
- Extract
- fileKey
- and
- nodeId
- from the URL:
- URL Format
- fileKey
- nodeId
- figma.com/design/:fileKey/:name?node-id=X-Y
- :fileKey
- X-Y
- →
- X:Y
- figma.com/file/:fileKey/:name?node-id=X-Y
- :fileKey
- X-Y
- →
- X:Y
- figma.com/design/:fileKey/branch/:branchKey/:name
- use
- :branchKey
- from
- node-id
- param
- Always convert
- nodeId
- hyphens to colons:
- 1234-5678
- →
- 1234:5678
- .
- Worked example:
- Given:
- https://www.figma.com/design/QiEF6w564ggoW8ftcLvdcu/MyDesignSystem?node-id=4185-3778
- fileKey
- =
- QiEF6w564ggoW8ftcLvdcu
- nodeId
- =
- 4185-3778
- →
- 4185:3778
- Step 2: Discover Unmapped Components
- The user may provide a URL pointing to a frame, instance, or variant — not necessarily a component set or standalone component. Call the MCP tool
- get_code_connect_suggestions
- with:
- fileKey
- — from Step 1
- nodeId
- — from Step 1 (colons format)
- excludeMappingPrompt
- —
- true
- (returns a lightweight list of unmapped components)
- This tool identifies published components in the selection that don't yet have Code Connect mappings.
- Handle the response:
- "No published components found in this selection"
- — the node contains no published components. Inform the user they need to publish the component to a team library in Figma first, then stop.
- "All component instances in this selection are already connected to code via Code Connect"
- — everything is already mapped. Inform the user and stop.
- Normal response with component list
- — extract the
- mainComponentNodeId
- for each returned component. Use these resolved node IDs (not the original from the URL) for all subsequent steps. If multiple components are returned (e.g. the user selected a frame containing several different component instances), repeat Steps 3–6 for each one.
- Step 3: Fetch Component Properties
- Call the MCP tool
- get_context_for_code_connect
- with:
- fileKey
- — from Step 1
- nodeId
- — the resolved
- mainComponentNodeId
- from Step 2
- clientFrameworks
- — determine from
- figma.config.json
- parser
- field (e.g.
- "react"
- →
- ["react"]
- )
- clientLanguages
- — infer from project file extensions (e.g. TypeScript project →
- ["typescript"]
- , JavaScript →
- ["javascript"]
- )
- For multiple components, call the tool once per node ID.
- The response contains the Figma component's
- property definitions
- — note each property's name and type:
- TEXT
- — text content (labels, titles, placeholders)
- BOOLEAN
- — toggles (show/hide icon, disabled state)
- VARIANT
- — enum options (size, variant, state)
- INSTANCE_SWAP
- — swappable component slots (icon, avatar)
- Save this property list — you will use it in Step 5 to write the template.
- Step 4: Identify the Code Component
- If the user did not specify which code component to connect:
- Check
- figma.config.json
- for
- paths
- and
- importPaths
- to find where components live
- Search the codebase for a component matching the Figma component name. Check common directories (
- src/components/
- ,
- components/
- ,
- lib/ui/
- ,
- app/components/
- ) if
- figma.config.json
- doesn't specify paths
- Read candidate files and compare their props interface against the Figma properties from Step 3 — look for matching variant types, size options, boolean flags, and slot props
- If multiple candidates match, pick the one with the closest prop-interface match and explain your reasoning to the user
- If no match is found, show the 2 closest candidates and ask the user to confirm or provide the correct path
- Confirm with the user
- before proceeding to Step 5. Present the match: which code component you found, where it lives, and why it matches (prop correspondence, naming, purpose).
- Read
- figma.config.json
- for import path aliases — the
- importPaths
- section maps glob patterns to import specifiers, and the
- paths
- section maps those specifiers to directories.
- Read the code component's source to understand its props interface — this informs how to map Figma properties to code props in Step 5.
- Step 5: Create the Template File (.figma.ts)
- File location
- Place the file alongside existing Code Connect templates (
- .figma.tsx
- or
- .figma.ts
- files). Check
- figma.config.json
- include
- patterns for the correct directory. Name it
- ComponentName.figma.ts
- .
- Template structure
- Every template file follows this structure:
- // url=https://www.figma.com/file/{fileKey}/{fileName}?node-id={nodeId}
- // source={path to code component from Step 4}
- // component={code component name from Step 4}
- import
- figma
- from
- 'figma'
- const
- instance
- =
- figma
- .
- selectedInstance
- // Extract properties from the Figma component (see property mapping below)
- // ...
- export
- default
- {
- example
- :
- figma
- .
- code
- `
- `
- ,
- // Required: code snippet
- imports
- :
- [
- 'import { Component } from "..."'
- ]
- ,
- // Optional: import statements
- id
- :
- 'component-name'
- ,
- // Required: unique identifier
- metadata
- :
- {
- // Optional
- nestable
- :
- true
- ,
- // true = inline in parent, false = show as pill
- props
- :
- {
- }
- // data accessible to parent templates
- }
- }
- Property mapping
- Use the property list from Step 3 to extract values. For each Figma property type, use the corresponding method:
- Figma Property Type
- Template Method
- When to Use
- TEXT
- instance.getString('Name')
- Labels, titles, placeholder text
- BOOLEAN
- instance.getBoolean('Name', { true: ..., false: ... })
- Toggle visibility, conditional props
- VARIANT
- instance.getEnum('Name', { 'FigmaVal': 'codeVal' })
- Size, variant, state enums
- INSTANCE_SWAP
- instance.getInstanceSwap('Name')
- Icon slots, swappable children
- (child layer)
- instance.findInstance('LayerName')
- Named child instances without a property
- (text layer)
- instance.findText('LayerName')
- →
- .textContent
- Text content from named layers
- TEXT
- — get the string value directly:
- const
- label
- =
- instance
- .
- getString
- (
- 'Label'
- )
- VARIANT
- — map Figma enum values to code values:
- const
- variant
- =
- instance
- .
- getEnum
- (
- 'Variant'
- ,
- {
- 'Primary'
- :
- 'primary'
- ,
- 'Secondary'
- :
- 'secondary'
- ,
- }
- )
- const
- size
- =
- instance
- .
- getEnum
- (
- 'Size'
- ,
- {
- 'Small'
- :
- 'sm'
- ,
- 'Medium'
- :
- 'md'
- ,
- 'Large'
- :
- 'lg'
- ,
- }
- )
- BOOLEAN
- — simple boolean or mapped to values:
- // Simple boolean
- const
- disabled
- =
- instance
- .
- getBoolean
- (
- 'Disabled'
- )
- // Mapped to code values
- const
- hasIcon
- =
- instance
- .
- getBoolean
- (
- 'Has Icon'
- ,
- {
- true
- :
- figma
- .
- code
- `
- `
- ,
- false
- :
- undefined
- ,
- }
- )
- INSTANCE_SWAP
- — access swappable component instances:
- const
- icon
- =
- instance
- .
- getInstanceSwap
- (
- 'Icon'
- )
- let
- iconCode
- if
- (
- icon
- &&
- icon
- .
- hasCodeConnect
- (
- )
- )
- {
- iconCode
- =
- icon
- .
- executeTemplate
- (
- )
- .
- example
- }
- Interpolation in tagged templates
- When interpolating values in tagged templates, use the correct wrapping:
- String values
- (
- getString
- ,
- getEnum
- ,
- textContent
- ): wrap in quotes →
- variant="${variant}"
- Instance/section values
- (
- executeTemplate().example
- ): wrap in braces →
- icon={${iconCode}}
- Boolean bare props
- use conditional →
${disabled ? 'disabled' : ''}
Finding descendant layers
When you need to access children that aren't exposed as component properties:
Method
Use when
instance.getInstanceSwap('PropName')
A component property exists for this slot
instance.findInstance('LayerName')
You know the child layer name (no component property)
instance.findText('LayerName')
→
.textContent
You need text content from a named text layer
instance.findConnectedInstance('id')
You know the child's Code Connect
id
instance.findConnectedInstances(fn)
You need multiple connected children matching a filter
instance.findLayers(fn)
You need any layers (text + instances) matching a filter
Nested component example
For multi-level nested components or metadata prop passing between templates, see
advanced-patterns.md
.
const
icon
=
instance
.
getInstanceSwap
(
'Icon'
)
let
iconSnippet
if
(
icon
&&
icon
.
hasCodeConnect
(
)
)
{
iconSnippet
=
icon
.
executeTemplate
(
)
.
example
}
export
default
{
example
:
figma
.
code
<Button ${ iconSnippet ? figma . codeicon={ ${ iconSnippet } } ` : '' }${ label }
, // ... } Conditional props const variant = instance . getEnum ( 'Variant' , { 'Primary' : 'primary' , 'Secondary' : 'secondary' } ) const disabled = instance . getBoolean ( 'Disabled' ) export default { example : figma . code<Button variant=" ${ variant } " ${ disabled ? 'disabled' : '' }${ label }
, // ... } Step 6: Validate Read back the .figma.ts file and review it against the following: Property coverage — every Figma property from Step 3 should be accounted for in the template. Flag any that are missing and ask the user if they were intentionally omitted. Rules and Pitfalls — check for the common mistakes listed below (string concatenation of template results, missing hasCodeConnect() guards, missing type === 'INSTANCE' checks, etc.) Interpolation wrapping — strings ( getString , getEnum , textContent ) wrapped in quotes, instance/section values ( executeTemplate().example ) wrapped in braces, booleans using conditionals If anything looks uncertain, consult api.md for API details and advanced-patterns.md for complex nesting. Inline Quick Reference instance.* Methods Method Signature Returns getString (propName: string) string getBoolean (propName: string, mapping?: { true: any, false: any }) boolean | any getEnum (propName: string, mapping: { [figmaVal]: codeVal }) any getInstanceSwap (propName: string) InstanceHandle | null getPropertyValue (propName: string) string | boolean findInstance (layerName: string, opts?: SelectorOptions) InstanceHandle | ErrorHandle findText (layerName: string, opts?: SelectorOptions) TextHandle | ErrorHandle findConnectedInstance (codeConnectId: string, opts?: SelectorOptions) InstanceHandle | ErrorHandle findConnectedInstances (selector: (node) => boolean, opts?: SelectorOptions) InstanceHandle[] findLayers (selector: (node) => boolean, opts?: SelectorOptions) (InstanceHandle | TextHandle)[] InstanceHandle Methods Method Returns hasCodeConnect() boolean executeTemplate() { example: ResultSection[], metadata: Metadata } codeConnectId() string | null TextHandle Properties Property Type .textContent string .name string SelectorOptions { path ? : string [ ] , traverseInstances ? : boolean } Export Structure export default { example : figma . code..., // Required: ResultSection[] id : 'component-name' , // Required: string imports : [ 'import { X } from "..."' ] , // Optional: string[] metadata : { nestable : true , props : { } } // Optional } Rules and Pitfalls Never string-concatenate template results. executeTemplate().example is a ResultSection[] object, not a string. Using + or .join() produces [object Object] . Always interpolate inside tagged templates: figma.code${snippet1}${snippet2}Always check hasCodeConnect() before executeTemplate() . Calling executeTemplate() on an instance without Code Connect returns an error section. Check type === 'INSTANCE' before calling hasCodeConnect() . findInstance() , findConnectedInstance() , and findText() return an ErrorHandle (truthy, but lacking hasCodeConnect() ) on failure — not null . Add a type check to avoid crashes: if (child && child.type === 'INSTANCE' && child.hasCodeConnect()) { ... } Prefer getInstanceSwap() over findInstance() when a component property exists for the slot. findInstance('Star Icon') breaks when the icon is swapped to a different name; getInstanceSwap('Icon') always works regardless of which instance is in the slot. Property names are case-sensitive and must exactly match what get_context_for_code_connect returns. Handle multiple template arrays correctly. When iterating over children, set each result in a separate variable and interpolate them individually — do not use .map().join() : // Wrong: items . map ( n => n . executeTemplate ( ) . example ) . join ( '\n' ) // Correct — use separate variables: const child1 = items [ 0 ] ?. executeTemplate ( ) . example const child2 = items [ 1 ] ?. executeTemplate ( ) . example export default { example : figma . code${ child1 } ${ child2 }} Complete Worked Example Given URL: https://figma.com/design/abc123/MyFile?node-id=42-100 Step 1: Parse the URL. fileKey = abc123 nodeId = 42-100 → 42:100 Step 2: Call get_code_connect_suggestions with fileKey: "abc123" , nodeId: "42:100" , excludeMappingPrompt: true . Response returns one component with mainComponentNodeId: "42:100" . If the response were empty, stop and inform the user. If multiple components were returned, repeat Steps 3–6 for each. Step 3: Call get_context_for_code_connect with fileKey: "abc123" , nodeId: "42:100" (from Step 2), clientFrameworks: ["react"] , clientLanguages: ["typescript"] . Response includes properties: Label (TEXT) Variant (VARIANT): Primary, Secondary Size (VARIANT): Small, Medium, Large Disabled (BOOLEAN) Has Icon (BOOLEAN) Icon (INSTANCE_SWAP) Step 4: Search codebase → find Button component. Read its source to confirm props: variant , size , disabled , icon , children . Import path: "primitives" . Step 5: Create src/figma/primitives/Button.figma.ts : // url=https://figma.com/design/abc123/MyFile?node-id=42-100 // 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 hasIcon = instance . getBoolean ( 'Has Icon' ) const icon = hasIcon ? instance . getInstanceSwap ( 'Icon' ) : null let iconCode if ( icon && icon . hasCodeConnect ( ) ) { iconCode = icon . executeTemplate ( ) . example } export default { example : figma . code<Button variant=" ${ variant } " size=" ${ size } " ${ disabled ? 'disabled' : '' } ${ iconCode ? figma . codeicon={ ${ iconCode } }: '' }${ label } ` , imports : [ 'import { Button } from "primitives"' ] , id : 'button' , metadata : { nestable : true } } Step 6: Read back file to verify syntax. Additional Reference For advanced patterns (multi-level nested components, findConnectedInstances filtering, metadata prop passing between parent/child templates): api.md — Full Code Connect API reference advanced-patterns.md — Advanced nesting, metadata props, and descendant patterns
figma-code-connect
安装
npx skills add https://github.com/figma/mcp-server-guide --skill figma-code-connect