@baur-software/figma-to
v0.5.0
Published
Transform Figma design tokens to any framework via adapters
Maintainers
Readme
@baur-software/figma-to
Transform Figma design tokens to any framework via adapters.
This library bridges Figma's MCP server and REST API with your frontend stack through a pluggable adapter architecture.
Current Adapters
Input Adapters
- Figma - Parse Figma REST API and MCP server responses
Output Adapters
Tailwind/Ionic - Generate production-ready CSS for:
- Tailwind CSS v4 (
@themedirective with CSS variables) - Ionic Framework (CSS custom properties with color variants)
- SolidJS / Capacitor applications
- Tailwind CSS v4 (
Figma - Push design tokens back to Figma:
- Variables (colors, dimensions, strings, booleans)
- Text Styles (typography tokens)
- Effect Styles (shadows)
- Paint Styles (gradients)
SCSS - Generate SCSS partials with variables, maps, and mixins
Why This Library?
Keep your design and code in sync automatically.
Traditionally, when designers update colors, spacing, or typography in Figma, developers manually copy those values into code. This creates drift, inconsistencies, and wasted time.
With @baur-software/figma-to, you can:
- Eliminate manual token translation - Figma variables become CSS automatically
- Stay in sync with design changes - Re-run the generator whenever Figma updates
- Use AI-assisted workflows - With Figma's MCP server, Claude can read your design tokens and generate theme CSS in one conversation
- Support multiple modes - Light/dark themes from Figma variable modes, no manual duplication
- Get framework-ready output - Ionic color variants (shade, tint, contrast, RGB) generated automatically
The Workflow
Figma Variables → This Library → Production CSS
↓ ↓ ↓
Designer Automated Developer
updates sync ships
tokens script featuresWithout this library: Designer changes primary color → Slack message → Developer searches codebase → Updates 5 files → Hopes nothing was missed
With this library: Designer changes primary color → CI runs sync script → PR with all CSS updated → Ship it
AI-Powered Design Sync
When using Claude with the Figma MCP server, just ask:
You: "Get the design tokens from my Figma file and generate theme CSS"Claude will:
- Use
get_variable_defsto fetch your Figma variables - Use this library to transform them into Tailwind/Ionic CSS
- Write the CSS files to your project
No scripts to maintain - the library handles Font() and Effect() strings from MCP automatically.
Installation
npm install @baur-software/figma-toCLI
Quickly sync your Figma design tokens to CSS:
# Using npx
npx @baur-software/figma-to sync --file YOUR_FIGMA_FILE_KEY --output ./src/theme
# Or install globally
npm install -g @baur-software/figma-to
figma-to sync --file YOUR_FIGMA_FILE_KEY --output ./src/themeSet your Figma token:
export FIGMA_TOKEN=your_figma_tokenQuick Start
import { figmaToTailwind } from '@baur-software/figma-to';
// From Figma REST API response
const output = await figmaToTailwind({
variablesResponse: figmaApiResponse,
});
// Write the generated CSS
fs.writeFileSync('theme.css', output.css);Usage
From Figma MCP Server
When using the Figma MCP server with Claude or other AI assistants:
import { figmaToTailwind } from '@baur-software/figma-to';
// From MCP get_variable_defs tool
const output = await figmaToTailwind({
variableDefs: mcpVariables, // { "Color/Primary/500": "#3880f6", ... }
fileName: 'My Design System',
});
console.log(output.css);The library also supports the full MCP response format:
// MCP server response from get_figma_data tool
const output = await figmaToTailwind({
mcpData: mcpResponse,
});From Figma REST API
import { figmaToTailwind } from '@baur-software/figma-to';
// Fetch variables from Figma API
const response = await fetch(
`https://api.figma.com/v1/files/${fileKey}/variables/local`,
{ headers: { 'X-Figma-Token': token } }
);
const variablesResponse = await response.json();
const output = await figmaToTailwind({
variablesResponse,
fileKey,
});Two-Step Workflow
For more control, separate parsing and generation:
import { parseTheme, generateOutput } from '@baur-software/figma-to';
// Step 1: Parse Figma data to normalized theme
const theme = await parseTheme({
variablesResponse: figmaApiResponse,
});
// Inspect or modify the theme
console.log(theme.collections.map(c => c.name));
// Step 2: Generate output with custom options
const output = await generateOutput(theme, {
tailwind: { colorFormat: 'oklch' },
framework: 'solidjs',
});Using Adapters Directly
import {
createFigmaAdapter,
createTailwindIonicAdapter,
} from '@baur-software/figma-to';
const figmaAdapter = createFigmaAdapter();
const theme = await figmaAdapter.parse({ variablesResponse });
const outputAdapter = createTailwindIonicAdapter();
const output = await outputAdapter.transform(theme, options);Output Structure
const output = await figmaToTailwind({ variablesResponse });
// Combined CSS with all sections
output.css;
// Tailwind CSS v4 output
output.tailwind.themeCss; // @theme { ... } block
output.tailwind.darkModeCss; // Dark mode overrides
output.tailwind.variables; // Array of { name, value, comment }
// Ionic output
output.ionic.css; // :root { --ion-color-* } + .ion-color-* classes
output.ionic.theme; // Structured theme object
// Separate files for different use cases
output.files['tailwind-theme.css']; // Just Tailwind
output.files['ionic-theme.css']; // Just Ionic
output.files['variables.css']; // Pure CSS variablesOptions
const output = await figmaToTailwind(input, {
// Select specific mode (default: uses collection's default mode)
mode: 'Dark',
// Target framework for additional CSS
framework: 'solidjs', // 'solidjs' | 'react' | 'vue' | 'angular'
// Generate dark mode CSS
darkMode: true,
// Tailwind-specific options
tailwind: {
colorFormat: 'oklch', // 'oklch' | 'hex'
includeComments: true,
ionicIntegration: true,
prefix: '',
},
// Ionic-specific options
ionic: {
includeColorClasses: true,
},
// Output formatting
format: {
comments: true,
minify: false,
},
});Generated CSS Examples
Tailwind CSS v4 (@theme)
@theme {
/* color */
--color-primary-500: oklch(59.15% 0.1895 262.47);
--color-secondary-500: oklch(78.23% 0.1342 168.91);
--color-success: oklch(67.84% 0.1756 149.23);
/* spacing */
--spacing-1: 4px;
--spacing-2: 8px;
--spacing-4: 16px;
/* font-family */
--font-family-sans: "Inter", sans-serif;
/* radius */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 16px;
}Ionic Theme
:root {
--ion-color-primary: #3880f6;
--ion-color-primary-rgb: 56, 128, 246;
--ion-color-primary-contrast: #ffffff;
--ion-color-primary-contrast-rgb: 255, 255, 255;
--ion-color-primary-shade: #3171d8;
--ion-color-primary-tint: #4c8df7;
--ion-color-secondary: #3cd6af;
/* ... */
}
.ion-color-primary {
--ion-color-base: var(--ion-color-primary);
--ion-color-base-rgb: var(--ion-color-primary-rgb);
--ion-color-contrast: var(--ion-color-primary-contrast);
--ion-color-contrast-rgb: var(--ion-color-primary-contrast-rgb);
--ion-color-shade: var(--ion-color-primary-shade);
--ion-color-tint: var(--ion-color-primary-tint);
}Figma Variable Mapping
The library automatically maps your Figma variables to the appropriate output:
| Figma Variable Path | Tailwind Namespace | Ionic Color |
|---------------------|-------------------|-------------|
| Colors/Primary/500 | --color-primary-500 | --ion-color-primary |
| Colors/Success | --color-success | --ion-color-success |
| Spacing/4 | --spacing-4 | - |
| Typography/Font Family | --font-family-* | - |
| Radius/Medium | --radius-md | - |
Ionic Color Detection
Colors are auto-mapped to Ionic's semantic colors based on naming:
primary,brand→--ion-color-primarysecondary,accent→--ion-color-secondarysuccess,green,positive→--ion-color-successwarning,yellow,orange→--ion-color-warningdanger,error,red→--ion-color-dangerdark,gray-900,black→--ion-color-darkmedium,gray-500→--ion-color-mediumlight,gray-100,white→--ion-color-light
TypeScript Types
The library exports all types from @figma/rest-api-spec plus custom types:
import type {
// Figma API types (from @figma/rest-api-spec)
LocalVariable,
LocalVariableCollection,
GetLocalVariablesResponse,
RGBA,
VariableAlias,
VariableScope,
// Normalized theme types
ThemeFile,
TokenCollection,
Token,
ColorValue,
DimensionValue,
// Output types
TailwindThemeOutput,
IonicTheme,
} from '@baur-software/figma-to';Pushing Tokens Back to Figma
The Figma output adapter lets you push normalized design tokens back to Figma as Variables and Styles. This enables bidirectional sync - you can read tokens from one Figma file and push them to another.
Using the Figma MCP Write Server (Recommended)
The easiest way to push tokens to Figma is via the figma-mcp-write-server, which provides Plugin API access without requiring Figma Enterprise.
Setup:
Install and run the write server:
npx figma-mcp-write-serverOpen Figma Desktop and activate the write-server plugin (Dev Mode → Plugins → figma-mcp-write-server)
Use the adapter in your code:
import { parseTheme, createFigmaOutputAdapter, tryConnectWriteServer, } from '@baur-software/figma-to'; // Parse tokens from source const theme = await parseTheme({ variablesResponse }); // Connect to write server const writeClient = await tryConnectWriteServer(); if (!writeClient) { console.error('Figma plugin not connected'); return; } // Create adapter with write client const adapter = createFigmaOutputAdapter(writeClient); const result = await adapter.transform(theme, { targetFileKey: 'target-file-key', }); // Push to Figma await result.execute(); console.log(result.report.toString()); // Output: // Transformation Report // ===================== // Collections: 2 created // Variables: 45 created // Text Styles: 8 created // Effect Styles: 3 created
Using the REST API (Enterprise)
If you have Figma Enterprise with file_variables:write scope:
import { parseTheme, createFigmaOutputAdapter } from '@baur-software/figma-to';
const theme = await parseTheme({ variablesResponse });
const adapter = createFigmaOutputAdapter();
const result = await adapter.transform(theme, {
targetFileKey: 'your-file-key',
});
// Get the REST API request body
console.log(JSON.stringify(result.requestBody, null, 2));
// Or get manual instructions
console.log(result.getManualInstructions());What Gets Pushed
| Token Type | Figma Output |
|------------|--------------|
| color | Variable (COLOR) |
| dimension | Variable (FLOAT) |
| string | Variable (STRING) |
| boolean | Variable (BOOLEAN) |
| typography | Text Style |
| shadow | Effect Style |
| gradient | Paint Style |
Safety Checks
The adapter includes safety checks to prevent accidental overwrites:
// This will throw SourceOverwriteError
const result = await adapter.transform(theme, {
targetFileKey: theme.meta.figmaFileKey, // Same as source!
});
// Explicitly allow overwriting
const result = await adapter.transform(theme, {
targetFileKey: theme.meta.figmaFileKey,
allowSourceOverwrite: true,
});Integration with Ionic + SolidJS + Capacitor
// generate-theme.ts
import { figmaToTailwind } from '@baur-software/figma-to';
import { writeFileSync } from 'fs';
async function generateTheme() {
const response = await fetch(
`https://api.figma.com/v1/files/${process.env.FIGMA_FILE_KEY}/variables/local`,
{ headers: { 'X-Figma-Token': process.env.FIGMA_TOKEN! } }
);
const output = await figmaToTailwind({
variablesResponse: await response.json(),
}, {
framework: 'solidjs',
darkMode: true,
});
// Write to your project
writeFileSync('src/theme/variables.css', output.files['variables.css']);
writeFileSync('src/theme/ionic.css', output.files['ionic-theme.css']);
writeFileSync('src/theme/tailwind.css', output.files['tailwind-theme.css']);
}
generateTheme();Then import in your app:
/* src/index.css */
@import './theme/tailwind.css';
@import './theme/ionic.css';
@import "tailwindcss";API Reference
figmaToTailwind(input, options?)
One-step conversion from Figma data to CSS output.
parseTheme(input)
Parse Figma data into normalized ThemeFile format.
generateOutput(theme, options?)
Generate CSS output from a normalized theme.
createFigmaAdapter()
Create a Figma input adapter instance with parse() and validate() methods.
createTailwindIonicAdapter()
Create a Tailwind/Ionic output adapter instance with transform() method.
Requirements
- Node.js >= 20
- Tailwind CSS v4 (peer dependency)
License
MIT
