React Native Unistyles
react-native-unistyles is a high-performance, universal styling solution for React Native, designed to enhance developer experience and application performance across iOS, Android, Web, and Expo environments. It leverages a shared C++ core and JSI bindings, powered by Nitro Modules, to achieve styling without triggering unnecessary re-renders in the React tree. The library is currently stable at version 3.2.3, with a rapid release cadence addressing features and bug fixes. Key differentiators include its unique custom web parser supporting CSS classes and pseudo-classes, tight integration with React Native's Fabric and Shadow Tree for optimal rendering, and significant performance benefits, adding under 0.1ms to StyleSheet processing. It allows developers to share nearly 100% of styles across platforms in a monorepo setup, register multiple themes, and dynamically switch them with a single function call, all without introducing new components into the view hierarchy. This approach ensures a clean and efficient component tree.
Common errors
-
Native module 'Unistyles' was not found. Did you forget to run 'pod install'?
cause The native module for Unistyles was not correctly linked or built into your project, often due to missing 'pod install' on iOS or incorrect native setup on Android/other platforms.fixFor iOS, navigate to your `ios/` directory and run `pod install`. For Android, ensure `react-native-unistyles` is correctly linked (often automatic with autolinking, but sometimes requires manual intervention or a clean build). -
Uncaught Error: Unistyles registry is not initialized. Please ensure UnistylesRegistry.addThemes() and UnistylesRegistry.addBreakpoints() are called before using Unistyles.
cause The Unistyles global registry (for themes, breakpoints) was not configured before components attempted to use Unistyles hooks or functions.fixEnsure `UnistylesRegistry.addThemes()`, `UnistylesRegistry.addBreakpoints()`, and `UnistylesRegistry.setInitialTheme()` are called once at the root of your application, typically in your `App.tsx` or a dedicated setup file. -
TypeError: Cannot read properties of undefined (reading 'colors')
cause This typically means the `theme` object passed to your stylesheet function or accessed directly from `useStyles` is undefined or malformed, likely because the themes were not correctly registered with `UnistylesRegistry` or the initial theme was not set.fixVerify that `UnistylesRegistry.addThemes()` and `UnistylesRegistry.setInitialTheme()` have been properly invoked with valid theme objects. -
SyntaxError: require() not supported
cause Attempting to use CommonJS `require()` syntax to import `react-native-unistyles` in an environment that expects ES Modules, or when your project configuration is set for ESM.fixUpdate all `require()` statements for `react-native-unistyles` to ES Module `import` statements (e.g., `import { useStyles } from 'react-native-unistyles';`).
Warnings
- breaking Upgrading from Unistyles v2.0 to v3.0 involves significant breaking changes and requires following the official migration guide.
- breaking `react-native-unistyles` v3.x has strict peer dependency requirements for `react-native-nitro-modules`. Ensure you install the compatible version.
- breaking Unistyles v3 requires Node.js version >= 20.18.0 and React Native version >= 0.76.0.
- gotcha The `react-native-edge-to-edge` dependency became optional from v3.1.0, but it's strongly recommended to enable `edgeToEdgeEnabled=true` in `android/gradle.properties` for proper system bar handling.
Install
-
npm install react-native-unistyles -
yarn add react-native-unistyles -
pnpm add react-native-unistyles
Imports
- UnistylesRegistry
const UnistylesRegistry = require('react-native-unistyles').UnistylesRegistryimport { UnistylesRegistry } from 'react-native-unistyles' - createStyleSheet
import createStyleSheet from 'react-native-unistyles'
import { createStyleSheet } from 'react-native-unistyles' - useStyles
import { useStyles as useUnistyles } from 'react-native-unistyles'import { useStyles } from 'react-native-unistyles' - UnistylesRuntime
import { UnistylesRuntime } from 'react-native-unistyles'
Quickstart
import React from 'react';
import { View, Text, Pressable } from 'react-native';
import {
UnistylesRegistry,
createStyleSheet,
useStyles,
UnistylesRuntime
} from 'react-native-unistyles';
// 1. Define your themes
const lightTheme = {
colors: {
background: '#FFFFFF',
text: '#000000',
primary: '#6200EE'
}
} as const; // 'as const' helps with type inference
const darkTheme = {
colors: {
background: '#121212',
text: '#FFFFFF',
primary: '#BB86FC'
}
} as const;
// 2. Define your breakpoints (optional, but powerful)
const breakpoints = {
sm: 0,
md: 768,
lg: 1024
} as const;
// 3. Register themes and breakpoints - crucial for TypeScript type inference
type AppBreakpoints = typeof breakpoints;
type AppThemes = {
light: typeof lightTheme;
dark: typeof darkTheme;
};
declare module 'react-native-unistyles' {
export interface UnistylesBreakpoints extends AppBreakpoints {}
export interface UnistylesThemes extends AppThemes {}
}
UnistylesRegistry.addBreakpoints(breakpoints)
.addThemes({
light: lightTheme,
dark: darkTheme
})
.setInitialTheme('light'); // Set initial theme
// 4. Create your stylesheet
const stylesheet = createStyleSheet((theme) => ({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: theme.colors.background
},
text: {
color: theme.colors.text,
fontSize: 20,
marginBottom: 20,
// Responsive styling using breakpoints
$$container: {
lg: { fontSize: 30 },
md: { fontSize: 24 }
}
},
button: {
backgroundColor: theme.colors.primary,
paddingVertical: 12,
paddingHorizontal: 24,
borderRadius: 8
},
buttonText: {
color: theme.colors.text === '#000000' ? '#FFFFFF' : '#000000', // Ensure contrast
fontSize: 16,
fontWeight: 'bold'
}
}));
// 5. Use the stylesheet in your component
export default function App() {
const { styles, theme } = useStyles(stylesheet);
const toggleTheme = () => {
UnistylesRuntime.setTheme(theme.name === 'light' ? 'dark' : 'light');
};
return (
<View style={styles.container}>
<Text style={styles.text}>
Current Theme: {theme.name}
</Text>
<Pressable onPress={toggleTheme} style={styles.button}>
<Text style={styles.buttonText}>Toggle Theme</Text>
</Pressable>
</View>
);
}