# Working with Variable Collections and Modes in Figma: A Complete Guide to Design Tokens

> Master Figma variable collections and modes with this guide. Learn to manage design tokens and implement multi-theme support efficiently using the Figma Plugin API.

- Repository: [Figma/mcp-server-guide](https://github.com/figma/mcp-server-guide)
- Tags: how-to-guide
- Published: 2026-03-30

---

**Figma variable collections are containers that group related design tokens, while modes enable multi-theme support (Light/Dark) within a single collection using the Figma Plugin API and helper scripts from the figma/mcp-server-guide repository.**

This guide explores working with variable collections and modes in Figma based on the canonical reference implementation in the `figma/mcp-server-guide` repository. Whether you are automating design system generation or managing complex theming architectures, understanding how collections structure primitives and semantic tokens alongside mode-specific values is essential for scalable, maintainable design systems.

## Understanding Variable Collections and Modes Architecture

Figma’s design token system organizes variables into **collections**, which act as namespaces for related tokens such as colors, spacing, or typography. Each collection contains one or more **modes** that store alternate values for every variable within that collection.

### What Are Variable Collections?

A **Variable Collection** is created using `figma.variables.createVariableCollection(name)`. According to the source code in [`skills/figma-generate-library/scripts/createVariableCollection.js`](https://github.com/figma/mcp-server-guide/blob/main/skills/figma-generate-library/scripts/createVariableCollection.js), every new collection initializes with a single default mode automatically named "Mode 1". This default mode must be renamed to your first meaningful mode name (e.g., "Value", "Light", or "Base") before adding additional modes.

Collections support metadata tagging via `setSharedPluginData` using keys like `dsb_key` and `run_id`, enabling idempotent cleanup and safe re-runs of generation scripts.

### Understanding Modes and Plan Limits

Modes represent contextual variations of your design tokens. As documented in [`skills/figma-use/references/variable-patterns.md`](https://github.com/figma/mcp-server-guide/blob/main/skills/figma-use/references/variable-patterns.md) (lines 33-34), Figma enforces plan-dependent mode limits:

- **Starter**: 1 mode per collection
- **Professional**: 4 modes per collection  
- **Enterprise**: 40+ modes per collection

You rename the default mode using `collection.renameMode(collection.modes[0].modeId, firstModeName)` and add subsequent modes with `collection.addMode(name)`.

## Creating Variable Collections and Modes

The repository provides two approaches for working with variable collections and modes in Figma: direct API access and helper utilities.

### Direct API Implementation

For minimal use cases, interact directly with the Figma Plugin API:

```javascript
// Create a collection called "Spacing"
const spacing = figma.variables.createVariableCollection('Spacing');

// Rename the default mode to "Value"
spacing.renameMode(spacing.modes[0].modeId, 'Value');

// Tag for idempotent cleanup (optional but recommended)
spacing.setSharedPluginData('dsb', 'key', 'collection/spacing');
spacing.setSharedPluginData('dsb', 'run_id', 'run-2024-07');

```

### Using the Helper Script

For production workflows, use the abstraction in [`skills/figma-generate-library/scripts/createVariableCollection.js`](https://github.com/figma/mcp-server-guide/blob/main/skills/figma-generate-library/scripts/createVariableCollection.js):

```javascript
// Creates collection + modes, returns modeId map
const { collection, modeIds } = await createVariableCollection(
  'Color',               // collection name
  ['Light', 'Dark'],     // mode list
  'run-2024-07'          // optional run ID for cleanup
);

// modeIds = { Light: '12345', Dark: '67890' }

```

This helper automatically handles the default mode renaming, subsequent mode creation, and metadata tagging for safe re-runs.

## Building a Token Architecture with Primitives and Semantics

The recommended pattern for working with variable collections and modes in Figma separates **primitive** variables (raw values) from **semantic** variables (theme-aware aliases).

### Creating Hidden Primitive Variables

Primitive variables store raw values (hex colors, base spacing units) and remain hidden from designers. Implemented in [`skills/figma-generate-library/scripts/createSemanticTokens.js`](https://github.com/figma/mcp-server-guide/blob/main/skills/figma-generate-library/scripts/createSemanticTokens.js):

```javascript
// Assume primColl is the "Primitives" collection with a single "Value" mode
const valueMode = primColl.modes[0].modeId;

const red = figma.variables.createVariable('red/500', primColl, 'COLOR');
red.setValueForMode(valueMode, { r: 0.95, g: 0.2, b: 0.2, a: 1 }); // raw RGBA
red.scopes = []; // hide from pickers
red.setVariableCodeSyntax('WEB', 'var(--color-red-500)');

```

Setting `scopes = []` prevents primitives from appearing in Figma's variable pickers, ensuring designers only interact with semantic tokens.

### Creating Semantic Aliases and Modes

Semantic tokens alias primitives and expose the correct modes to designers. This pattern uses `figma.variables.createVariableAlias()` to reference primitives per mode:

```javascript
// colorColl has Light/Dark modes (modeIds from helper)
const semantic = figma.variables.createVariable('color/bg/primary', colorColl, 'COLOR');

// Light mode -> alias to red/500
semantic.setValueForMode(modeIds.Light,
  figma.variables.createVariableAlias(red));

// Dark mode -> alias to another primitive (e.g., gray/800)
const gray = /* previously created primitive */;
semantic.setValueForMode(modeIds.Dark,
  figma.variables.createVariableAlias(gray));

// Expose to designers with appropriate scopes
semantic.scopes = ['FRAME_FILL', 'SHAPE_FILL'];
semantic.setVariableCodeSyntax('WEB', 'var(--color-bg-primary)');

```

### Batch Token Creation

For generating entire libraries, use the batch processor in [`createSemanticTokens.js`](https://github.com/figma/mcp-server-guide/blob/main/createSemanticTokens.js):

```javascript
const tokenMap = [
  {
    name: 'color/bg/primary',
    type: 'COLOR',
    values: { Light: { type: 'VARIABLE_ALIAS', id: red.id },
              Dark:  { type: 'VARIABLE_ALIAS', id: gray.id } },
    scopes: ['FRAME_FILL', 'SHAPE_FILL'],
    codeSyntax: { WEB: 'var(--color-bg-primary)' }
  },
  {
    name: 'spacing/md',
    type: 'FLOAT',
    values: { Value: 16 },
    scopes: ['GAP'],
    codeSyntax: { WEB: 'var(--spacing-md)' }
  }
];

await createSemanticTokens(colorColl, modeIds, tokenMap, 'run-2024-07');

```

This utility handles hex-to-RGBA conversion, aliasing, scope assignment, and metadata tagging automatically.

## Managing Collections for Production Workflows

When working with variable collections and modes in Figma at scale, implement cleanup and validation patterns from [`skills/figma-generate-library/references/token-creation.md`](https://github.com/figma/mcp-server-guide/blob/main/skills/figma-generate-library/references/token-creation.md). The shared plugin data keys (`dsb_key` and `run_id`) allow scripts to identify and remove previous generation runs before creating new tokens, preventing duplication and enabling iterative development.

## Summary

- **Variable Collections** are containers created via `figma.variables.createVariableCollection()` that always initialize with a default "Mode 1" requiring immediate renaming.
- **Modes** enable per-collection theming (Light/Dark) with plan limits ranging from 1 (Starter) to 40+ (Enterprise).
- **Primitive variables** should use `scopes = []` to remain hidden, while **semantic variables** expose appropriate scopes and alias primitives per mode.
- The [`createVariableCollection.js`](https://github.com/figma/mcp-server-guide/blob/main/createVariableCollection.js) and [`createSemanticTokens.js`](https://github.com/figma/mcp-server-guide/blob/main/createSemanticTokens.js) helpers in the figma/mcp-server-guide repository automate metadata tagging for idempotent, production-safe workflows.
- **Code syntax** and **scopes** bridge the gap between Figma's visual interface and developer handoff in Dev Mode.

## Frequently Asked Questions

### What are the mode limits for Figma variable collections?

Figma enforces strict mode limits based on your plan tier: Starter teams can use 1 mode per collection, Professional teams can use 4 modes, and Enterprise teams can use 40 or more. These limits are documented in [`skills/figma-use/references/variable-patterns.md`](https://github.com/figma/mcp-server-guide/blob/main/skills/figma-use/references/variable-patterns.md) and apply across all collection types including color, number, string, and boolean variables.

### How do I rename the default mode when creating a new collection?

When you call `figma.variables.createVariableCollection(name)`, Figma automatically creates "Mode 1" as the default. You must call `collection.renameMode(collection.modes[0].modeId, 'YourModeName')` immediately after creation. The helper function in [`skills/figma-generate-library/scripts/createVariableCollection.js`](https://github.com/figma/mcp-server-guide/blob/main/skills/figma-generate-library/scripts/createVariableCollection.js) handles this automatically by accepting an array of mode names and renaming the default to the first entry before creating additional modes.

### What is the difference between primitive and semantic variables?

**Primitive variables** store raw values (specific hex codes, base spacing units) and should have `scopes = []` to hide them from designers. **Semantic variables** reference primitives via `VARIABLE_ALIAS` objects created with `figma.variables.createVariableAlias()`, expose relevant scopes like `FRAME_FILL` or `GAP`, and often contain per-mode values pointing to different primitives. This separation enables centralized value management while presenting a clean, theme-aware interface to designers.

### How do I clean up variable collections programmatically?

Use the shared plugin data system to tag collections with unique identifiers during creation. The [`createVariableCollection.js`](https://github.com/figma/mcp-server-guide/blob/main/createVariableCollection.js) script sets `dsb_key` and `run_id` metadata via `setSharedPluginData()`. Before generating new tokens, query existing collections using `getSharedPluginData('dsb', 'key')` to match previous run IDs, then remove old collections to ensure idempotent script execution and avoid orphaned variables.