Figma Variables for Theming: One Collection with Light and Dark Modes
Use one Figma Variable collection with Light and Dark modes for theming. A single semantic token like color/primary resolves per mode without duplicating components, with clear limits and common engineering mistakes to avoid.
05 Dec 2025, 03:08 UTC

Stop duplicating components for dark mode
The practical engineering decision with Figma Variables is to model a theme as modes inside one collection, not as separate collections or duplicated components. A single component referencing color/primary resolves to different values in Light and Dark without edits to the component.
That is the useful takeaway: one semantic token, one collection, multiple modes. The file’s active mode per collection drives resolution.
How resolution works
Variables are named, typed tokens - Color, Number, String, Boolean - organized in collections. Each collection can have named modes. Resolution is collection-scoped and mode-aware.
When a property uses a variable, Figma resolves the value for the active mode of that collection. If a mode value is missing, Figma falls back to the collection’s default mode. Variables can reference other variables, but only within the same collection, and references are resolved at read time.
Mode switching is per collection, not global. A file can have Brand in Dark and Spacing in Light at the same time. That is important for engineering handoff because the resolved value depends on which collection mode is active in the file.
Worked configuration for Light/Dark color token
Use this as a reference setup for a design system library.
Create a Variable collection named Brand. Add two modes: Light and Dark. Set Light as the default mode.
Create a Color variable with name color/primary and type Color. In the Variables panel, set the value for Light mode to #0A84FF and for Dark mode to #409CFF. The name is semantic, not value-based.
Apply the variable to a frame fill via the Fill picker in the right sidebar, then choose Variables. The fill now references color/primary. Switching the active mode in the Variables panel previews the resolution without editing the component.
In the API representation, the variable is stored with resolved values per mode id. The UI shows the mode switcher for preview; the API reflects the same per-mode mapping.
Verification steps you can run in a file with Variables enabled: create the collection and modes, bind a fill to color/primary, toggle the collection mode in the Variables panel and confirm the fill updates. Inspect a component using the variable and change the file’s active mode to verify resolution changes without editing the component. Check the Variables panel for warnings about missing mode values or duplicate names to confirm fallback behavior.
Limits to plan for
Performance degrades with thousands of variables in a file. Keep collections focused and avoid creating a variable for every one-off value.
Mode switching is per collection. There is no global theme switch that changes all collections at once. Teams need a documented convention for which collections are theme-related and how modes are named.
Variables cannot be conditionally applied based on component state or variants. A Boolean prop cannot switch a variable on and off. The variable reference is static on the property.
Variable names must be unique within a collection. Renaming a variable in a large library can break references. Treat renames as breaking changes and coordinate with engineering.
Behavior is version-sensitive. Variables and mode resolution changed after initial launch and continues to evolve. UI capabilities may exceed the REST API, and API shape can differ from the UI.
Common mistakes and how to avoid them
Creating separate collections per theme fragments sync. Two collections Brand-Light and Brand-Dark diverge over time and make publishing harder. Use one collection with modes.
Using flat, value-based names like primary-blue instead of semantic color/primary couples the token to a specific hue. Semantic names survive palette changes and map cleanly to code tokens.
Forgetting to publish the collection to the library causes local overrides. Local edits diverge from the source of truth and are not pushed to consuming files. Publish and version the collection, and document the owner.
Missing mode values lead to silent fallback to default mode. Audit the Variables panel for warnings and ensure every token has an explicit value for each shipped mode.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.