Tutorial
Dynamic theming in React using IBM Carbon
Implement dynamic theming in React applications using IBM Carbon React Library, including system-based and custom theme switchingIn today’s UI landscape, theming is essential for ensuring that applications align seamlessly with brand aesthetics and user preferences. With modern browsers and operating systems providing built-in support for light and dark modes, it is essential for UI teams to ensure their applications can adapt accordingly.
This tutorial explores theming with IBM Carbon Design System, a powerful tool designed to streamline theming for React applications. Learn how to use Carbon’s theming capabilities to meet diverse application requirements.
IBM Carbon Design System
Carbon is a IBM open-source design system that offers a comprehensive foundation for creating consistent, user-friendly digital experiences. Built on the IBM Design Language, Carbon provides:
- Usable code: Ready-made React components and utilities for rapid development.
- Design tools and resources: Assets, templates, and guidelines to maintain design consistency.
- Human interface guidelines: Clear principles for user experience optimization.
- Active community: A network of contributors for collaboration and support.
For more details, refer to the IBM Carbon Design System.
Theming for React frontend applications using IBM Carbon Design System
Now that we understand the importance of theming, let’s set up a theme using the Carbon Design System.
There are a few terminologies related to the library that we need to understand before proceeding:
- Theme: The aesthetic you want to apply to your application.
- Token: The series of color tokens that enable the aesthetic for UI elements.
- Role: The schematic way in which tokens should be applied.
- Value: The actual hex code assigned to the token.
For more inforation, refer to IBM Carbon themeing basics.
Integrate theming into your React application using @carbon/react
Note: @carbon/react is available only in v11 of Carbon package.
Prerequisites
This tutorial assumes you have a React project set up and are familiar with React front-end development. We will use the React boilerplate,
create-react-app, with a few tweaks covered in the steps below.For demonstration purposes, we are using macOS and Visual Studio Code as the IDE, but the principles apply to any React application.
Setting up boilerplate for Theming
Create a React Project. Refer to Create React App for detailed instructions.
npx create-react-app carbon-theming-demo cd carbon-theming-demoInstall Carbon Libraries.
npm install @carbon/reactRemove or rename existing
.cssfiles to.scss. If you want to preserve existing styles, carefully integrate Carbon’s SCSS styles. We’ll demonstrate by creating a new SCSS file:@use '@carbon/react/scss/themes' as *; @use '@carbon/styles';
Theming approaches
With the above setup, there are different ways in which each application can implement theming:
- Default OS/browser preference: The application should behave according to accessibility requirements when using the default OS/browser preference.
- Controlled theme switching: Theme switching should be under the control of the application and not based on OS/browser settings.
- Automatic theme token application: Components should automatically pick up theme tokens when using the Carbon Design System.
- Custom theme token usage: Customize the theme token usage within components based on the theme switcher.
This tutorial covers how to implement each of these approaches in your application using the IBM Carbon React package.
Using system preferences for theme switching
In many cases, you’ll want your application to adapt to the user’s system-defined light or dark mode preference as the default theming behavior. Carbon makes this easy. Add the following code to your entry point SCSS file:
:root {
@include themes.theme($white); /*Set default to white theme*/}
@media (prefers-color-scheme: dark) {
:root {
@include themes.theme($g100); /*Use dark theme for dark system preference*/}}
This code ensures your application starts in Carbon’s white theme and switches to the dark theme ($g100) if the user’s system prefers dark mode. On macOS, you can change your preferred theme in System Settings -> Appearance. You can also update your browser-specific theme, for example, in Chrome, go to Settings -> Appearance -> Mode and change it to Dark.
After implementing the above code, launch your application to see the theming in effect.
Carbon theming in detail
Carbon offers four base themes:
- White
- Gray 10
- Gray 90
- Gray 100
These themes use appropriate color tokens to support various color contrasts as per accessibility requirements. Additionally, custom theming can be implemented using the Carbon Design System . For more details, visit the IBM Carbon Design System.
Leveraging Carbon React components
Carbon’s React components automatically adapt to the active theme based on your system preferences or custom theming logic. Let’s see this in action:
Explore Carbon React storybook: The Carbon Design System offers a variety of pre-designed components to simplify frontend development. Browse the Carbon React Storybook to find examples of component usage and incorporate them into your application.
Import and use components: In the following source code example, we are importing form and its related components from
@carbon/reactinto the entry point file,App.js, with the necessary attributes.import { FormGroup, Stack, TextInput, RadioButtonGroup, RadioButton, Button } from '@carbon/react'; function App() { return ( <> <header> <title>Carbon Theming</title> </header> <body className="App-header"> <FormGroup className="form" legendText="Personal Details"> <Stack gap={7}> <TextInput id="fn" labelText="First Name" /> <TextInput id="ln" labelText="Last Name" /> <RadioButtonGroup legendText="Gender" name="gender-radio" defaultSelected="g1" > <RadioButton labelText="Male" value="M" id="g1" /> <RadioButton labelText="Female" value="F" id="g2" /> <RadioButton labelText="Other" value="O" id="g3" /> <RadioButton labelText="Doesn't Want to Mention" value="N" id="r4" /> </RadioButtonGroup> <Button>Submit</Button> </Stack> </FormGroup> </body> </>);} export default App;Run your application: Run your application using the following command to see the theme behavior based on system settings:
`npm run start`Here, we are using macOS and have updated the system preference to dark theme. The following behavior can be observed:

Add custom theme toggling option to your application
To add custom theme toggling to your application, follow these steps to design a component that allows you to switch between themes using either a dropdown menu or a radio button.
Step 1. Create the theme selector component
We will use the Carbon dropdown component. Add a file ThemeSelector.js with the following code to implement the dropdown with React state management.
Note: Exit your application if it is running before updating the code.
import { Dropdown } from '@carbon/react';
import { useState } from 'react';
import PropTypes from 'prop-types';
const availableThemes = [
{ label: 'White', value: 'white' },
{ label: 'G10', value: 'g10' },
{ label: 'G90', value: 'g90' },
{ label: 'G100', value: 'g100' },
];
const ThemeSelector = ({ handleSelectionChange }) => {
const [selectedTheme, setSelectedTheme] = useState(availableThemes[0]);
const handleThemeChange = ({ selectedItem }) => {
setSelectedTheme(selectedItem);
handleSelectionChange(selectedItem.value);
};
return (
<Dropdown
id="theme-dropdown"
label="Theme Switcher"
titleText="Theme Switcher"
selectedItem={selectedTheme}
items={availableThemes}
onChange={handleThemeChange}
itemToString={(item) => (item ? item.label : '')}
style={{ width: '385px', marginBottom: '30px'}}
/>
);
};
ThemeSelector.propTypes = {
handleSelectionChange: PropTypes.func.isRequired,
};
export default ThemeSelector;
Step 2. Add CSS attributes for theme switching
Add the following CSS attributes to your style file to enable theme switching:
[data-carbon-theme='g10'] {
@include themes.theme($g10);
}
[data-carbon-theme='g90'] {
@include themes.theme($g90);
}
[data-carbon-theme='g100'] {
@include themes.theme($g100);
}
Step 3: Update higher order component (HOC)
Update your App.js to manage state changes and apply the theming:
For the complete source code of the component, visit the Github repository.
Step 4: Launch your application
Run your application using:
`npm run start`
Observe how you can toggle the theme using the designed dropdown.
Developing themed custom components using carbon tokens
Instead of using pre-styled Carbon components, you can integrate theme style switching into custom components. Carbon provides color tokens with specific names that, when applied, ensure the desired color styling respects the active theme of the application.
Example: Themed button and modal
Here, we demonstrate using a button that opens a modal window. We apply Carbon tokens to replicate the behavior:
@use '@carbon/styles';
@use '@carbon/react/scss/theme' as theme;
.customComponent {
button {
/* Base styles */
color: theme.$text-inverse;
background-color: theme.$icon-secondary;
Explanation
The usage of tokens for the button color ensures it respects the theme used in the application. The SCSS code above applies the appropriate theme-based color styling to the button within the custom component.

Conclusion
This tutorial guided you through implementing theming in React applications using IBM’s Carbon React Library. It covered essential concepts such as themes, tokens, and roles, and explained how to integrate system-based and custom theme switching. By using Carbon’s pre-designed components and tokens, you can create a dynamic and accessible user interface. The tutorial also provided practical examples, including a custom theme toggling component and themed custom components.