A CSS variable exists within the boundaries of one project and one language. If you have five products on different stacks — React, Swift, Kotlin — you will have to manually duplicate the variables in each repository, and desynchronization is guaranteed within just a few sprints. A token is described in a neutral JSON format (the W3C Design Tokens Community Group standard with fields $value and $type) and is automatically translated into the appropriate syntax for each platform.
Practical effect: a primitive token blue-500 = #335CFF changes only once in the source. This automatically propagates the change to all semantic tokens that reference it — bg-primary, text-link — and to all components that use those semantic tokens. No one searches for the color throughout the codebase or manually renames hundreds of files.
The classic scheme is three levels: primitive, semantic, and component. But in real product companies, it's a bit more complex, especially when it comes to multiple brands under one umbrella.
| Level | What it describes | Example |
|---|---|---|
| Primitive (Ref) | Raw values without meaning | blue-500 = #335CFF |
| Semantic (Sys) | Purpose in the interface | bg-primary → blue-500 |
| Component | Implementation in a specific UI element | button-primary-bg → bg-primary |
| Brand | Approved variations for each brand | brand-b-button-bg → own reference to Ref |
The fourth, brand level is needed only in white-label or multi-brand systems, where one code serves several visual identities. If you have one product — don't drag it artificially, this is extra complexity without benefit.
VK Tech transitioned to tokens not out of love for trends, but due to a specific pain point: developers spent hours adjusting colors and spacing from Figma mocks to pixels in code, and any theme change required manual correction of dozens of components. After implementation, the transfer of UI from design to code accelerated — what used to be a routine manual check of values is now just a couple of clicks for the designer to modify tokens and pass them to the frontend.
An interesting move worth noting — support for both light and dark themes with a single base of components. The components were not rewritten at all: the team simply renamed the semantic token values within one theme to another. The component layer remained unchanged, only the layer of meaning shifted — this is the essence of a three-tier architecture in practice, not just theory.
Technically, the linkage between design and development is usually built like this:
It works exactly as advertised, provided the team has discipline: token modifications are made only through this pipeline, not via spot fixes in CSS 'on the fly' — otherwise the source of truth ceases to be the source of truth within a month.
This is the part that almost all articles about tokens skip — the organizational aspect. Technically, implementing Style Dictionary takes a week. The harder question is: who decides what blue-500 changes to blue-600, and how the fifteen product teams are informed about it.
Implementing tokens from scratch at a stage when the product does not yet exist or the UI changes every week is a bad idea: the system will be rewritten faster than it can bring benefit. A reasonable entry point is the moment when the product has at least 15-20 reusable components and a second product or platform is on the way.
Sberbank and VK in this sense show the correct sequence: first, a two-level system is launched — primitives plus semantics (Ref + Sys). The component level is added later, when there is a real need for flexibility under platform-specific features or white-label options. Building four levels at once for a single product without multi-branding is a typical overcomplication that slows down the team, rather than accelerating it.
Poor naming kills even a perfectly designed token system — the developer simply won't find the required token and will hardcode the value. The W3C standard with its fields allowed tools to generate names using an object-oriented approach: first the object, then its property. Hence the rule — $value and $type allowed tools to generate names using an object-oriented approach: first the object, then its property. From this comes the rule — button-primary-bg-color, and not color-button-bg-primary.
The difference is not cosmetic. The first variant is grouped in the IDE autocomplete by component — when you start typing 'button', you see all its tokens at once. The second variant is grouped by the type of value, which is convenient only for color designers, but inconvenient for 90% developers who think in terms of components, not palettes.
A CSS variable exists within the boundaries of one project and one language. If you have five products on different stacks — React, Swift, Kotlin — you will have to manually duplicate the variables in each repository, and desynchronization is guaranteed within just a few sprints. A token is described in a neutral JSON format (the W3C Design Tokens Community Group standard with fields $value and $type) and is automatically translated into the appropriate syntax for each platform.
Practical effect: a primitive token blue-500 = #335CFF changes only once in the source. This automatically propagates the change to all semantic tokens that reference it — bg-primary, text-link — and to all components that use those semantic tokens. No one searches for the color throughout the codebase or manually renames hundreds of files.
The classic scheme is three levels: primitive, semantic, and component. But in real product companies, it's a bit more complex, especially when it comes to multiple brands under one umbrella.
| Level | What it describes | Example |
|---|---|---|
| Primitive (Ref) | Raw values without meaning | blue-500 = #335CFF |
| Semantic (Sys) | Purpose in the interface | bg-primary → blue-500 |
| Component | Implementation in a specific UI element | button-primary-bg → bg-primary |
| Brand | Approved variations for each brand | brand-b-button-bg → own reference to Ref |
The fourth, brand level is needed only in white-label or multi-brand systems, where one code serves several visual identities. If you have one product — don't drag it artificially, this is extra complexity without benefit.
VK Tech transitioned to tokens not out of love for trends, but due to a specific pain point: developers spent hours adjusting colors and spacing from Figma mocks to pixels in code, and any theme change required manual correction of dozens of components. After implementation, the transfer of UI from design to code accelerated — what used to be a routine manual check of values is now just a couple of clicks for the designer to modify tokens and pass them to the frontend.
An interesting move worth noting — support for both light and dark themes with a single base of components. The components were not rewritten at all: the team simply renamed the semantic token values within one theme to another. The component layer remained unchanged, only the layer of meaning shifted — this is the essence of a three-tier architecture in practice, not just theory.
Technically, the linkage between design and development is usually built like this:
It works exactly as advertised, provided the team has discipline: token modifications are made only through this pipeline, not via spot fixes in CSS 'on the fly' — otherwise the source of truth ceases to be the source of truth within a month.
This is the part that almost all articles about tokens skip — the organizational aspect. Technically, implementing Style Dictionary takes a week. The harder question is: who decides what blue-500 changes to blue-600, and how the fifteen product teams are informed about it.
Implementing tokens from scratch at a stage when the product does not yet exist or the UI changes every week is a bad idea: the system will be rewritten faster than it can bring benefit. A reasonable entry point is the moment when the product has at least 15-20 reusable components and a second product or platform is on the way.
Sberbank and VK in this sense show the correct sequence: first, a two-level system is launched — primitives plus semantics (Ref + Sys). The component level is added later, when there is a real need for flexibility under platform-specific features or white-label options. Building four levels at once for a single product without multi-branding is a typical overcomplication that slows down the team, rather than accelerating it.
Poor naming kills even a perfectly designed token system — the developer simply won't find the required token and will hardcode the value. The W3C standard with its fields allowed tools to generate names using an object-oriented approach: first the object, then its property. Hence the rule — $value and $type allowed tools to generate names using an object-oriented approach: first the object, then its property. From this comes the rule — button-primary-bg-color, and not color-button-bg-primary.
The difference is not cosmetic. The first variant is grouped in the IDE autocomplete by component — when you start typing 'button', you see all its tokens at once. The second variant is grouped by the type of value, which is convenient only for color designers, but inconvenient for 90% developers who think in terms of components, not palettes.