Home Writing Reading

til / Nativewind with design tokens and dark mode

Nativewind is Tailwind for React Native. The upcoming version of Nativewind, v4, adds support for CSS which means we can use CSS custom properties (variables). This allows us to use design tokens for things like colors which means we don’t have to define and maintain a light and dark color everywhere. No more bg-gray-100 dark:bg-gray-900, just bg-background.

To get started, use the getting started section for your app type. The setup differs between Expo and bare React Native.

/* The CSS file you defined during setup */
:root {
  /* We're using the modern rgb syntax. We can also
	use hsl or the legacy rgba syntax if we want. */
  --color-background: 255 255 255; /* #FFFFFF */
}

@media (prefers-color-scheme: dark) {
  :root {
    --color-background: 40 40 37; /* #282825 */
  }
}

Here we’ve added one design token, a background color, to our CSS. It has one color for light mode (inside the top :root) and one color for dark mode inside the prefers-color-scheme media query. Note that we define the RGB values without the color space function.

The color space is defined inside tailwind.config.js with a reference to our variable and a special <alpha-value> placeholder. This allows us to use the alpha modifier in our Tailwind classes. For example, bg-background/10 to use our background color with 10% opacity.

// tailwind.config.js
module.exports = {
  // Other config...
  theme: {
    // This overrides all of Tailwind's default colors which
    // we don't need in our case since we rely only on our
    // design tokens.
    colors: {
      background: 'rgb(var(--color-background) / <alpha-value>)',
    },
    // To extend default colors, use theme.extend.colors instead.
  },
}

Now we’re ready to use our color inside our app. It will switch automatically between light and dark mode whenever the color scheme changes, either if the system setting changes or if you update it manually using useColorScheme from nativewind.

import { View } from 'react-native'

export function Card({ children }) {
  return <View className="p-4 bg-container">{children}</View>
}

This will become even simpler once Tailwind v4 lands since we will only need to define the tokens in the CSS file.


  • Loading next post...
  • Loading previous post...