EngineeringMarch 21, 2025By Ankur Prajapati

Theming System with Shopify Restyle

Theming System with Shopify Restyle

Introduction

This document outlines the theming system developed using Shopify Restyle. The system provides a scalable and maintainable way to manage themes in our React Native application while leveraging the powerful utilities of Restyle.

Architecture

The theming system is structured around a core theme object that defines design tokens such as colors, spacing, typography, and component variants. The theme is consumed by Shopify Restyle's ThemeProvider, ensuring that all components use the defined design system.

Theme File Structure

  • theme/
  • index.ts (implements and export theme)
  • primitives.ts (primitives values such as lineheight, fontSize, scale)
  • helpers.ts (helpers functions)
  • colors.ts (color palettes dark/light)
  • types.ts (Theme types)

Defining the Theme

A base theme is created and extended for different variations (e.g., light and dark mode).

First lets understand how the theme is built in our project context.

  1. Spacing - this is built from scale primitives. e.g '2xs': scale['scale-2'] . This will be used in margin , padding etc in our Themed Components.

  2. borderRadii - this is built from scale primitives. full: scale['scale-999']. This will be used for all border radius values.

  3. Colors : we have a base color obj which looks like which maps color alias names to color palettes. e.g. 'bg-surface-primary': palette.grey[0].

For some aliases instead of directly using the palette we use primary/secondary which helps us build customized themes e.g. 'text-action-primary': defaultPrimaryPalette[1000].

And the function generateColorPalette takes primaryColor and secondaryColor then replaces the palette with the generated palette with those colors hence we get the final color object. This can be used for bgColor , borderColor values etc.

  1. textVariants : this consists of all the text variants defined in the design system

Each text variant is made up of properties like fontWeight, fontSize , lineHeight and fontFamily. This will be used by ThemedText variant prop.

Using the Theme

To use the theme, wrap the application with ThemeProvider and consume the theme values inside components using Restyle utilities.

Example Usage

import { ThemeProvider } from '@shopify/restyle';

import theme from './theme';

const App = () => (

<ThemeProvider theme={theme}> <HomeScreen /> </ThemeProvider>

);

Inside a component:

import { Box, Text, useTheme } from '@shopify/restyle';

import { Theme } from '../theme';

const Card = () => {

const theme = useTheme<Theme>();

return (

<Box backgroundColor="primary" padding="m">

<Text variant="body" color="text">Hello, Theming!</Text>

</Box>

);

};

Dynamic Theming

For dynamic theme switching, maintain a state and update the theme provider dynamically.

Example Theme Switcher

const [theme, setTheme] = useState(lightTheme);

const toggleTheme = () => {

setTheme(theme === lightTheme ? darkTheme : lightTheme);

};

<ThemeProvider theme={theme}> <Button title="Toggle Theme" onPress={toggleTheme} /> </ThemeProvider>

Best Practices

  • Define consistent design tokens to maintain uniformity.
  • Use variants to simplify component styling.
  • Avoid hardcoded styles inside components.

Examples

  1. Using text and view

  2. Using React native elements like

  3. Accessing the theme

Conclusion

This theming system ensures consistency and flexibility across the application. Future improvements may include supporting multiple themes, integrating with context providers, and enhancing accessibility.