Skip to content
Autumn 2026 Mesh Release and Design Tokens v2 now available! Read the announcement

Design tokens for React

How to work with tokens and react.

Mesh's design tokens are authored in the @nib-group/design-tokens repo using a tool called Style Dictionary. Style Dictionary allows us to have a single source of truth for tokens, and their values, defined in JSON. These token definitions are then used to generate many different formats to support different platforms and tech stacks.

In react, our preferred format for design tokens is CSS Custom Properties.

Using tokens

The design tokens are available directly via the @nib-group/design-tokens npm package. However, within React applications it is easier to access tokens via the @nib-group/mesh-theme package and its token function, for custom styling worker, or via provided props on mesh components.

Many mesh components have been updated to consume design tokens for properties such as color, spacing and border radii. By updating to the latest version of @nib-group/mesh-theme you can take advantage of these changes with minimal effort.

The Box component

The Box component has been updated to support tokenised values for background, foreground and borderColor. Padding, margin and border radius values also now pull directly from tokens.

jsx
<Box background="default" foreground="prominent" padding={4} borderRadius="small">
<Copy>All powered by tokens!</Copy>
</Box>

The old, non-tokenised values are no longer supported and should be updated to use tokens:

diff
- <Box background="brandBase" foreground="nearWhite">
- <Copy>Still works for compatibility reasons</Copy>
- </Box>
+ <Box sentiment="hero" background="default" foreground="gentle">
+ <Copy>Now with updated token-based colors</Copy>
+ </Box>

Box also allows for setting sentiment and prominence props directly on the element, instead of adding a wrapping ModeProvider.

Other components that are built on top of Box, or use the same props to allow you to pick a foreground or background value also have token support. These include:

  • Section
  • Heading
  • Copy

Token function

When creating any custom component, the token function is the recommended way to access tokens. It should be used within your css declarations for a styled-component:

jsx
import styled, {css} from 'styled-components';
export const Wrapper = styled.div`
background-color: ${token('theme.color.bg', '#f2f2f2')}; // string fallback
color: var(--themeColorFg);
padding: ${token('common.dimension.spacing.6')};
`;

The token function is typed to enable autocomplete and typescript errors when invalid token paths are provided.

The token function has a second parameter to provide a fallback value if the token cannot be found for whatever reason. During the initial migration to tokens it is recommended that fallbacks be provided for all token references.

See the token function docs for more information.

ModeProvider

The tokens release brings about a new concept of "modes". Like brands (themes), modes are a way to switch between different sets of tokens. For example, a "feature" mode might have a different color palette to the "default" mode. The ModeProvider component is used to set the mode for a section of your app.

The mesh ThemeProvider component has been updated to have a nested ModeProvider with a mode value of "default".

jsx
import ThemeProvider, { ModeProvider } from '@nib-group/mesh-theme';
import nib from '@nib-group/mesh-theme/brand/nib';
const App = () => (
<ThemeProvider theme={nib}>
<main>
<Columns space={4} collapseBelow="md">
<Column width="2/3">
Main content here
</Column>
<Column width="1/3">
<ModeProvider sentiment="hero" prominence="default">
<Box background="default" color="prominent">
<Copy>This box and text is in the feature mode.</Copy>
</Box>
</ModeProvider>
</Column>
</Columns>
</main>
</ThemeProvider>
);

ModeProvider can be nested within other ModeProvider's to allow for different modes to be set at different levels of your component tree. The mode prop can be set to a string to apply for all brands, or an object to apply for specific brands. If you have many brands to support, we have a special key of rest which will apply to any brand not set in the dictionary:

jsx
import { ModeProvider } from '@nib-group/mesh-theme';
const App = () => (
<ModeProvider sentiment="default" prominence="default">
<Box background="default" color="prominent">
<Copy>This box and text is in the feature mode.</Copy>
</Box>
</ModeProvider>
);

Theme selectors

Up until recently, the correct approach to styling custom components was to use the selectors exported from our theme package.

jsx
const Wrapper = styled.div`
background-color: ${colorBrandBase};
color: ${colorWhite};
`;

With the introduction of tokens, this has changed. Color selectors have been removed from the theme package. If you are using any of the removed selectors, you will need to update your code to use tokens instead.

jsx
import { token } from '@nib-group/mesh-theme';
const Wrapper = styled.div`
background-color: ${token('theme.color.bg')};
color: ${token('theme.color.fg')};
`;

Spacing utilities like p(4) and m(4) pull from the spacing scale tokens and do not need to be modified in your code base:

jsx
import {p, mb} from '@nib-group/mesh-layout';
const Wrapper = styled.div`
${p(4)};
${mt(2)};
${mb({xs: 4, md: 6})};
`;

Resources