Migrating to Design Tokens
A guide to help you migrate your project to Design Tokens v2 and the new modes system. Covers removed color selectors and how to pick suitable replacements for them.
This document covers in detail how to work with color in design-tokens v2, and how to migrate from the previous system. If you are looking for a more general overview of the changes in the Autumn 2026 release, see our release notes.
Approach to applying color
Many of the concepts behind applying color in design-tokens v2 already existed in v1, but v1 still supported legacy color patterns through:
- theme-based selectors (imported from
@nib-components/theme) - color props on components mapping to theme values (such as
color="darkest"orbackground="brandBase")
Consumers were encouraged to apply color via modes, but the old approaches were still available and were not initially marked as deprecated. That made it hard for teams to know when they had fully moved to the new system, so many applications that adopted tokens still rely on legacy color usage somewhere.
In v2, these legacy approaches have been removed. Any existing usage needs to be refactored to use the new modes system and token values. This guide explains how.
There are two main ways to apply color:
- applying color via props on
Box(or other components that accept color props, such asCopyorHeading) - applying color via styled components, using either
- the
tokenfunction (named export from@nib-components/theme) - CSS custom properties directly
- the
Props on Box
Using Box props has a few advantages:
- quick to apply
- makes the purpose of the color clear (background, foreground, or border)
- gives you access to sentiment and prominence to further refine the color choice
<Box background="default" foreground="default" borderColor="default">...</Box>
Styled components/CSS
Via CSS, you only have access to the available token color options. You cannot set sentiment or prominence via CSS.
token function
const MyComponent = styled.div`background: ${token('theme.color.bg')};color: ${token('theme.color.fg')};border-color: ${token('theme.color.border')};`;
CSS custom properties
const MyComponent = styled.div`background: var(--themeColorBg);color: var(--themeColorFg);border-color: var(--themeColorBorder);`;
In both approaches, the token value is determined by the mode the component is rendered within.
<ModeProvider sentiment="sage" prominence="prominent"><MyComponent /><Box sentiment="hero" prominence="gentle"><MyComponent /></Box></ModeProvider>
The same MyComponent will render with different colors in each case, based on the surrounding mode. Box can also be used in place of ModeProvider.
Why has our approach changed?
When you choose a color token, you are not choosing a fixed color. You are choosing a color role, and each mode fills that role with the appropriate color. This makes the system more flexible and easier to scale.
Dark mode is a clear example of why this is important: you choose the same role, and the system automatically resolves it to the right dark-mode color. The same is true for sentiments and prominences: you choose the role, and the system automatically resolves it to the right color for that sentiment and prominence.
Because the token set is curated to work across modes, staying within the system helps maintain accessible color contrast. Choosing colors outside it increases the risk of accessibility issues.
Picking a suitable replacement for theme based selectors
Start by identifying how the color is being used: background, text, or border. Then choose from the corresponding token set.
Never use a color token for a purpose it was not designed for! The tokens have been carefully designed to maintain sufficient contrast between backgrounds and foregrounds across brands, sentiments, and prominences. Using a background token as a foreground color, or vice versa, is likely to create accessibility issues.
What if there is no direct replacement?
In the tables below, there are many cases where there is no direct replacement for the color you were using. When you encounter this, you will need to pick the closest available option and potentially adjust your design to accommodate the change in color.
Think semantically about the purpose of the color and choose a replacement that aligns with that purpose. If that is not clear, default is a safe starting point for background and foreground colors. Start there and adjust as needed.
If you find that there is a gap in the token set that makes it hard to find a suitable replacement, or you are unsure, please reach out to the mesh team to discuss potential solutions.
Background color
At a glance, the background token set looks limited, but it is designed to work with the modes system to produce a wide range of backgrounds. The available background tokens are:
defaulthover(reserved for hover states of interactive elements, should not be used as a static background color)transparent
Note: For each of these selectors, you might instead have been passing the color as a string prop to a component, such as
background="brandBase". In that case, replace the value withdefaultand ensure the component is wrapped in a mode that sets the background to the intended color, for examplehero.
| Before | After |
|---|---|
colorBrandBase | <Box sentiment="hero" background="default" foreground="default"> |
colorBrandDark | <Box sentiment="hero" prominence="gentle" background="default" foreground="default"> |
colorBrandLight | <Box sentiment="hero" background="prominent" foreground="default"> |
colorAccent | No direct replacement available. |
colorFocus | No direct replacement available. The focus color is reserved for focus states of interactive elements. Should not be used as a background color. |
colorWhite | <Box sentiment="default" background="default" foreground="default"> |
colorNearWhite | <Box sentiment="default" prominence="gentle" background="default" foreground="default"> |
colorLightest | <Box sentiment="default" prominence="gentle" background="default" foreground="default"> |
colorLighter | <Box sentiment="default" prominence="muted" background="default" foreground="default"> |
colorLight | No direct replacement available. |
colorDark | No direct replacement available. |
colorDarker | No direct replacement available. |
colorDarkest | No direct replacement available. |
colorBlack | No direct replacement available. |
colorHospital | No direct replacement available. |
colorExtras | No direct replacement available. |
colorCombined | No direct replacement available. |
colorHighlightBg | No direct replacement available. |
colorHighlightText | No direct replacement available. |
colorSuccess | <Box sentiment="positive" prominence="prominent" background="default" foreground="default"> Also other prominences available. |
colorInfo | <Box sentiment="informative" prominence="prominent" background="default" foreground="default"> Also other prominences available. |
colorError | <Box sentiment="negative" prominence="prominent" background="default" foreground="default"> Also other prominences available. |
colorWarning | <Box sentiment="cautionary" prominence="prominent" background="default" foreground="default"> Also other prominences available. |
colorTrueGreen | <Box sentiment="hero" prominence="default" background="default" foreground="default"> |
colorTrueGreen80 | No direct replacement available. |
colorTrueGreen60 | No direct replacement available. |
colorTrueGreen40 | No direct replacement available. |
colorTrueGreen20 | No direct replacement available. |
colorBrightGreen | <Box sentiment="hero" prominence="prominent" background="default" foreground="default"> |
colorBrightGreen80 | No direct replacement available. |
colorBrightGreen60 | No direct replacement available. |
colorBrightGreen40 | No direct replacement available. |
colorBrightGreen20 | No direct replacement available. |
colorSageGreen | <Box sentiment="sage" prominence="prominent" background="default" foreground="default"> |
colorSageGreen80 | <Box sentiment="sage" prominence="default" background="default" foreground="default"> |
colorSageGreen60 | <Box sentiment="sage" prominence="gentle" background="default" foreground="default"> |
colorSageGreen40 | <Box sentiment="sage" prominence="gentle" background="default" foreground="default"> |
colorSageGreen20 | <Box sentiment="sage" prominence="muted" background="default" foreground="default"> |
colorWarmWhite | <Box sentiment="warm" prominence="default" background="default" foreground="default"> |
colorWarmWhite80 | <Box sentiment="warm" prominence="default" background="default" foreground="default"> |
colorWarmWhite60 | <Box sentiment="warm" prominence="gentle" background="default" foreground="default"> |
colorWarmWhite40 | <Box sentiment="warm" prominence="gentle" background="default" foreground="default"> |
colorWarmWhite20 | <Box sentiment="warm" prominence="muted" background="default" foreground="default"> |
colorSunsetPink | <Box sentiment="sunset" prominence="default" background="default" foreground="default"> |
colorSunsetPink80 | <Box sentiment="sunset" prominence="default" background="default" foreground="default"> |
colorSunsetPink60 | <Box sentiment="sunset" prominence="gentle" background="default" foreground="default"> |
colorSunsetPink40 | <Box sentiment="sunset" prominence="gentle" background="default" foreground="default"> |
colorSunsetPink20 | <Box sentiment="sunset" prominence="muted" background="default" foreground="default"> |
Foreground color
Foreground colors have a substantially larger set of options to pick from:
defaultprominentgentlemutedbrandsentimenterrorsuccessinfowarningselected
Even with the expanded set of options compared to background colors, each of these tokens can still vary across sentiments/prominences.
Note: For each of these selectors, you might instead have been passing the color as a string prop to a component, such as
color="brandBase". In this case, you would replace the value withbrandand ensure that the component is wrapped in a mode that sets the foreground to the appropriate color for that mode.
Whilst we are updating foreground colors, note that the
colorprop onBoxhas been renamed toforegroundto better reflect the purpose of the prop.
| Before | After |
|---|---|
colorBrandBase | <Box foreground="brand"> |
colorBrandDark | <Box foreground="brand"> |
colorBrandLight | <Box foreground="brand"> |
colorAccent | No direct replacement available. |
colorFocus | No direct replacement available. The focus color is reserved for focus states of interactive elements. Should not be used as a foreground color. |
colorWhite | <Box foreground="white">. This is one non-mode aware value. It is literally #ffffff. Very risky to use alongside a variable background. |
colorNearWhite | No direct replacement available. |
colorLightest | No direct replacement available. |
colorLighter | No direct replacement available. |
colorLight | No direct replacement available. |
colorDark | <Box foreground="muted"> |
colorDarker | <Box foreground="gentle"> |
colorDarkest | <Box foreground="default"> |
colorBlack | <Box foreground="black">. This is one non-mode aware value. It is literally #000000. Very risky to use alongside a variable background. |
colorHospital | No direct replacement available. |
colorExtras | No direct replacement available. |
colorCombined | No direct replacement available. |
colorHighlightBg | No direct replacement available. |
colorHighlightText | No direct replacement available. |
colorSuccess | <Box foreground="success"> |
colorInfo | <Box foreground="info"> |
colorError | <Box foreground="error"> |
colorWarning | <Box foreground="warning"> |
colorTrueGreen | <Box foreground="brand"> |
colorTrueGreen80 | No direct replacement available. |
colorTrueGreen60 | No direct replacement available. |
colorTrueGreen40 | No direct replacement available. |
colorTrueGreen20 | No direct replacement available. |
colorBrightGreen | No direct replacement available. |
colorBrightGreen80 | No direct replacement available. |
colorBrightGreen60 | No direct replacement available. |
colorBrightGreen40 | No direct replacement available. |
colorBrightGreen20 | No direct replacement available. |
colorSageGreen | No direct replacement available. |
colorSageGreen80 | No direct replacement available. |
colorSageGreen60 | No direct replacement available. |
colorSageGreen40 | No direct replacement available. |
colorSageGreen20 | No direct replacement available. |
colorWarmWhite | No direct replacement available. |
colorWarmWhite80 | No direct replacement available. |
colorWarmWhite60 | No direct replacement available. |
colorWarmWhite40 | No direct replacement available. |
colorWarmWhite20 | No direct replacement available. |
colorSunsetPink | No direct replacement available. |
colorSunsetPink80 | No direct replacement available. |
colorSunsetPink60 | No direct replacement available. |
colorSunsetPink40 | No direct replacement available. |
colorSunsetPink20 | No direct replacement available. |
For each of the suggestions above being set on Box, you could also apply the same token values to any other component that accepts a color prop, such as Copy or Heading. You could also apply the same token values to a styled component:
const MyErrorComponent = styled.div`color: ${token('theme.color.fg.error')};`;
Border color
Border colors take a similar approach to foreground colors, with tokens for prominence within the neutral palette (default, prominent, gentle and muted), as well as tokens for more semantic purposes (brand, error, success, info, warning, selected and sentiment). In addition, we have a focus border color that is reserved for focus states of interactive elements, an input border color that is used for form controls and some product-specific border colors (productBasic, productBronze, productSilver, productGold, productHospital, productExtras and productCombined).
Note: For each of these selectors, you might instead have been passing the color as a string prop to a component, such as
borderColor="brandBase". In this case, you would replace the value withbrandand ensure that the component is wrapped in a mode that sets the border color to the appropriate color for that mode.
| Before | After |
|---|---|
colorBrandBase | <Box borderColor="brand" /> |
colorBrandDark | <Box borderColor="brand" /> |
colorBrandLight | <Box borderColor="brand" /> |
colorAccent | No direct replacement available. |
colorFocus | <Box borderColor="focus" /> |
colorWhite | <Box borderColor="white" /> |
colorNearWhite | No direct replacement available. |
colorLightest | No direct replacement available. |
colorLighter | No direct replacement available. |
colorLight | No direct replacement available. |
colorDark | <Box borderColor="muted" /> |
colorDarker | <Box borderColor="gentle" /> |
colorDarkest | <Box borderColor="default" /> |
colorBlack | <Box borderColor="prominent" /> |
colorHospital | <Box borderColor="productHospital" /> |
colorExtras | <Box borderColor="productExtras" /> |
colorCombined | <Box borderColor="productCombined" /> |
colorBasic | <Box borderColor="productBasic" /> |
colorBronze | <Box borderColor="productBronze" /> |
colorSilver | <Box borderColor="productSilver" /> |
colorGold | <Box borderColor="productGold" /> |
colorHighlightBg | No direct replacement available. |
colorHighlightText | No direct replacement available. |
colorSuccess | <Box borderColor="success" /> |
colorInfo | <Box borderColor="info" /> |
colorError | <Box borderColor="error" /> |
colorWarning | <Box borderColor="warning" /> |
colorTrueGreen | <Box borderColor="brand" /> |
colorTrueGreen80 | No direct replacement available. |
colorTrueGreen60 | No direct replacement available. |
colorTrueGreen40 | No direct replacement available. |
colorTrueGreen20 | No direct replacement available. |
colorBrightGreen | No replacement available in light mode. |
colorBrightGreen80 | No direct replacement available. |
colorBrightGreen60 | No direct replacement available. |
colorBrightGreen40 | No direct replacement available. |
colorBrightGreen20 | No direct replacement available. |
colorSageGreen | No direct replacement available. |
colorSageGreen80 | No direct replacement available. |
colorSageGreen60 | No direct replacement available. |
colorSageGreen40 | No direct replacement available. |
colorSageGreen20 | No direct replacement available. |
colorWarmWhite | No direct replacement available. |
colorWarmWhite80 | No direct replacement available. |
colorWarmWhite60 | No direct replacement available. |
colorWarmWhite40 | No direct replacement available. |
colorWarmWhite20 | No direct replacement available. |
colorSunsetPink | No direct replacement available. |
colorSunsetPink80 | No direct replacement available. |
colorSunsetPink60 | No direct replacement available. |
colorSunsetPink40 | No direct replacement available. |
colorSunsetPink20 | No direct replacement available. |
Appendix
List of removed color selectors
A complete list of color selectors that are no longer available in v2 is as follows:
- colorBrandBase
- colorBrandDark
- colorBrandLight
- colorAccent
- colorFocus
- colorWhite
- colorNearWhite
- colorLightest
- colorLighter
- colorLight
- colorDark
- colorDarker
- colorDarkest
- colorBlack
- colorHospital
- colorExtras
- colorCombined
- colorHighlightBg
- colorHighlightText
- colorSuccess
- colorInfo
- colorError
- colorWarning
- colorTrueGreen
- colorTrueGreen80
- colorTrueGreen60
- colorTrueGreen40
- colorTrueGreen20
- colorBrightGreen
- colorBrightGreen80
- colorBrightGreen60
- colorBrightGreen40
- colorBrightGreen20
- colorSageGreen
- colorSageGreen80
- colorSageGreen60
- colorSageGreen40
- colorSageGreen20
- colorWarmWhite
- colorWarmWhite80
- colorWarmWhite60
- colorWarmWhite40
- colorWarmWhite20
- colorSunsetPink
- colorSunsetPink80
- colorSunsetPink60
- colorSunsetPink40
- colorSunsetPink20