1--- 2title: Color themes 3description: Learn how to support light and dark modes in your app. 4--- 5 6import { SnackInline, Terminal } from '~/ui/components/Snippet'; 7import Video from '~/components/plugins/Video'; 8import { Collapsible } from '~/ui/components/Collapsible'; 9import { BoxLink } from '~/ui/components/BoxLink'; 10import { BookOpen02Icon } from '@expo/styleguide-icons'; 11 12Whether you are personally on team light or team dark, it's becoming increasingly common for apps to support these two color schemes. Here is an example of how supporting both modes looks in an Expo project: 13 14<Video file="guides/color-schemes.mp4" spaceAfter={30} /> 15 16## Configuration 17 18Projects require additional configuration to support switching between light and dark modes for Android and iOS. However, no additional configuration is required for the web. 19 20You can configure the supported appearance styles in **app.json** with the [`userInterfaceStyle`](/versions/latest/config/app/#userinterfacestyle) property. You can also configure specific platforms to support different appearance styles by setting either [`android.userInterfaceStyle`](/versions/latest/config/app/#userinterfacestyle-2) or [`ios.userInterfaceStyle`](/versions/latest/config/app/#userinterfacestyle-1) to the preferred value. 21 22The available options are `automatic` (follow system appearance settings and notify about any change user makes), `light` (restrict the app to support light theme only), and `dark` (restrict the app to support dark theme only). The app will default to the light style if this property is absent. Here is an example configuration: 23 24```json app.json 25{ 26 "expo": { 27 "userInterfaceStyle": "automatic" 28 } 29} 30``` 31 32In development builds, you'll need to install the native package [`expo-system-ui`](/versions/latest/sdk/system-ui/#installation). Otherwise, the `userInterfaceStyle` property is ignored. You can also use following command to check if the project is misconfigured: 33 34<Terminal cmd={['npx expo config --type introspect']} /> 35 36If the project is misconfigured, you'll see a warning as shown below: 37 38<Terminal 39 cmd={[ 40 '» android: userInterfaceStyle: Install expo-system-ui in your project to enable this feature.', 41 ]} 42/> 43 44<Collapsible summary="Using bare workflow?"> 45 46### Android 47 48> Appearance locking requires `[email protected]` to work correctly. 49 50Ensure that the `uiMode` flag is present on your `MainActivity` (and any other activities where this behavior is desired) in **AndroidManifest.xml**: 51 52```xml 53<activity 54... 55android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"> 56``` 57 58Implement the `onConfigurationChanged` method in **MainActivity.java** (`[email protected]` don't need this): 59 60```java 61import android.content.Intent; // <--- import 62import android.content.res.Configuration; // <--- import 63public class MainActivity extends ReactActivity { 64 ...... 65 @Override 66 public void onConfigurationChanged(Configuration newConfig) { 67 super.onConfigurationChanged(newConfig); 68 Intent intent = new Intent("onConfigurationChanged"); 69 intent.putExtra("newConfig", newConfig); 70 sendBroadcast(intent); 71 } 72 ...... 73} 74``` 75 76### iOS 77 78You can configure supported styles with the [UIUserInterfaceStyle](https://developer.apple.com/documentation/bundleresources/information_property_list/uiuserinterfacestyle) key in your app **Info.plist**. Use `Automatic` to support both light and dark modes. 79 80</Collapsible> 81 82## Detect the color scheme 83 84To detect the color scheme in your project, use `Appearance` and/or `useColorScheme` from `react-native`: 85 86```js App.js 87import { Appearance, useColorScheme } from 'react-native'; 88``` 89 90Then, you can use `useColorScheme()` hook as shown below: 91 92```js App.js 93function MyComponent() { 94 let colorScheme = useColorScheme(); 95 96 if (colorScheme === 'dark') { 97 // render some dark thing 98 } else { 99 // render some light thing 100 } 101} 102``` 103 104In some cases, you will find it helpful to get the current color scheme imperatively with [`Appearance.getColorScheme()` and/or listen to changes with `Appearance.addChangeListener`](https://reactnative.dev/docs/appearance). 105 106## Minimal example 107 108> Don't forget to configure your project to support the automatic color scheme as described above in [Configuration](#configuration). 109 110> [Snack](https://snack.expo.dev) is locked to light mode. 111 112<SnackInline label="useColorScheme example" dependencies={['expo-status-bar']}> 113 114```jsx 115import React from 'react'; 116import { Text, StyleSheet, View, useColorScheme } from 'react-native'; 117import { StatusBar } from 'expo-status-bar'; // automatically switches bar style based on theme! 118 119export default function App() { 120 const colorScheme = useColorScheme(); 121 122 const themeTextStyle = colorScheme === 'light' ? styles.lightThemeText : styles.darkThemeText; 123 const themeContainerStyle = 124 colorScheme === 'light' ? styles.lightContainer : styles.darkContainer; 125 126 return ( 127 <View style={[styles.container, themeContainerStyle]}> 128 <Text style={[styles.text, themeTextStyle]}>Color scheme: {colorScheme}</Text> 129 <StatusBar /> 130 </View> 131 ); 132} 133 134const styles = StyleSheet.create({ 135 container: { 136 flex: 1, 137 alignItems: 'center', 138 justifyContent: 'center', 139 }, 140 lightContainer: { 141 backgroundColor: '#d0d0c0', 142 }, 143 darkContainer: { 144 backgroundColor: '#242c40', 145 }, 146 lightThemeText: { 147 color: '#242c40', 148 }, 149 darkThemeText: { 150 color: '#d0d0c0', 151 }, 152}); 153``` 154 155</SnackInline> 156 157## Tips 158 159While you're developing your project, you can change your simulator's or device's appearance by using the following shortcuts: 160 161- If working with an iOS emulator locally, you can use the <kbd>Cmd ⌘</kbd> + <kbd>Shift</kbd> + <kbd>a</kbd> shortcut to toggle between light and dark modes. 162- If using an Android Emulator, you can run `adb shell "cmd uimode night yes"` to enable dark mode, and `adb shell "cmd uimode night no"` to disable dark mode. 163- If using a real device or an Android Emulator, you can toggle the system dark mode setting in the device's settings. 164 165## Next step 166 167<BoxLink 168 title="Animation" 169 description="Learn more about integrating the react-native-reanimated library to create animations in your app." 170 href="/develop/user-interface/animation" 171 Icon={BookOpen02Icon} 172/> 173