Extract metadata and download images from Figma files. A standalone library for accessing Figma design data and downloading frame images programmatically.
npm install figma-metadata-extractorA TypeScript library for extracting metadata and downloading images from Figma files programmatically, based on Figma-Context-MCP.
``bash`
npm install figma-metadata-extractor
- 🎨 Extract comprehensive metadata from Figma files
- 📦 Auto-download image assets (to disk or as buffers)
- 🔄 Support for both file-based and buffer-based workflows
- 🎯 Enrich metadata with image paths and markup
- 🔐 Support for both API keys and OAuth tokens
- 📝 Multiple output formats (JSON, YAML, object)
`typescript
import { getFigmaMetadata } from "figma-metadata-extractor";
// Extract metadata AND automatically download image assets to disk
const metadata = await getFigmaMetadata(
"https://figma.com/file/ABC123/My-Design",
{
apiKey: "your-figma-api-key",
outputFormat: "object",
downloadImages: true, // Auto-download image assets
localPath: "./assets/images", // Where to save images
},
);
// Nodes are enriched with downloadedImage property
metadata.nodes.forEach((node) => {
if (node.downloadedImage) {
console.log(node.downloadedImage.filePath);
console.log(node.downloadedImage.markdown); // !name
}
});
`
`typescript
import {
getFigmaMetadata,
enrichMetadataWithImages,
} from "figma-metadata-extractor";
import fs from "fs/promises";
// Get metadata with images as ArrayBuffers
const result = await getFigmaMetadata(
"https://figma.com/file/ABC123/My-Design",
{
apiKey: "your-figma-api-key",
downloadImages: true,
returnBuffer: true, // Get images as ArrayBuffer
},
);
// Images are returned separately, metadata is not enriched
console.log(Downloaded ${result.images.length} images as buffers);
// Process buffers (upload to S3, convert format, etc.)
const savedPaths: string[] = [];
for (const image of result.images) {
// Example: Save to disk after processing
const buffer = Buffer.from(image.buffer);
const path = ./processed/${Date.now()}.png;
await fs.writeFile(path, buffer);
savedPaths.push(path);
}
// Optionally enrich metadata with saved file paths
const enrichedMetadata = enrichMetadataWithImages(result, savedPaths, {
useRelativePaths: true,
});
// Now nodes have downloadedImage properties
enrichedMetadata.nodes.forEach((node) => {
if (node.downloadedImage) {
console.log(node.downloadedImage.markdown);
}
});
`
`typescript
import { getFigmaMetadata } from "figma-metadata-extractor";
// Extract metadata from a Figma file
const metadata = await getFigmaMetadata(
"https://figma.com/file/ABC123/My-Design",
{
apiKey: "your-figma-api-key",
outputFormat: "object", // or 'json' or 'yaml'
},
);
console.log(metadata.nodes); // Array of design nodes
console.log(metadata.globalVars); // Styles, colors, etc.
// Download images from the file
const images = await downloadFigmaImages(
"https://figma.com/file/ABC123/My-Design",
[
{
nodeId: "1234:5678",
fileName: "icon.svg",
},
{
nodeId: "9876:5432",
fileName: "hero-image.png",
},
],
{
apiKey: "your-figma-api-key",
localPath: "./assets/images",
},
);
console.log(images); // Array of download results
// Download a single frame image from a Figma URL
const frameImage = await downloadFigmaFrameImage(
"https://figma.com/file/ABC123/My-Design?node-id=1234-5678",
{
apiKey: "your-figma-api-key",
localPath: "./assets/frames",
fileName: "my-frame.png",
format: "png", // or 'svg'
pngScale: 2,
},
);
console.log(frameImage.filePath); // Path to downloaded image
`
Extracts comprehensive metadata from a Figma file including layout, content, visuals, and component information.
Parameters:
- figmaUrl (string): The Figma file URLoptions
- (FigmaMetadataOptions): Configuration options
Options:
- apiKey?: string - Figma API key (Personal Access Token). Either apiKey or oauthToken is requiredoauthToken?: string
- - Figma OAuth Bearer token. When provided, OAuth is used automaticallyoutputFormat?: 'json' | 'yaml' | 'object'
- - Output format (default: 'object')depth?: number
- - Maximum depth to traverse the node treedownloadImages?: boolean
- - Automatically download image assets and enrich metadata (default: false)localPath?: string
- - Local path for downloaded images (optional if returnBuffer is true)imageFormat?: 'png' | 'svg'
- - Image format for downloads (default: 'png')pngScale?: number
- - Export scale for PNG images (default: 2)returnBuffer?: boolean
- - Return images as ArrayBuffer instead of saving to disk (default: false)enableLogging?: boolean
- - Enable JSON debug log files (default: false)
Returns: Promise
FigmaMetadataResult:
`typescript`
{
metadata: any; // File metadata
nodes: any[]; // Design nodes
globalVars: any; // Styles, colors, etc.
images?: FigmaImageResult[]; // Only present when downloadImages: true and returnBuffer: true
}
When downloadImages: true and returnBuffer: false, nodes with image assets will include a downloadedImage property:
`typescript`
{
filePath: string; // Absolute path
relativePath: string; // Relative path for code
dimensions: {
width, height;
}
markdown: string; // !name
html: string; //
}
When downloadImages: true and returnBuffer: true, images are returned in the images array and nodes are NOT enriched. Use enrichMetadataWithImages() to enrich them later after saving buffers to disk.
Downloads SVG and PNG images from a Figma file.
Parameters:
- figmaUrl (string): The Figma file URLnodes
- (FigmaImageNode[]): Array of image nodes to downloadoptions
- (FigmaMetadataOptions & FigmaImageOptions): Configuration options
Node Properties:
- nodeId: string - The Figma node ID (format: '1234:5678')fileName: string
- - Local filename (must end with .png or .svg)imageRef?: string
- - Image reference for image fillsneedsCropping?: boolean
- - Whether image needs croppingcropTransform?: number[][]
- - Transform matrix for croppingrequiresImageDimensions?: boolean
- - Whether to generate CSS variablesfilenameSuffix?: string
- - Suffix for unique filenames
Additional Options:
- pngScale?: number - Export scale for PNG images (default: 2)localPath?: string
- - Absolute path to save images (optional if returnBuffer is true)returnBuffer?: boolean
- - Return images as ArrayBuffer instead of saving to disk (default: false)enableLogging?: boolean
- - Enable JSON debug log files (default: false)
Returns: Promise
When returnBuffer is true, each result will contain a buffer property instead of filePath.
Enriches metadata with saved image file paths after saving buffers to disk.
Parameters:
- metadata (FigmaMetadataResult): The metadata result from getFigmaMetadata with returnBuffer: trueimagePaths
- (string[]): Array of file paths where images were saved (must match order of metadata.images)options
- (object): Configuration optionsuseRelativePaths?: boolean | string
- - How to generate paths (default: true)localPath?: string
- - Base path for relative path calculation
Returns: FigmaMetadataResult with enriched nodes
Example:
`typescript
// Get metadata with buffers
const result = await getFigmaMetadata(url, {
apiKey: "key",
downloadImages: true,
returnBuffer: true,
});
// Save buffers to disk
const paths = await Promise.all(
result.images.map((img, i) =>
fs
.writeFile(./images/img-${i}.png, Buffer.from(img.buffer))./images/img-${i}.png
.then(() => ),
),
);
// Enrich metadata with file paths
const enriched = enrichMetadataWithImages(result, paths, {
useRelativePaths: true,
});
`
Downloads a single frame image from a Figma URL that contains a node-id parameter.
Parameters:
- figmaUrl (string): The Figma URL with node-id parameter (e.g., https://figma.com/file/ABC123/My-Design?node-id=1234-5678)options
- (FigmaFrameImageOptions): Configuration options
Options:
- apiKey?: string - Figma API key (Personal Access Token). Either apiKey or oauthToken is requiredoauthToken?: string
- - Figma OAuth Bearer token. When provided, OAuth is used automaticallylocalPath?: string
- - Absolute path to save the image (optional if returnBuffer is true)fileName?: string
- - Local filename (must end with .png or .svg, optional if returnBuffer is true)format?: 'png' | 'svg'
- - Image format to download (default: 'png')pngScale?: number
- - Export scale for PNG images (default: 2)returnBuffer?: boolean
- - Return image as ArrayBuffer instead of saving to disk (default: false)enableLogging?: boolean
- - Enable JSON debug log files (default: false)
Returns: Promise
Result Properties:
- filePath?: string - Path to saved file (only when returnBuffer is false)buffer?: ArrayBuffer
- - Image data as ArrayBuffer (only when returnBuffer is true)finalDimensions: { width: number; height: number }
- - Image dimensionswasCropped: boolean
- - Whether the image was croppedcssVariables?: string
- - CSS variables for dimensions (if requested)
You need either a Figma API key (Personal Access Token) or an OAuth token:
1. Go to Figma → Settings → Account → Personal Access Tokens
2. Generate a new token
3. Use it in the apiKey option
`typescript`
getFigmaMetadata(url, { apiKey: "figd_xxx..." });
1. Set up Figma OAuth in your application
2. Use the bearer token in the oauthToken option
`typescript`
getFigmaMetadata(url, { oauthToken: "figu_xxx..." });
Note: When oauthToken is provided, OAuth (Bearer auth) is used automatically. If both apiKey and oauthToken are provided, oauthToken takes precedence.
The easiest way to download a frame image is to copy the Figma URL directly from your browser when viewing a specific frame:
`typescript
import { downloadFigmaFrameImage } from "figma-metadata-extractor";
// Copy this URL from Figma when viewing a frame
const figmaUrl =
"https://www.figma.com/design/ABC123/My-Design?node-id=1234-5678&t=xyz123";
// Save to disk
const result = await downloadFigmaFrameImage(figmaUrl, {
apiKey: "your-figma-api-key",
localPath: "./downloads",
fileName: "my-frame.png",
format: "png",
pngScale: 2, // High resolution
});
console.log(Downloaded to: ${result.filePath});Dimensions: ${result.finalDimensions.width}x${result.finalDimensions.height}
console.log(
,`
);
If you want to process the image in memory without saving to disk:
`typescript
import { downloadFigmaFrameImage } from "figma-metadata-extractor";
const figmaUrl =
"https://www.figma.com/design/ABC123/My-Design?node-id=1234-5678";
// Get as ArrayBuffer
const result = await downloadFigmaFrameImage(figmaUrl, {
apiKey: "your-figma-api-key",
returnBuffer: true,
format: "png",
});
console.log(Buffer size: ${result.buffer.byteLength} bytes);Dimensions: ${result.finalDimensions.width}x${result.finalDimensions.height}
console.log(
,
);
// Use the buffer directly (e.g., upload to cloud storage, process with sharp, etc.)
// const processedImage = await sharp(Buffer.from(result.buffer)).resize(100, 100).toBuffer();
`
`typescript
import { downloadFigmaImages } from "figma-metadata-extractor";
// For multiple frames, use the batch download function
const results = await downloadFigmaImages(
"https://figma.com/file/ABC123/My-Design",
[
{ nodeId: "1234:5678", fileName: "frame1.png" },
{ nodeId: "9876:5432", fileName: "frame2.svg" },
{ nodeId: "1111:2222", fileName: "frame3.png" },
],
{
apiKey: "your-figma-api-key",
localPath: "./frames",
},
);
`
`typescript
import { downloadFigmaImages } from "figma-metadata-extractor";
// Get multiple images as ArrayBuffers
const results = await downloadFigmaImages(
"https://figma.com/file/ABC123/My-Design",
[
{ nodeId: "1234:5678", fileName: "frame1.png" },
{ nodeId: "9876:5432", fileName: "frame2.png" },
],
{
apiKey: "your-figma-api-key",
returnBuffer: true,
},
);
// Process each buffer
results.forEach((result, index) => {
console.log(Image ${index}: ${result.buffer.byteLength} bytes);`
// Upload to S3, process with sharp, etc.
});
The library also exports the underlying extractor system for custom processing:
`typescript
import {
simplifyRawFigmaObject,
allExtractors,
layoutExtractor,
textExtractor,
} from "figma-metadata-extractor";
// Use specific extractors
const customResult = simplifyRawFigmaObject(rawFigmaResponse, [
layoutExtractor,
textExtractor,
]);
``
MIT