Learn how to support light and dark modes in your app.
Regardless of whether you are personally on team light or team dark, it's becoming increasingly common for apps to support these two color schemes. This guide explains how you can do that.
Both managed and bare projects for Android and iOS require additional configuration to support switching between light and dark modes. No additional configuration is required for the web.
Configure your supported appearance styles in app.json/app.config.js with the userInterfaceStyle
key. You can also configure specific platforms to support different appearance styles by setting either android.userInterfaceStyle
or ios.userInterfaceStyle
to the preferred value.
The 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). If this key is absent, the app will default to the light
style. Here is an example configuration:
{
"expo": {
"userInterfaceStyle": "automatic"
}
}
In EAS Build and development builds you'll need to install the native module expo-system-ui
otherwise the userInterfaceStyle
property will be ignored. Running expo config --type introspect
will warn if the project is misconfigured:
» android: userInterfaceStyle: Install expo-system-ui in your project to enable this feature.
Appearance locking requires
react-native@0.63.3
to work correctly.
Ensure that the uiMode
flag is present on your MainActivity
(and any other activities where this behavior is desired) in AndroidManifest.xml:
<activity
...
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode">
Implement the onConfigurationChanged
method in MainActivity.java (react-native@0.63.3
don't need this):
import android.content.Intent; // <--- import
import android.content.res.Configuration; // <--- import
public class MainActivity extends ReactActivity {
......
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Intent intent = new Intent("onConfigurationChanged");
intent.putExtra("newConfig", newConfig);
sendBroadcast(intent);
}
......
}
You can configure supported styles with the UIUserInterfaceStyle key in your app Info.plist. Use Automatic
to support both light and dark modes.
To detect the color scheme in our application, we can use Appearance
and/or useColorScheme
from react-native
:
import { Appearance, useColorScheme } from 'react-native';
You will probably want to use the useColorScheme()
hook:
function MyComponent() {
let colorScheme = useColorScheme();
if (colorScheme === 'dark') {
// render some dark thing
} else {
// render some light thing
}
}
In some cases, you may find it helpful to get the current color scheme imperatively with Appearance.getColorScheme()
and/or listen to changes with Appearance.addChangeListener
.
Don't forget to configure your project to support the automatic color scheme as described above in Configuration.
import React from 'react';
import { Text, StyleSheet, View, useColorScheme } from 'react-native';
import { StatusBar } from 'expo-status-bar'; // automatically switches bar style based on theme!
export default function App() {
const colorScheme = useColorScheme();
const themeTextStyle = colorScheme === 'light' ? styles.lightThemeText : styles.darkThemeText;
const themeContainerStyle =
colorScheme === 'light' ? styles.lightContainer : styles.darkContainer;
return (
<View style={[styles.container, themeContainerStyle]}>
<Text style={[styles.text, themeTextStyle]}>Color scheme: {colorScheme}</Text>
<StatusBar />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
lightContainer: {
backgroundColor: '#d0d0c0',
},
darkContainer: {
backgroundColor: '#242c40',
},
lightThemeText: {
color: '#242c40',
},
darkThemeText: {
color: '#d0d0c0',
},
});
While you're developing, you may want to change your simulator's or device's appearance.
adb shell "cmd uimode night yes"
to enable dark mode, and adb shell "cmd uimode night no"
to disable dark mode.