https://github.com/marklearst/figma-vars-hooks
🌳 Welcome to FigmaVars, a React hooks library designed to simplify the integration of Figma variables into your React applications.
https://github.com/marklearst/figma-vars-hooks
design-system design-systems design-tokens figma figma-api figma-design figma-to-code figma-variables react react-hooks react-library storybook storybook-design-system typescript typescript-library variables-css
Last synced: 3 months ago
JSON representation
🌳 Welcome to FigmaVars, a React hooks library designed to simplify the integration of Figma variables into your React applications.
- Host: GitHub
- URL: https://github.com/marklearst/figma-vars-hooks
- Owner: marklearst
- License: mit
- Created: 2025-06-12T18:03:22.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2025-08-27T17:53:37.000Z (5 months ago)
- Last Synced: 2025-09-18T10:11:23.640Z (4 months ago)
- Topics: design-system, design-systems, design-tokens, figma, figma-api, figma-design, figma-to-code, figma-variables, react, react-hooks, react-library, storybook, storybook-design-system, typescript, typescript-library, variables-css
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/@figma-vars/hooks
- Size: 545 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
A fast, typed React 19 hooks library for the Figma Variables API: fetch, update, and manage design tokens via the official [Figma REST API](https://www.figma.com/developers/api#variables).
Built for the modern web, this library provides a suite of hooks to fetch, manage, and mutate your design tokens, making it easy to sync them between Figma and your React applications, Storybooks, or design system dashboards.


[](https://codecov.io/gh/marklearst/figma-vars-hooks)







---
## 🚀 Features
- **✅ Token Agnostic for the Best DX**: Our library doesn't care _how_ you get your Figma token. Use environment variables, `localStorage`, a state management library, or even a simple input field. This framework-agnostic approach means it works seamlessly with Vite, Next.js, Create React App, and more, without locking you into a specific build tool.
- **⚛️ Modern React Hooks**: A full suite of hooks for fetching and mutating Figma variables, collections, and modes.
- **✍️ Ergonomic Mutations**: A `useMutation`-style API for creating, updating, and deleting variables, providing clear loading and error states.
- **🔒 TypeScript-first**: Strictly typed for an ergonomic and safe developer experience. Get autocompletion for all API responses.
- **📖 Storybook & Next.js Ready**: Perfect for building live design token dashboards or style guides.
- **🔄 Local JSON Support**: Use local JSON files exported from Figma Dev Mode plugins when you don't have a Figma Enterprise account, enabling offline development and static deployments.
- **🚧 Style Dictionary Integration**: Coming soon in future beta releases - seamless integration with Amazon's Style Dictionary for multi-platform design token distribution.
---
## 🧱 Architecture Highlights
- ✅ **100% Test Coverage** - Comprehensive test suite with 78 tests covering all hooks, utilities, and edge cases via Vitest
- ✅ **Consistent Error Handling** - Standardized error propagation with clear messages from the Figma API
- ✅ **Strictly Typed APIs** - Modern TypeScript best practices with full type inference and autocompletion
- ✅ **Predictable Hook Signatures** - Consistent, composable patterns designed for safe React integrations
- ✅ **Developer-First Architecture** - Clean folder structure, path aliases, and logical component separation
- ✅ **React Ecosystem** - Built specifically for React apps, Storybook, Next.js, and design system dashboards
- ✅ **Ergonomic DX** - Intuitive API that's easy to use in both prototype and production environments
- ✅ **Minimal Dependencies** - Leverages SWR for caching with careful dependency selection for optimal bundle size
---
## 📦 Install
```bash
npm install @figma-vars/hooks
# or
yarn add @figma-vars/hooks
# or
pnpm add @figma-vars/hooks
```
> **Peer dependencies:** You'll need `react` and `react-dom`.
---
## 🛠️ Setup & Usage
The library is designed to be as flexible as possible. You provide the Figma token and file key, and the hooks handle the rest.
Wrap your application (or the relevant component tree) with the `FigmaVarsProvider`. This makes the Figma token and file key available to all the hooks.
```tsx
// src/main.tsx or App.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import { FigmaVarsProvider } from '@figma-vars/hooks'
import App from './App'
// The token can come from anywhere: .env, localStorage, state, etc.
const FIGMA_TOKEN = import.meta.env.VITE_FIGMA_TOKEN
const FIGMA_FILE_KEY = 'your-figma-file-key'
ReactDOM.createRoot(document.getElementById('root')!).render(
)
```
### Fetching Data
Now, you can use the query hooks anywhere in your app:
```tsx
// src/components/TokenList.tsx
import { useVariables } from '@figma-vars/hooks'
export function TokenList() {
const { data, isLoading, error } = useVariables()
if (isLoading) return
Loading tokens...
if (error) return Error: {error.message}
// The 'data' object contains variables, collections, and modes
const variables = Object.values(data?.variables ?? {})
return (
-
{variable.name}: {JSON.stringify(variable.valuesByMode)}
{variables.map(variable => (
))}
)
}
```
### Mutating Data
To create, update, or delete variables, use the provided mutation hooks. They follow a standard pattern, returning a `mutate` function and states for `data`, `isLoading`, and `error`.
Here's an example of creating a new variable:
```tsx
// src/components/CreateVariableForm.tsx
import { useCreateVariable } from '@figma-vars/hooks'
import type { CreateVariablePayload } from '@figma-vars/hooks'
function CreateVariableForm({ collectionId }: { collectionId: string }) {
const { mutate, data, isLoading, error } = useCreateVariable()
const handleSubmit = (event: React.FormEvent) => {
event.preventDefault()
const form = event.currentTarget
const variableName = (form.elements.namedItem('variableName') as HTMLInputElement)?.value
if (!variableName) return
const payload: CreateVariablePayload = {
name: variableName,
variableCollectionId: collectionId,
resolvedType: 'COLOR', // Example type
}
mutate(payload)
}
return (
{isLoading ? 'Creating...' : 'Create Variable'}
{error &&
Error: {error.message}
}{data &&
Created variable with ID: {data.id}
})
}
```
### Using Local JSON Files (No Enterprise Account Required)
If you don't have a Figma Enterprise account (required for the Variables API), you can still use this library with local JSON files exported from Figma Dev Mode plugins. This is perfect for:
- **Offline Development**: Work on your design system without an internet connection
- **Static Deployments**: Deploy design token dashboards to static hosting
- **CI/CD Pipelines**: Use exported JSON files in automated workflows
- **Team Collaboration**: Share design tokens without API access
#### Getting Your JSON File
We recommend using the [Variables Exporter for Dev Mode](https://www.figma.com/community/plugin/1491572182178544621) plugin:
1. Install the plugin in Figma
2. Open your Figma file in Dev Mode
3. Run the plugin and export your variables as JSON
4. Save the JSON file to your project (e.g., `src/assets/figma-variables.json`)
This plugin exports the exact same format that the Figma Variables API returns, ensuring perfect compatibility with this library.
#### Using the Fallback File
```tsx
// src/main.tsx or App.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import { FigmaVarsProvider } from '@figma-vars/hooks'
import App from './App'
import variablesData from './assets/figma-variables.json'
ReactDOM.createRoot(document.getElementById('root')!).render(
)
```
You can also pass the JSON as a string if you prefer:
```tsx
import variablesJson from './assets/figma-variables.json?raw'
;
```
### Figma PAT Security
When using the Figma API, it's essential to keep your Personal Access Token (PAT) secure. Here are some best practices:
- Never hardcode your PAT in your code.
- Use environment variables or a secure storage mechanism to store your PAT.
- Limit the scope of your PAT to only the necessary permissions.
- Rotate your PAT regularly.
### Advanced Usage
For advanced use cases, you can use the `useFigmaToken` hook to access the token and file key from the context.
```tsx
// src/components/AdvancedUsage.tsx
import { useFigmaToken } from '@figma-vars/hooks'
function AdvancedUsage() {
const { token, fileKey } = useFigmaToken()
// Use the token and file key to make custom API requests
const apiRequest = async () => {
const response = await fetch(`https://api.figma.com/v1/files/${fileKey}/variables`, {
headers: {
'X-Figma-Token': token,
},
})
const data = await response.json()
console.log(data)
}
return Make API Request
}
```
### Error Handling
All hooks return an `error` state that you can use to handle errors.
```tsx
// src/components/ErrorHandling.tsx
import { useVariables } from '@figma-vars/hooks'
function ErrorHandling() {
const { data, isLoading, error } = useVariables()
if (error) {
return (
Error
{error.message}
)
}
// Render data or loading state
}
```
---
## 🧩 API Reference
### Core Hooks
- `useVariables()`: Fetches all local variables for the file key provided to the `FigmaVarsProvider`. Returns a SWR hook state with `data`, `isLoading`, and `error` properties. The actual Figma response is in `data.data`. When `fallbackFile` is provided, it uses the local JSON data instead of making an API request.
- `useVariableCollections()`: A convenience hook that returns just the variable collections from the main `useVariables` data.
- `useVariableModes()`: A convenience hook that returns just the variable modes from the main `useVariables` data.
- `useFigmaToken()`: A simple hook to access the token and file key from the context.
### Provider Props
The `FigmaVarsProvider` accepts the following props:
- `token`: Figma Personal Access Token (PAT) for API authentication. Can be `null` when using `fallbackFile`.
- `fileKey`: Figma file key for the target file. Required for API requests but can be `null` when using `fallbackFile`.
- `fallbackFile`: Optional local JSON file (as object or string) to use instead of API requests. Perfect for users without Figma Enterprise accounts.
### Mutation Hooks
All mutation hooks return an object with the following shape: `{ mutate, data, isLoading, error }`.
- `useCreateVariable()`: Creates a new variable. The `mutate` function expects a `CreateVariablePayload` object.
- `useUpdateVariable()`: Updates an existing variable. The `mutate` function expects an object `{ variableId, payload }` where `payload` is an `UpdateVariablePayload`.
- `useDeleteVariable()`: Deletes a variable. The `mutate` function expects the `variableId` (string) of the variable to delete.
- `useBulkUpdateVariables()`: Creates, updates, or deletes multiple entities in a single batch operation. The `mutate` function expects a `BulkUpdatePayload` object.
### Types
All types are exported from `@figma-vars/hooks`. The core response type from Figma for local variables is `LocalVariablesResponse`.
---
## 📚 Storybook & Next.js Integration
The provider model makes integration trivial. Simply wrap your Storybook stories or Next.js pages with the `FigmaVarsProvider`.
```tsx
// In a Storybook story
import { FigmaVarsProvider, useVariables } from '@figma-vars/hooks'
export const TokensStory = () => (
)
const TokenList = () => {
const { data } = useVariables()
return
{JSON.stringify(data?.variables, null, 2)}
}
```
---
## 📝 Contributing
PRs and issues are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
## 📝 License
This project is licensed under the [MIT License](LICENSE).
© 2024–2025 Mark Learst