This is the full developer documentation for React Native Unistyles 3.0 # Configuration > How configure Unistyles To unlock more features and tailor Unistyles to your needs, you can configure it. The Unistyles configuration is divided into three parts: 1. **Themes** 2. **Breakpoints** 3. **Settings** Note Each configuration is optional but enables advanced features, which are explained in the guide [How Unistyles Works?](/v3/start/how-unistyles-works) ### Themes (Optional) `Themes` is a JavaScript object where the keys represent unique theme names, and the values are the corresponding theme definitions. For more details, refer to the [theming](/v3/guides/theming) guide. unistyles.ts ```tsx const lightTheme = { colors: { primary: '#ff1ff4', secondary: '#1ff4ff' // any nesting, spreading, arrays, etc. }, // functions, external imports, etc. gap: (v: number) => v * 8 } const otherTheme = { colors: { primary: '#aa12ff', secondary: 'pink' }, gap: (v: number) => v * 8 } const appThemes = { light: lightTheme, other: otherTheme } ``` Note Unistyles supports any dynamic theme and doesn’t enforce a specific structure. To avoid TypeScript issues, ensure that all themes share the same type. ### Breakpoints (Optional) `Breakpoints` is a JavaScript object where the keys are unique breakpoint names and the values are the corresponding breakpoint values (numbers). Be sure to register at least one breakpoint with a value of 0, as it’s required to simulate the cascading behavior of CSS media queries. unistyles.ts ```tsx const breakpoints = { xs: 0, // <-- make sure to register one breakpoint with value 0 sm: 300, md: 500, lg: 800, xl: 1200 // use as many breakpoints as you need } ``` ### Settings (Optional) The `Settings` object has been simplified, and in the most recent version, it supports only four properties: * **`adaptiveThemes`** – a boolean that enables or disables adaptive themes [learn more](/v3/guides/theming#adaptive-themes) * **`initialTheme`** – a string or a synchronous function that sets the initial theme * **`CSSVars`** – a boolean that enables or disables web CSS variables (defaults to `true`) [learn more](/v3/references/web-only#css-variables) * **`nativeBreakpointsMode`** - iOS/Android only. User preferred mode for breakpoints. Can be either `points` or `pixels` (defaults to `pixels`) [learn more](/v3/references/breakpoints#pixelpoint-mode-for-native-breakpoints) unistyles.ts ```tsx const settings = { initialTheme: 'light' } // or with a synchronous function const settings = { initialTheme: () => { // get preferred theme from user's preferences/MMKV/SQL/StanJS etc. return storage.getString('preferredTheme') ?? 'light' } } // or with adaptive themes const settings = { adaptiveThemes: true } ``` Note In the Unistyles 3.0 setting both `initialTheme` and `adaptiveThemes` will cause an error. These options are mutually exclusive. ### TypeScript Types (Optional) If your repository is using TypeScript, it is highly recommended to override the library types for optimal autocomplete and type safety regarding your themes and breakpoints: unistyles.ts ```tsx type AppThemes = typeof appThemes type AppBreakpoints = typeof breakpoints declare module 'react-native-unistyles' { export interface UnistylesThemes extends AppThemes {} export interface UnistylesBreakpoints extends AppBreakpoints {} } ``` ### Set configuration The final step in the configuration is to set all the options by calling the `StyleSheet.configure` function: unistyles.ts ```tsx import { StyleSheet } from 'react-native-unistyles' StyleSheet.configure({ themes: appThemes, breakpoints, settings }) ``` That’s it! You can now use all the features of Unistyles in your project! ### Full example unistyles.ts ```tsx import { StyleSheet } from 'react-native-unistyles' const lightTheme = { colors: { primary: '#ff1ff4', secondary: '#1ff4ff' }, gap: (v: number) => v * 8 } const otherTheme = { colors: { primary: '#aa12ff', secondary: 'pink' }, gap: (v: number) => v * 8 } const appThemes = { light: lightTheme, other: otherTheme } const breakpoints = { xs: 0, sm: 300, md: 500, lg: 800, xl: 1200 } type AppBreakpoints = typeof breakpoints type AppThemes = typeof appThemes declare module 'react-native-unistyles' { export interface UnistylesThemes extends AppThemes {} export interface UnistylesBreakpoints extends AppBreakpoints {} } StyleSheet.configure({ settings: { initialTheme: 'light', }, breakpoints, themes: appThemes }) ``` Note Don’t forget to import this config somewhere in your project, for example in `index.ts` file. You **must** call `StyleSheet.configure` **before** any `StyleSheet.create` call. For expo router users, please refer to the [Expo Router guide](/v3/guides/expo-router). # Getting started > How to get started with Unistyles We put a lot of effort into making Unistyles as easy to use as possible. You no longer need the `useStyle` hook or wrap your app in provider. Unistyles integrates seamlessly with your existing code, so you can start using it immediately. ### Prerequisites Unistyles 3.0 is tightly integrated with `Fabric` and the latest version of React Native. Therefore, you must use the **New Architecture** and at least **React Native 0.76.0**. Additionally, Unistyles relies on `react-native-nitro-modules` and `react-native-edge-to-edge`. Note Learn more about how Unistyles leverages Nitro Modules and React Native Edge to Edge [here](/v3/other/dependencies). **Table of requirements:** | | Required | Note | | ---------------- | -------- | ------------------------- | | React Native | 0.76+ | | | New Architecture | enabled | no option to opt-out | | Expo SDK | 52+ | (if you use Expo) | | Xcode | 16+ | Required by Nitro Modules | Caution There is a known bug in Xcode 16.2. If you use this version, please follow [this github issue](https://github.com/jpudysz/react-native-unistyles/issues/507#issuecomment-2602963047) Since Unistyles relies on `Fabric`, it cannot run on the `Old Architecture` or older versions of React Native. If you can’t meet these requirements, you can use Unistyles 2.0+, which is compatible with those versions. ### Installation Install Unistyles and its dependencies ```shell yarn add react-native-unistyles@beta yarn add react-native-nitro-modules react-native-edge-to-edge ``` Caution To avoid unexpected behaviors always use a fixed version of `react-native-nitro-modules`. Check compatibility table [here](https://github.com/jpudysz/react-native-unistyles?tab=readme-ov-file#installation). Add babel plugin: babel.config.js ```js module.exports = function (api) { api.cache(true) return { // for bare React Native // presets: ['module:@react-native/babel-preset'], // or for Expo // presets: ['babel-preset-expo'], // other config plugins: [ // other plugins ['react-native-unistyles/plugin'] ] } } ``` Note Learn more on how the Babel plugin works [here](/v3/other/babel-plugin). If you’re using React Compiler, check [this guide](/v3/guides/react-compiler) for more details. Check extra configuration options [here](/v3/other/babel-plugin#extra-configuration). Finish installation based on your platform: * Expo ```shell yarn expo prebuild --clean ``` Dev client only Unistyles includes custom native code, which means it does not support **Expo Go.** * React Native ```shell cd ios && pod install ``` * React Native Web Unistyles offers first-class support for React Native Web. To run the project, we recommend following the guidelines provided by [Expo](https://docs.expo.dev/workflow/web/). * Custom Web 🚧 Work in progress, we will share more details soon. * SSR Unistyles offers first-class support for Next.js Server Side Rendering. To run the project, we recommend following the guidelines provided by [Next.JS](https://nextjs.org/docs). ### As easy as React Native StyleSheet Getting started with Unistyles couldn’t be easier. Simply replace React Native’s `StyleSheet` with the `StyleSheet` exported from Unistyles. From that moment, you’ll be using a `StyleSheet` with superpowers 🦸🏼‍♂️. Example.tsx ```tsx import { StyleSheet } from 'react-native' import { StyleSheet } from 'react-native-unistyles' const MyComponent = () => { return ( Hello world from Unistyles ) } const styles = StyleSheet.create({ container: { backgroundColor: 'red' } }) ``` By replacing `StyleSheet`, you immediately gain several benefits that aren’t available in React Native’s `StyleSheet`: * [Variants](/v3/references/variants) * [Compound variants](/v3/references/compound-variants) * [Dynamic functions](/v3/references/dynamic-functions) * [Media queries](/v3/references/media-queries) * [Horizontal and vertical breakpoints for Native](/v3/references/breakpoints#built-in-breakpoints-landscape-and-portrait) * [Custom web styles](/v3/references/web-styles) * [Web only features](/v3/references/web-only) When you’re ready to customize your styles and unlock additional features you can [configure](/v3/start/configuration) Unistyles. # How Unistyles works? > Understanding how Unistyles 3.0 works To get the most out of Unistyles, it’s important to understand how it works and how it updates your styles. ### 1. StyleSheets A typical app consist of many `StyleSheets`. A `StyleSheet` is a JavaScript object that holds one or many styles. Each style is associated with native view. What’s more important is that each `StyleSheet` is unique, tailored to the needs of the view, or to a shared component. ![](/_astro/how-1.ClhanbTT.png) Your app’s StyleSheets ### 2. Babel plugin: dependencies Unistyles needs to understand your `StyleSheet` dependencies in order to update them only when necessary. This process begins when Babel transforms your app’s code. At this stage, the Unistyles Babel plugin scans your `StyleSheets` and determines the dependencies for each style: ```ts const styles = StyleSheet.create((theme, rt) => ({ // static: no dependencies container: { backgroundColor: 'red', }, // depends on theme and font scale text: { color: theme.colors.text, fontSize: rt.fontScale * 16 }, dynamic: (isOdd: boolean) => ({ // depends on theme color: isOdd ? theme.colors.primary : theme.colors.secondary, }) }) ``` ### 3. Babel plugin: component factory As you already know, Unistyles has no components. This means your native view hierarchy remains exactly the same as in your original code. The Babel plugin processes your components through our component factory to borrow `refs` and bind the `ShadowNode` with `Unistyle`. You might be wondering, what is `Unistyle`? We refer to it as your `StyleSheet` style that have been parsed by the Unistyles compiler, and with the attached `C++` state. ![](/_astro/how-2.CKBxY89P.png) Your styles are transformed into Unistyles Note Learn more on how the Babel plugin works [here](/v3/other/babel-plugin). ### 4. StyleSheet registry We don’t just extract metadata from your styles. We do the same for your `StyleSheet`. On the C++ side, we know exactly which `StyleSheet` is static, which depends on a `theme`, and which `Unistyles` it contains. At this point, your app’s `StyleSheets` are reconstructed on the C++ side and stored in native C++ `StyleSheets`, which contain the parsed `Unistyles`. ![](/_astro/how-3.C8JEACBb.png) C++ StyleSheets that contains parsed styles (Unistyles) To make this process easier to visualize, imagine that the Unistyles engine is a production line. It takes your raw `StyleSheets`, parses them, and produces their C++ representation with `Unistyles`: ![](/_astro/how-4.DbcKjxwq.png) Unistyles workflow ### 5. Reacting to events When you access your `StyleSheet` styles in your component, you’ll get a regular JS object as expected. If your component re-renders, we simply return the same `Unistyle` that’s already parsed and stored in the cache. To visualize the true power of `Unistyles`, imagine that some event occurs, such as: * A theme change triggered by the user clicking a button * A phone color scheme change * A phone orientation change * Accessibility settings being updated * and much more! Unistyles is able to update your styles based on 14 events At this point, the Unistyles algorithm scans the `StyleSheetRegistry` and looks for styles that depend on this event: ![](/_astro/how-5.Bu7A8bBJ.png) Finding affected styles Affected styles are then re-computed to reflect the new state of your app. ### 6. Shadow Tree updates With the list of affected styles, we can now browse the `ShadowRegistry`, where we keep the bindings between `ShadowNode` and `Unistyles`. In other words, we know which `component` relies on which `style`. With all this information, we can translate the update into atomic `ShadowTree` instructions. With Unistyles 2.0 or any other library, we would need to re-render your entire app to reflect the changes: ![](/_astro/how-6.D5izBS6T.png) Regular flow: your app is re-rendered Instead, with all the optimizations and features that Unistyles 3.0 brings, we can target only specific nodes and update your `ShadowTree` directly from C++: ![](/_astro/how-7.DHJpQ7un.png) Unistyles 3.0 updates only selected ShadowNodes from C++ With this architecture and the power of selective updates through `ShadowTree`, your components are never re-rendered. *Engineering is the closest thing to magic that exists in the world.* \~Elon Musk # Introduction > Welcome to Unistyles! Beta Unistyles 3.0 is still in beta. We’re waiting for the community feedback before promoting it to the stable. ![](/_astro/uni2.CWBtkH-A.png) Unistyles is a cross-platform library that enables you to share up to 100% of your styles across all platforms. It combines the simplicity of `StyleSheet` with the performance of `C++`. **`Unistyles` is a superset of `StyleSheet`** similar to how `TypeScript` is a superset of `JavaScript`. If you’re familiar with styling in React Native, then you already know how to use `Unistyles`. ### Why should you use Unistyles? * Guarantees no re-renders across the entire app (no hooks, no context—just pure JSI bindings) * Doesn’t pollute your native view hierarchy (Unistyles has no component wrappers) * Includes a cross-platform parser written in C++, ensuring consistent output across all platforms * Leverages [Nitro Modules](https://nitro.margelo.com/) under the hood (everything is strongly typed!) * Transforms your `StyleSheets` into enhanced `StyleSheets` with superpowers 🦸🏼‍♂️ that can access themes, platform-specific values, and more! * Loved by developers worldwide: 1.5M+ downloads and over 1.9K stars on GitHub # Migration guide > How to migrate from previous version The migration process is quite simple, but it can be tedious since you’ll need to remove a lot of the existing code. 1. Follow installation steps from [Getting started](/v3/start/getting-started) guide. 2. Replace your configuration with [new](/v3/start/configuration) one. `UnistylesRegistry` can be easily replaced with `StyleSheet.configure` as it follows the same syntax. `Themes` and `Breakpoints` work exactly the same. For `Settings` we removed 4 out of 6 options: ```tsx import { UnistylesRegistry } from 'react-native-unistyles' import { StyleSheet } from 'react-native-unistyles' UnistylesRegistry.addConfig({ adaptiveThemes: false, initialTheme: 'dark', plugins: [...], experimentalCSSMediaQueries: true, windowResizeDebounceTimeMs: 100, disableAnimatedInsets: true }) StyleSheet.configure({ settings: { adaptiveThemes: false, // works exactly the same like in 2.0 initialTheme: 'dark', // works exactly the same like in 2.0 // plugins are removed, instead transform your styles with static functions // experimentalCSSMediaQueries: these options is also removed, and enabled by default with custom parser // windowResizeDebounceTimeMs: removed, there is no debouncing anymore. Styles are updated with CSS media queries // disableAnimatedInsets: removed, insets won't re-render your views } }) ``` 3. Import `StyleSheet` from `react-native-unistyles`: ```tsx import { createStyleSheet, useStyles } from 'react-native-unistyles' import { StyleSheet } from 'react-native-unistyles' ``` 4. Replace `createStyleSheet` with `StyleSheet.create`: ```tsx const stylesheet = createStyleSheet(theme => ({ const stylesheet = StyleSheet.create(theme => ({ ``` 5. Remove all occurrences of `useStyles` hook: ```tsx const { styles } = useStyles(stylesheet) ``` 6. Rename your `stylesheet` to `styles`: ```tsx const stylesheet = StyleSheet.create(theme => ({ const styles = StyleSheet.create(theme => ({ ``` 7. If you used `useInitialTheme`, remove it and set initial theme in `StyleSheet.configure`: ```tsx import { StyleSheet } from 'react-native-unistyles' StyleSheet.configure({ themes, breakpoints, settings: { initialTheme: () => { // get preferred theme from user's preferences/MMKV/SQL/StanJS etc. // must be synchronous return storage.getString('preferredTheme') ?? 'light' } } }) ``` 8. If you need to access your `theme` in component, refactor it to use `withUnistyles`: ```tsx import { Button } from 'react-native' import { useStyles } from 'react-native-unistyles' import { withUnistyles } from 'react-native-unistyles' const UniButton = withUnistyles(Button, theme => ({ color: theme.colors.primary })) const MyButton = () => { return } const MyButton = () => { const { theme } = useStyles(stylesheet) return