Without Code Connect, every Figma button becomes freshly generated flexbox; with it, the Dev Mode MCP tells the agent "this instance is @acme/ui Button, variant=primary, size=md" — and generated screens compose your components instead of regenerating primitives. Mapping the top twenty components changes the character of every design-to-code run.
Tier: Advanced · Workflow area: Design-to-code & design systems · Tools: Figma Code Connect, Dev Mode MCP, any coding agent
This is the multiplier on pb-09. The Dev Mode MCP faithfully describes geometry; Code Connect adds identity — which code component a Figma instance corresponds to and how its Figma properties map to props. The difference in output is categorical: composition of real imports versus a parallel universe of look-alike divs.
Install and authenticate the Code Connect CLI. In the design-system repo:
npm i -D @figma/code-connect
npx figma connect --help
export FIGMA_ACCESS_TOKEN=figd_... # token with code_connect:write scope
Rank components by instance count, then map the top twenty. Don't map alphabetically — map by leverage. Your design-system analytics (or a quick audit of three recent feature files) tells you the ranking; Button, Text, Input, Card, Badge, and layout primitives usually cover 80% of any frame.
Write the first mapping by hand to set the pattern. A Code Connect file colocated with the component:
import figma from '@figma/code-connect';
import { Button } from './Button';
figma.connect(Button, 'https://figma.com/design/ABC123/DS?node-id=1-234', {
props: {
label: figma.string('Label'),
variant: figma.enum('Variant', {
Primary: 'primary',
Secondary: 'secondary',
Destructive: 'destructive',
}),
size: figma.enum('Size', { Small: 'sm', Medium: 'md', Large: 'lg' }),
disabled: figma.boolean('Disabled'),
iconStart: figma.instance('Icon start'),
},
example: ({ label, variant, size, disabled, iconStart }) => (
<Button variant={variant} size={size} disabled={disabled} iconStart={iconStart}>
{label}
</Button>
),
});
The node URL comes from right-clicking the component in Figma → Copy link to selection. The example render is exactly what Dev Mode and the MCP will surface — keep it the canonical usage, not a kitchen sink.
Let AI generate the remaining mappings — from component source plus Figma properties. This is mechanical work the model does well with both sides in context:
For each component listed in mapping-batch.md (Badge, Card, TextField,
Select, Tabs, Tooltip...), generate a .figma.tsx Code Connect file
following the Button.figma.tsx pattern. Figma property names per
component are in figma-props.json (exported from the library). Map
every Figma variant/boolean/text property to the real prop per the
component's TypeScript types — if a Figma property has no code
equivalent (or vice versa), add it to a MISMATCHES.md table instead
of guessing.
That MISMATCHES.md is gold: it is your design-system parity backlog, discovered for free.
Validate and publish. Code Connect ships a parser that catches broken mappings before they go live:
npx figma connect parse
npx figma connect publish
Wire both into design-system CI so a component API change that breaks a mapping fails the build — stale mappings are worse than none, because agents trust them.
Prove the effect with a before/after generation. Re-run a pb-09 task on a frame heavy with mapped instances:
Get the code for my current Figma selection via the Dev Mode MCP and
implement it. Where the payload identifies a Code Connect component,
you MUST import and use that component with the given props — never
re-implement it.
Good output now reads like your feature code: <Button variant="primary" size="md"> with imports from @acme/ui, and generation time drops because the agent composes instead of constructing. Diff against the pre-mapping output and count regenerated primitives — that number should approach zero.
Make mapping part of the component definition-of-done. New component PR → includes .figma.tsx → CI parses and publishes. Add it to the design-system contribution docs and the PR template checklist.
Code Connect mappings assert equivalence, so a wrong mapping silently injects the wrong component into every downstream generation. Review .figma.tsx files with the same rigor as component APIs — especially enum mappings, where Destructive -> 'danger' vs 'destructive' typos produce runtime-invalid props that look plausible in review.
*.figma.tsx with components and publish from design-system CI.figma connect with Swift/Kotlin templates); map your DesignSystemButton composable/view the same way, and mobile agents using the MCP get real component identities.<acme-button variant="primary">); the enum-mapping discipline is identical.figma-component-map.md (Figma component name → import + props table) in your instruction files, and prompt agents to consult it for every instance the MCP payload names; weaker, but it kills most primitive regeneration.figma connect parse green in CIand a component API change demonstrably fails it.Publish the before/after diff from step 6 to your design-system channel. Nothing recruits designers into naming layers properly — and engineers into maintaining mappings — like seeing the same frame become <Button variant="primary"> instead of ninety lines of regenerated flexbox.