Building a Scalable Design System in Figma with Variables and Dev Mode
Learn how to set up a Figma Variables library for scalable design tokens, support light/dark modes, and hand off to developers with Dev Mode or the Variables API. Follow the step‑by‑step guide and checklists for a smooth workflow.
16 Mar 2026, 16:42 UTC

Desired Outcome
By the end of this guide you will have a single, version‑controlled Figma library that exposes design tokens—colors, spacing, typography, radii—as Variables. The library will support multiple visual modes (Light, Dark, High‑Contrast) and will be consumable by developers through Dev Mode or the Variables API. When a primitive value changes, all semantic aliases and mode overrides update automatically, keeping design and code in sync.
Prerequisites
- Figma Professional or Organization plan (Variables are only available on paid tiers).
- Edit access to a team library file (the "Tokens" file).
- Basic familiarity with design token concepts: primitive (raw value) vs. semantic (meaningful name).
- Optional: Figma CLI or a token‑export plugin if you want automated JSON exports.
Step‑by‑Step Procedure
- Create the Tokens Library
- File → New → Team Library.
- Name it
Design‑Tokensand add a descriptive description. - Ensure the file is set to "Publish as Library".
- Define Primitive Collections
- Open the Assets panel, click the Variables tab.
- Create a new collection:
Color/Primitive.- Add variables like
Primary‑Base(value #0052CC),Secondary‑Base(#FF4081). - Set the variable type to Color and enter the hex value.
- Add variables like
- Repeat for
Spacing/Primitive,Typography/Primitive, etc., using the appropriate variable type (Number, Font, Radius).
- Create Semantic Collections
- Make a new collection:
Color/Semantic. - When adding a variable, click the Equals (=) picker and choose the primitive you want to alias. For example,
Button‑Background=Primary‑Base. - Repeat for all semantic names:
Text‑Primary,Border‑Accent, etc. - For spacing, create
Spacing/Semanticand alias primitives likePadding‑Small=8(spacing primitive).
- Make a new collection:
- Configure Modes
- In the Variables panel, click + Mode and add
Light,Dark,High‑Contrast. - Modes are scoped per collection. Add the same mode names to every semantic collection you created.
- To override a value in a mode, select the semantic variable, click the mode dropdown, and enter the new value. For example,
Primary‑BaseinDarkmode becomes #0A84FF. - Primitive overrides are optional; if you only want semantic overrides, leave primitives unchanged.
- In the Variables panel, click + Mode and add
- Publish the Library
- File → Publish as Library. Confirm that all collections and modes are included.
- Note the library’s file key (e.g.,
abcd1234) for API access.
- Consume Tokens in Design Files
- Open or create a consumer file (e.g.,
UI‑Components). - File → Team Library → Enable
Design‑Tokens. - In the Assets panel, switch to the Variables tab. You’ll see the semantic collections.
- Apply a semantic variable to a style: select a frame, click the fill color picker, choose Variable, and pick
Button‑Background. - Change the file’s mode via the right‑hand sidebar (Light/Dark). The applied variable updates automatically.
- Open or create a consumer file (e.g.,
- Developer Handoff via Dev Mode
- Enable Dev Mode in the consumer file (File → Dev Mode).
- Select a layer with a variable applied.
- The Inspect panel now shows a CSS custom property reference, e.g.,
var(--color-button-background). - Developers can copy the CSS declaration or use the
Variables APIendpointGET /v1/files/:file_key/variables/localto retrieve the entire token set in JSON.
Expected Checks
- Propagation Test: Change
Primary‑BaseinColor/Primitiveand verify that all semantic aliases (e.g.,Button‑Background) update in all consumer files. - Mode Switch Test: In a consumer file, toggle the mode and confirm that layers using semantic variables reflect the correct override.
- API Validation: Call the Variables API and inspect the JSON. Each variable should have
name,value,type, andmodesfields. - Dev Mode Inspection: In Dev Mode, the Inspect panel must display the variable name and the resolved CSS custom property.
Recovery Options
- Variable Rename Breakage: If renaming a variable breaks references, open the Manage Variables modal, use the Re‑alias button to map the old name to the new one, or revert the rename.
- Deleted Mode: Restore a removed mode from the file’s version history (File → Version History). Figma keeps 30 days of history on paid plans.
- Large Token Set Performance: If the Variables panel lags, split the library into domain‑specific files (e.g.,
Colors‑Tokens,Spacing‑Tokens) and publish them separately. - API Versioning: For continuous integration, tag the token export endpoint with a version number and maintain a changelog so engineers know when to update their consumption logic.
Concrete Example: Light/Dark Color Override
Assume we have a primitive Primary‑Base set to #0052CC (Light) and #0A84FF (Dark). The semantic variable Button‑Background aliases Primary‑Base. In a consumer file:
/* Light mode */
.button {
background-color: var(--color-button-background);
}
/* Dark mode */
[data-theme="dark"] .button {
background-color: var(--color-button-background);
}
When the user toggles the theme, the CSS variable automatically resolves to the correct mode value.
Limitations & Practical Checks
- Variable aliasing works only within the same file or across published libraries. Ensure the target file has the source library enabled.
- Modes are per‑collection; you must add the same mode names manually to each semantic collection.
- The Variables API returns raw values; it does not resolve mode overrides. Your consumer code must apply the correct mode logic.
- Large token sets (>1,000 variables) can degrade performance. Monitor the Variables panel and consider modularizing the library.
Conclusion
By structuring your design tokens as Figma Variables, you gain a single source of truth that automatically propagates changes, supports multiple visual modes, and offers a clean handoff to developers via Dev Mode or the Variables API. This workflow keeps designers and engineers aligned, reduces friction, and scales as your product grows.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.