design tools

Primitive Layer

The primitive layer forms the bedrock of any Figma variable system built to last. It contains nothing but raw unchanging values. Hex colors sit here as blue-500 set to #0066FF or red-600 set to #e02c2c. Spacing scales live here as space-2 set to 8 and space-12 set to 48. Radius values appear as radius-sm set to 4 and radius-full set to 999. These primitives never reference other tokens. They hold literal values only. Everything else in the system builds on top by aliasing to these primitives. The semantic layer translates these raw values into meaning. The component layer then scopes that meaning to specific UI elements. This strict downward reference chain is what lets you introduce dark mode or a new brand without touching hundreds of layers or components. Primitives stay out of the way. They live in their own collection. Designers never touch them after the initial setup. That separation is the entire point. Naming follows a rigid scale based convention. Blue-100 through blue-900. Neutral-0 through neutral-1000. These names describe the value itself not its eventual use. Any name that sounds like it belongs on a button or in a notification breaks the system from day one.

The primitive layer is not your everyday color picker. It is not filled with tokens named after their purpose like link-blue or alert-red. Those names create semantic tokens one layer up. The primitive layer is not something you apply to frames, buttons, or text layers in your Figma files. Doing so bypasses the entire architecture and leaves you with a style system wearing token clothing. It is not the place for modes of any kind. Light dark and brand modes belong exclusively in the semantic collection. A primitive called blue-500 does not change its value. It remains constant. Changing the resolved color for text links happens when the semantic token text-link switches which primitive it points to. Mixing modes into primitives creates alias chains that break when you least expect it and turns debugging into detective work. The primitive layer is not optional. Skip it and your system turns into a house of cards the moment requirements change. It is not a flexible free for all where tokens can reference each other in loops or cross collection chaos. Primitives stand alone as the source.

Concrete example. In 2023 Shopify rebuilt their Polaris design system using this exact model. Their primitive collection contained 14 shades of gray starting at gray-50 with #fafafa and ending at gray-950 with #161618. They added brand primitives for the Shopify green scale plus supporting colors for orange purple and red. Spacing primitives followed a 4 pixel base scale with tokens from space-025 at 1px all the way to space-10 at 40px. Every radius value from 2px to full pill shapes lived in the primitives collection. All of these were scoped to none so they disappeared from the variables apply menu. Semantic tokens like background-default aliased to gray-50 in light mode and gray-950 in dark mode. Text tokens followed the same pattern. Component tokens for the Polaris button used button-primary-background which aliased to the semantic background-action token. When Shopify launched a new experimental brand for their enterprise product in early 2024 they added one mode to the semantic collection. The primitive collection stayed completely untouched. Buttons updated. Cards updated. The entire interface shifted to the new brand colors in seconds instead of days. IBM Carbon followed a similar approach in their 2022 refresh. Primitives used exact CIE values for color accuracy across platforms. Semantic mappings created the roles. Component tokens for complex data tables referenced those roles. The system supported four different product brands without any primitive duplication. Contrast this with teams that treat Figma variables like upgraded styles. They stuff raw values into component tokens directly. When dark mode arrives they face hundreds of manual updates and inconsistent color application. The primitive layer prevents that pain entirely. Stripe ran the same setup in 2023 with their checkout components. Their primitives collection held exact rem values for spacing and motion durations. Tokens Studio exported them nightly to JSON that fed Style Dictionary. The result was zero drift between Figma and the React codebase even after three major brand updates.

Use the primitive layer in every production design system that expects to support multiple themes or handoff to engineering. Start with it when you have more than one product or when dark mode is on the roadmap. Build it when you want to enforce consistency across 50 plus components. Maintain it as the single source of truth for all raw decisions. Update a primitive once and watch the change propagate safely through semantic references. Deploy it when your current file contains scattered hard coded colors that no one can track. Use it so your Tokens Studio export produces clean JSON that Style Dictionary can transform into platform specific code without extra cleanup steps. Do not use the primitive layer for one off mockups or personal side projects with no theming needs. The structure adds unnecessary clicks in those cases. Skip it when your team has zero plans to export tokens to code or when the project dies after one launch. Never reach for primitives when building components no matter how tempting a quick gray-900 feels. That path leads to systems that cannot adapt when the brand lead changes the primary blue from #0066FF to a new OKLCH based value. The teams that ignore this rule find themselves rewriting their entire Figma library the first time product requests a color update. Audit your file against the primitive rules weekly until the discipline sticks. The power of the primitive layer shows clearest during brand refreshes. Your marketing team decides the primary blue no longer works in 2025. You update the primitive blue-500 once. Semantic tokens like surface-primary and text-link that point to it update automatically. Component tokens stay pristine. The same happens with spacing. Change your base unit in the primitive layer and every semantic spacing token reflects the new scale. This is how systems at Stripe and Atlassian survive multiple annual updates without full rebuilds.

Primitives are the quiet foundation that prevents your entire token system from collapsing the moment someone asks for dark mode.

Related terms

Keep exploring