DEV Community

Alex Spinov
Alex Spinov

Posted on

Figma Has a Free API — Here's How to Extract Design Tokens and Automate Your Workflow

A frontend developer told me he spent every sprint manually copying hex codes, font sizes, and spacing values from Figma to CSS. 4 hours per sprint, 50 sprints per year = 200 hours wasted. Then he automated it with Figma's API.

What Figma's API Offers for Free

Figma free plan + REST API:

  • Read access to all files you have access to
  • Design tokens extraction — colors, typography, spacing
  • Component data — inspect any component's properties
  • Image export — render any frame as PNG, SVG, JPG, PDF
  • Comments API — read and post comments
  • File version history
  • Webhooks for real-time updates

Quick Start

# Get your Personal Access Token from Figma > Settings > Personal Access Tokens
export FIGMA_TOKEN='figd_YOUR_TOKEN'

# Get file data
curl 'https://api.figma.com/v1/files/YOUR_FILE_KEY' \
  -H "X-Figma-Token: $FIGMA_TOKEN" | jq '.document.children | length'
Enter fullscreen mode Exit fullscreen mode

Extract Design Tokens

const FIGMA_TOKEN = process.env.FIGMA_TOKEN;
const FILE_KEY = 'YOUR_FILE_KEY';

async function getFileStyles(fileKey) {
  const res = await fetch(`https://api.figma.com/v1/files/${fileKey}/styles`, {
    headers: { 'X-Figma-Token': FIGMA_TOKEN }
  });
  const { meta } = await res.json();
  return meta.styles;
}

async function extractColors(fileKey) {
  const res = await fetch(`https://api.figma.com/v1/files/${fileKey}`, {
    headers: { 'X-Figma-Token': FIGMA_TOKEN }
  });
  const file = await res.json();

  const colors = {};
  // Walk the document tree to find color styles
  function walk(node) {
    if (node.fills && node.fills[0]?.type === 'SOLID') {
      const { r, g, b, a } = node.fills[0].color;
      const hex = `#${[r, g, b].map(v => Math.round(v * 255).toString(16).padStart(2, '0')).join('')}`;
      if (node.name.startsWith('color/')) {
        colors[node.name] = hex;
      }
    }
    node.children?.forEach(walk);
  }
  walk(file.document);
  return colors;
}

// Generate CSS custom properties
const colors = await extractColors(FILE_KEY);
const css = ':root {\n' + 
  Object.entries(colors).map(([name, hex]) => 
    `  --${name.replace('/', '-')}: ${hex};`
  ).join('\n') + 
  '\n}';

console.log(css);
// :root {
//   --color-primary: #3b82f6;
//   --color-secondary: #10b981;
//   --color-danger: #ef4444;
// }
Enter fullscreen mode Exit fullscreen mode

Export Images from Figma

async function exportFrames(fileKey, nodeIds, format = 'png', scale = 2) {
  const ids = nodeIds.join(',');
  const res = await fetch(
    `https://api.figma.com/v1/images/${fileKey}?ids=${ids}&format=${format}&scale=${scale}`,
    { headers: { 'X-Figma-Token': FIGMA_TOKEN } }
  );
  const { images } = await res.json();

  // Download each image
  for (const [nodeId, url] of Object.entries(images)) {
    const imgRes = await fetch(url);
    const buffer = await imgRes.arrayBuffer();
    require('fs').writeFileSync(`./exports/${nodeId}.${format}`, Buffer.from(buffer));
  }
}

// Export specific frames
await exportFrames(FILE_KEY, ['1:23', '4:56'], 'svg');
Enter fullscreen mode Exit fullscreen mode

Component Inspector

async function getComponents(fileKey) {
  const res = await fetch(`https://api.figma.com/v1/files/${fileKey}/components`, {
    headers: { 'X-Figma-Token': FIGMA_TOKEN }
  });
  const { meta } = await res.json();

  return meta.components.map(c => ({
    name: c.name,
    description: c.description,
    key: c.key,
    containingFrame: c.containing_frame?.name
  }));
}
Enter fullscreen mode Exit fullscreen mode

Webhooks (Real-Time Updates)

// Register a webhook
const webhook = await fetch('https://api.figma.com/v2/webhooks', {
  method: 'POST',
  headers: {
    'X-Figma-Token': FIGMA_TOKEN,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    event_type: 'FILE_UPDATE',
    team_id: 'TEAM_ID',
    endpoint: 'https://your-server.com/figma-webhook',
    passcode: 'your-secret'
  })
});

// Handle webhook events
app.post('/figma-webhook', (req, res) => {
  if (req.body.passcode !== 'your-secret') return res.sendStatus(403);

  console.log(`File ${req.body.file_key} updated by ${req.body.triggered_by.handle}`);
  // Re-extract design tokens, rebuild CSS, notify team...
  res.sendStatus(200);
});
Enter fullscreen mode Exit fullscreen mode

Automation Ideas

  1. Design token pipeline — Figma → API → CSS/Tailwind config → deploy
  2. Screenshot comparison — export frames, compare with production
  3. Component documentation — auto-generate docs from Figma components
  4. Asset pipeline — auto-export icons as SVG when file updates
  5. Design QA — compare implemented UI with Figma designs pixel-by-pixel

Need to scrape design inspiration? Check out my web scraping actors on Apify — collect data from Dribbble, Behance, and more.

Need a design-to-code pipeline? Email me at spinov001@gmail.com.

Top comments (0)