
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
figma-metadata-extractor
Advanced tools
Extract metadata and download images from Figma files. A standalone library for accessing Figma design data and downloading frame images programmatically.
A TypeScript library for extracting metadata and downloading images from Figma files programmatically, based on Figma-Context-MCP.
npm install figma-metadata-extractor
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); // 
}
});
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);
}
});
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
getFigmaMetadata(figmaUrl, options)Extracts comprehensive metadata from a Figma file including layout, content, visuals, and component information.
Parameters:
figmaUrl (string): The Figma file URLoptions (FigmaMetadataOptions): Configuration optionsOptions:
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 | string>
FigmaMetadataResult:
{
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:
{
filePath: string; // Absolute path
relativePath: string; // Relative path for code
dimensions: {
width, height;
}
markdown: string; // 
html: string; // <img src="..." />
}
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.
downloadFigmaImages(figmaUrl, nodes, options)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 optionsNode 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 filenamesAdditional 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<FigmaImageResult[]>
When returnBuffer is true, each result will contain a buffer property instead of filePath.
enrichMetadataWithImages(metadata, imagePaths, options)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 options
useRelativePaths?: boolean | string - How to generate paths (default: true)localPath?: string - Base path for relative path calculationReturns: FigmaMetadataResult with enriched nodes
Example:
// 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))
.then(() => `./images/img-${i}.png`),
),
);
// Enrich metadata with file paths
const enriched = enrichMetadataWithImages(result, paths, {
useRelativePaths: true,
});
downloadFigmaFrameImage(figmaUrl, options)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 optionsOptions:
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:
apiKey optiongetFigmaMetadata(url, { apiKey: "figd_xxx..." });
oauthToken optiongetFigmaMetadata(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:
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}`);
console.log(
`Dimensions: ${result.finalDimensions.width}x${result.finalDimensions.height}`,
);
If you want to process the image in memory without saving to disk:
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`);
console.log(
`Dimensions: ${result.finalDimensions.width}x${result.finalDimensions.height}`,
);
// 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();
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",
},
);
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:
import {
simplifyRawFigmaObject,
allExtractors,
layoutExtractor,
textExtractor,
} from "figma-metadata-extractor";
// Use specific extractors
const customResult = simplifyRawFigmaObject(rawFigmaResponse, [
layoutExtractor,
textExtractor,
]);
MIT
FAQs
Extract metadata and download images from Figma files. A standalone library for accessing Figma design data and downloading frame images programmatically.
We found that figma-metadata-extractor demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.