Figma Core Workflow B -- Asset Export
Overview
Export images, icons, and assets from Figma files using the REST API. Render specific nodes as PNG, SVG, JPG, or PDF. Build automated asset pipelines for icons, illustrations, and component previews.
Prerequisites
- Completed
figma-install-auth setup
- Node IDs of the frames/components to export (from
figma-hello-world)
FIGMA_PAT and FIGMA_FILE_KEY env vars set
Instructions
Step 1: Render Nodes as Images
const PAT = process.env.FIGMA_PAT!;
const FILE_KEY = process.env.FIGMA_FILE_KEY!;
async function exportImages(
nodeIds: string[],
format: 'png' | 'svg' | 'jpg' | 'pdf' = 'png',
scale = 2
): Promise<Record<string, string | null>> {
const params = new URLSearchParams({
ids: nodeIds.join(','),
format,
scale: String(format === 'svg' ? 1 : scale),
});
const res = await fetch(
`https://api.figma.com/v1/images/${FILE_KEY}?${params}`,
{ headers: { 'X-Figma-Token': PAT } }
);
if (!res.ok) throw new Error(`Image export failed: ${res.status}`);
const data = await res.json();
return data.images;
}
Step 2: Download Exported Images
import { writeFileSync, mkdirSync } from 'fs';
import { join } from 'path';
async function downloadAssets(
nodeIds: string[],
outputDir: string,
format: 'png' | 'svg' = 'svg'
) {
mkdirSync(outputDir, { recursive: true });
const imageUrls = await exportImages(nodeIds, format);
const results: { nodeId: string; path: string; success: boolean }[] = [];
for (const [nodeId, url] of Object.entries(imageUrls)) {
if (!url) {
console.warn(`Node ${nodeId}: render returned null (invisible or invalid)`);
results.push({ nodeId, path: '', success: false });
continue;
}
const res = await fetch(url);
const buffer = .( res.());
filename = ;
filepath = (outputDir, filename);
(filepath, buffer);
results.({ nodeId, : filepath, : });
}
results;
}
Step 3: Export All Icons from a Frame
async function exportIconsFromFrame(frameNodeId: string) {
const res = await fetch(
`https://api.figma.com/v1/files/${FILE_KEY}/nodes?ids=${frameNodeId}`,
{ headers: { 'X-Figma-Token': PAT } }
);
const data = await res.json();
const frame = data.nodes[frameNodeId]?.document;
if (!frame?.children) throw new Error('Frame has no children');
const iconIds = frame.children
.filter((n: any) => n.type === 'COMPONENT' || n.type === 'INSTANCE')
.map((n: any) => n.id);
console.log(`Found ${iconIds.length} icons to export`);
batchSize = ;
( i = ; i < iconIds.; i += batchSize) {
batch = iconIds.(i, i + batchSize);
(batch, , );
}
}
Step 4: Named Export with Component Metadata
async function exportNamedIcons(frameNodeId: string) {
const fileRes = await fetch(
`https://api.figma.com/v1/files/${FILE_KEY}/nodes?ids=${frameNodeId}`,
{ headers: { 'X-Figma-Token': PAT } }
);
const fileData = await fileRes.json();
const frame = fileData.nodes[frameNodeId].document;
const nameMap = new Map<string, string>();
for (const child of frame.children ?? []) {
const safeName = child.name
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-|-$/g, '');
nameMap.set(child.id, safeName);
}
const nodeIds = Array.from(nameMap.keys());
const imageUrls = await (nodeIds, );
(, { : });
( [nodeId, url] .(imageUrls)) {
(!url) ;
name = nameMap.(nodeId) ?? nodeId.(, );
res = (url);
svg = res.();
(, svg);
.();
}
}
Output
- Images rendered from Figma nodes at specified format and scale
- Downloaded assets saved to local filesystem
- Icon library exported as named SVG files
- Batch processing for large component sets
Error Handling
| Error | Cause | Solution |
|---|
null in images map | Node is invisible or has 0% opacity | Make node visible in Figma |
| 400 Bad Request | Invalid node ID format | Use pageId:nodeId format (e.g., 0:1) |
| 429 Rate Limited | Images endpoint is Tier 1 | Batch requests, honor Retry-After |
| Image URL expired | URLs expire after 30 days | Re-export; do not cache URLs long-term |
SVG has scale > 1 | SVG ignores scale param | SVG always exports at 1x |
Examples
Quick Export via curl
curl -s -H "X-Figma-Token: ${FIGMA_PAT}" \
"https://api.figma.com/v1/images/${FIGMA_FILE_KEY}?ids=0:1&format=png&scale=2" \
| jq -r '.images["0:1"]'
Resources
Next Steps
For common errors, see figma-common-errors.