figma-export-assets (JS module)
A few months ago I started developing a CLI to easily start a design system with Figma as the single source of truth for logos and icons. These assets were organized as components on a Figma page, and my goal for easy updates was to pull them programmaticaly into my project using Figma's API. My specific needs were:
- Download all logos as
.svg
and.png
intosrc/logos
. - Download all icons (>2000!) into
src/icons
I aimed for this output:
src
│
├── logos
│ ├── logo-stylized.svg
│ ├── logo-stylized.png
│ ├── logo-wordmark.png
│ └── logo-wordmark.svg
│
└── icons
├── activity.svg
├── alarm.svg
├── alarm-fill.svg
├── ...
├── // other >2000 icons
├── ...
└── zoom-out.svg
I quickly found some Node packages, but there were bugs or missing features:
- There wasn't an option to set multiple formats for specific assets.
- It was impossible to ignore certain layers.
- >400 requested exports exceeded Figma's Export API, but batching was not implemented.
- There was no feature to customize file paths per asset.
I decided to take it into my own hands, forked figma-export-icons, took some inspiration from figma-assets-exporter and rewrote it to make it super customizable.
figma-export-assets
The result figma-export-assets
is of course available on GitHub and NPM – and I'm actually quite happy with the functionality of the package (shamelessly copied from the docs):
- 📄 Multiple Figma Pages/Frames: Configure to process assets from various Figma pages or specific frames.
- 🔄 Batch Exporting: Supports batch exporting out of the box to overcame Figma API export limits.
- 📁 Customizable Asset Paths/Names: Set unique saving paths or names for each asset.
- 🌈 Customizable Asset Format: Chose any Figma export format for each asset.
- 🚫 Asset Exclusion: Easily exclude specific assets from export based on their names.
- ⚙️ Axios Integration: Extend or modify Axios configurations for advanced HTTP request handling.
- 🌟 Variant Exporting: Overridable option to export components with variants as separate assets.
Here’s how it works for my initial requirements:
require("dotenv").config({ path: ".env" });
const { FigmaExporter } = require("figma-export-assets");
// Helper function to optimize path coming from Figma
const optimizePath = (path) =>
path.replace("assets/", "").replace("name=", "").replace(".png", "");
async function main() {
// 0. Initialize exporter
const figma = new FigmaExporter({
figmaPersonalToken: process.env.figma_token,
fileId: process.env.figma_file_id,
page: "📎 assets",
assetsPath: "src",
});
// 1. Get an array of all assets in the Figma file
let assets = await figma.getAssets();
// 2. Create PNGs from logos
let pngs = assets.filter((asset) => asset.name.includes("assets/logos"));
pngs = await figma.exportAssets(pngs, "png", 4);
const pngDownloads = pngs.map(async (asset) => {
await figma.saveAsset(asset, {
path: optimizePath(asset.name),
});
console.log(`Downloaded ${asset.name} as png`);
});
await Promise.all(pngDownloads);
// 3. Create SVGs from logos and icons
svgs = await figma.exportAssets(assets, "svg");
const svgDownloads = svgs.map(async (asset) => {
await figma.saveAsset(asset, {
name: optimizePath(asset.name),
});
console.log(`Downloaded ${asset.name} as svg`);
});
await Promise.all(svgDownloads);
}
// Run everything
main();
Broader usage
Of course this isn't limited to just icons or logos – It can be used with any imagery like photos, Open Graph images, illustrations etc., making it a nice tool to automize workflows between Figma and development.
For my personal project it was just perfect, and to my delight, just a few weeks later it was implemented in one Design System I'm part of. 🎉
Looking forward to other usages – maybe yours? 😉