Generates Figma Code Connect mappings for React or Angular repos, validates them with pre-checks and the Figma CLI, and can publish via figma connect...
Create Code Connect files, write figma.config.json, validate mappings, and optionally publish
rg, jq, and ast-grep over manual inspectionjq instead of ad-hoc parsingcurl -s -o /dev/null -w "%{http_code}\n" -H "X-Figma-Token: $FIGMA_ACCESS_TOKEN" https://api.figma.com/v1/files/<fileKey>scripts/check_figma_cli.shrg -l -g '.env*' -g 'superconnect.toml' "FIGMA_ACCESS_TOKEN|figma_access_token"echo ${#FIGMA_ACCESS_TOKEN}node scripts/figma-scan.js <figmaFileUrl> \
--token $FIGMA_ACCESS_TOKEN \
--output codeConnect/.figma-evidence \
--index codeConnect/.figma-evidence/figma-components-index.json
Each evidence file contains:
{
"schemaVersion": "figma-component@1",
"componentSetId": "6:4335",
"componentName": "Button",
"variantProperties": { "Size": ["Compact", "Base", "Wide"] },
"variantValueEnums": {
"Size": { "normalizedKey": "size", "enums": ["compact", "base", "wide"] }
},
"componentProperties": [
{ "name": "Disabled", "type": "BOOLEAN" },
{ "name": "Label", "type": "STRING" }
],
"textLayers": [{ "name": "Label", "type": "TEXT" }],
"slotLayers": [{ "name": "Icon", "type": "FRAME" }]
}
Before proceeding to generation, verify evidence is not empty:
for f in codeConnect/.figma-evidence/*.json; do
props=$(jq '.variantProperties | length' "$f")
comps=$(jq '.componentProperties | length' "$f")
if [ "$props" -eq 0 ] && [ "$comps" -eq 0 ]; then
echo "WARNING: Empty evidence for $f"
fi
done
If evidence is empty, the script may need --layer-depth increased or the Figma component genuinely has no configurable properties.
rg "= input[<\(]" projects/zap/src/lib/components/button/button.component.ts
rg "interface.*Props|type.*Props|function.*\(\{" src/components/Button.tsx
Create figmaToCodeMap in mapping.json to link Figma property names to code input names:
{
"figmaToCodeMap": {
"Size": "size",
"Disabled": "disabled",
"Label": "text"
}
}
Use these heuristics for matching:
Use Angular property binding syntax in examples:
// ✅ CORRECT - Angular property binding
html`<zap-button [disabled]="props.disabled" [size]="props.size">`
// ❌ WRONG - HTML attribute syntax
html`<zap-button disabled=${props.disabled} size="${props.size}">`
For content projection with slots, use figma.children:
props: {
icon: figma.children('Icon'),
},
example: ({ icon }) => html`<zap-button>${icon}</zap-button>`
figma.enum('PropName', {...}) for variantPropertiesfigma.boolean('PropName') for BOOLEAN componentPropertiesfigma.string('PropName') for STRING componentPropertiesfigma.textContent('LayerName') for textLayersfigma.children('LayerName') for slotLayersfigma.instance('PropName') for INSTANCE_SWAP componentPropertiesEvery figma.connect() call MUST include the node-id query parameter:
// ✅ CORRECT - includes node-id from componentSetId
figma.connect('https://www.figma.com/design/FILE_KEY/Name?node-id=6-4335', {...})
// ❌ WRONG - missing node-id
figma.connect('https://www.figma.com/design/FILE_KEY/Name', {...})
Use the componentSetId from evidence files, converting colon to hyphen (6:4335 → 6-4335).
Do not guess import paths. Derive them from the actual package:
# Find the package name
jq -r '.name' projects/zap/package.json
# Find exported components
rg "export \* from|export \{" projects/zap/src/public-api.ts
Write files to codeConnect/
If props cannot be determined, either prompt for manual input or skip the component:
// ❌ NEVER generate this - provides no value
figma.connect('...', {
props: {},
example: () => html`<zap-button></zap-button>`
})
For figma-scan.js, ensure dependencies are available:
npm install commander chalk json-stringify-pretty-compact