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