Skip to main content

Batch files

Batch files let you connect many Figma components to code using a single shared template. This is the recommended approach when you have a large number of components that follow the same structure, the most common example being icon libraries, where hundreds or thousands of icons share identical code patterns but each maps to a different Figma node.

Without batch files, each component would need its own .figma.ts file. Batch files collapse this into two files: a template (.figma.batch.ts) that describes the code shape, and a JSON file (.figma.batch.json) that lists every component with its Figma URL and any custom data.

File structure​

A batch integration consists of two files:

FilePurpose
*.figma.batch.tsTemplate describing the code snippet
*.figma.batch.jsonList of components with their Figma URLs and custom data

Writing a batch template​

A batch template is structured like a regular template file, with two differences:

  1. There are no metadata comments (// url=, // source=, // component=) at the top. Those values are defined in the JSON file instead.
  2. Per-component data is accessed via figma.batch rather than being hardcoded.
icons.figma.batch.ts
import figma from 'figma'

const instance = figma.selectedInstance

const size = instance.getEnum('Size', {
Small: '16px',
Medium: '24px',
Large: '32px',
})

export default {
example: figma.code`
<${figma.batch.name} size={${size}} />
`,
imports: [`import ${figma.batch.name} from "${figma.batch.importPath}"`],
id: figma.batch.id,
}

figma.batch​

figma.batch gives your template access to data defined in the JSON file for each component. Three fields have special meaning, corresponding to the metadata comments used in regular template files:

FieldRequiredReplaces
urlYes// url=
sourceNo// source=
componentNo// component=

Any additional fields you define in the JSON file, such as name, id, or importPath in the example above, are also available on figma.batch. This lets your template reference per-component values without hardcoding them, for example:

  figma.code`<MyComponent ${figma.batch.myCustomField} />`

The full type of figma.batch is:

figma.batch: {
url: string
source?: string
component?: string
[key: string]: any
}

Writing the JSON file​

The JSON file defines which components belong to a batch and what data each one provides to the template.

Single template (shorthand)​

When all your components share one template, use the shorthand format with a templateFile and a components array:

icons.figma.batch.json
{
"templateFile": "./icons.figma.batch.ts",
"components": [
{
"url": "https://www.figma.com/design/ABC/File?node-id=1-1",
"name": "Icon24Arrow",
"id": "icon-arrow",
"importPath": "@company/icons/arrow",
"source": "./src/icons/Icon24Arrow.tsx"
},
{
"url": "https://www.figma.com/design/ABC/File?node-id=1-2",
"name": "Icon24Check",
"id": "icon-check",
"importPath": "@company/icons/check",
"source": "./src/icons/Icon24Check.tsx"
}
]
}

Each entry in components must include a url. All other fields are passed to the template as properties on the batch object.

Multiple templates​

If your batch file covers components that use different templates, use an array at the top level:

design-system.figma.batch.json
[
{
"templateFile": "./icons.figma.batch.ts",
"components": [
{
"url": "https://www.figma.com/design/ABC/File?node-id=1-1",
"name": "Icon24Arrow",
"id": "icon-arrow",
"importPath": "@company/icons/arrow"
}
]
},
{
"templateFile": "./buttons.figma.batch.ts",
"components": [
{
"url": "https://www.figma.com/design/ABC/File?node-id=2-1",
"name": "PrimaryButton",
"id": "button-primary",
"importPath": "@company/buttons/primary"
}
]
}
]

Setup​

Discovery​

The CLI discovers batch files through the same include/exclude mechanism as all other Code Connect files. The default include globs already include **/*.figma.batch.json, so batch files work out of the box for projects that don't have a custom include in their figma.config.json.

If your project defines a custom include list, add the batch glob explicitly:

figma.config.json
{
"codeConnect": {
"include": ["**/*.figma.ts", "**/*.figma.batch.json"],
"label": "React",
"language": "jsx"
}
}

The template files (.figma.batch.ts) referenced by templateFile do not need to appear in include. They are read on demand when the CLI processes the JSON file.

Publishing​

Once your files are in place, publish the same way as any other Code Connect file:

npx figma connect publish

Each entry in your components array is published as an independent Code Connect doc. Unpublishing also works automatically: each component is removed individually by its Figma node URL.

Complete example​

Here is a full example connecting a library of icons, where each icon supports a Size variant and is imported from a package path unique to that icon.

icons.figma.batch.ts
import figma from 'figma'

const instance = figma.selectedInstance

const size = instance.getEnum('Size', {
Small: '16px',
Medium: '24px',
Large: '32px',
})

const iconSnippet = figma.code`
<${figma.batch.name} size={${size}} />
`

const importsList = figma.batch.withOutline
? figma.batch.name
: [figma.batch.name, 'IconOutline'].join(', ')

export default {
example: figma.batch.withOutline
? figma.code`
<IconOutline>${iconSnippet}</IconOutline>
`
: iconSnippet,
imports: [`import { ${importsList} } from "${figma.batch.importPath}"`],
id: figma.batch.id,
metadata: {
nestable: true,
},
}

icons.figma.batch.json
{
"templateFile": "./icons.figma.batch.ts",
"components": [
{
"url": "https://www.figma.com/design/XYZ/Icons?node-id=10-1",
"name": "ArrowIcon",
"id": "icon-arrow",
"withOutline": false,
"importPath": "@acme/icons",
"source": "./src/icons/ArrowIcon.tsx"
},
{
"url": "https://www.figma.com/design/XYZ/Icons?node-id=10-2",
"name": "CheckIcon",
"id": "icon-check",
"withOutline": true,
"importPath": "@acme/icons",
"source": "./src/icons/CheckIcon.tsx"
},
{
"url": "https://www.figma.com/design/XYZ/Icons?node-id=10-3",
"name": "CloseIcon",
"id": "icon-close",
"withOutline": true,
"importPath": "@acme/icons",
"source": "./src/icons/CloseIcon.tsx"
}
]
}

See the Template API reference for the full API available inside your batch template.