
Research
/Security News
Mini Shai-Hulud Campaign Hits Red Hat Cloud Services npm Packages
A mini Shai-Hulud campaign compromised Red Hat Cloud Services npm packages to steal developer and CI/CD secrets during installation.
@pchmn/expo-material3-theme
Advanced tools

This expo module allows you retrieve the Material 3 dynamic theme from Android 12+ devices, so that you can use it in your expo (or bare react-native) app.
For devices not compatible (iOS or older Android versions) a fallback theme is returned.
@material/material-color-utilities)react-native-paper
This library works with Expo Go, but you won't be able to retrieve the system theme (you'll get a fallback theme) because it requires custom native code and Expo Go doesn't support it
npx expo install @pchmn/expo-material3-theme
If you use development build, you'll have to rebuild development client (only android) after adding the library because it contains native code (https://docs.expo.dev/develop/development-builds/use-development-builds/#rebuild-a-development-build) :
npx expo prebuild --platform android
npx expo run:android
For bare React Native projects, you must ensure that you have installed and configured the expo package before continuing.
npx expo install @pchmn/expo-material3-theme
npx pod-install
A basic usage would be to retrieve the Material 3 theme from user device (or a fallback theme if not supported) by using useMaterial3Theme hook:
import { useMaterial3Theme } from '@pchmn/expo-material3-theme';
import { useColorScheme, View, Button } from 'react-native';
function App() {
const colorScheme = useColorScheme();
// If the device is not compatible, it will return a theme based on the fallback source color (optional, default to #6750A4)
const { theme } = useMaterial3Theme({ fallbackSourceColor: '#3E8260' });
return (
<View style={{ backgroundColor: theme[colorScheme].background }}>
<Button color={theme[colorScheme].primary}>Themed button</Button>
</View>
);
}
If you want to use a theme based on a specific color instead of the system theme, just pass the sourceColor param to useMaterial3Theme hook:
import { useMaterial3Theme } from '@pchmn/expo-material3-theme';
import { useColorScheme, View, Button } from 'react-native';
function App() {
const colorScheme = useColorScheme();
// Theme returned will be based on #3E8260 color
const { theme } = useMaterial3Theme({ sourceColor: '#3E8260' });
return (
<View style={{ backgroundColor: theme[colorScheme].background }}>
<Button color={theme[colorScheme].primary}>Themed button</Button>
</View>
);
}
With color fidelity (https://m3.material.io/styles/color/advanced/adjust-existing-colors#cb49eeb4-3bbd-4521-9612-0856c27f91ef):
import { useMaterial3Theme } from '@pchmn/expo-material3-theme';
import { useColorScheme, View, Button } from 'react-native';
function App() {
const colorScheme = useColorScheme();
const { theme } = useMaterial3Theme({ sourceColor: '#3E8260', colorFidelity: true });
return (
<View style={{ backgroundColor: theme[colorScheme].background }}>
<Button color={theme[colorScheme].primary}>Themed button</Button>
</View>
);
}
You may also want to update the theme by generating a new one, or go back to the default theme (to let users personalize your app for example). You can do it with useMaterial3Theme hook:
import { useMaterial3Theme } from '@pchmn/expo-material3-theme';
import { useColorScheme, View, Button } from 'react-native';
function App() {
const colorScheme = useColorScheme();
const { theme, updateTheme, resetTheme } = useMaterial3Theme();
return (
<View style={{ backgroundColor: theme[colorScheme].background }}>
{/* Update theme by generating a new one based on #3E8260 color */}
<Button onPress={() => updateTheme('#3E8260')}>Update theme</Button>
{/* Reset theme to default (system or fallback) */}
<Button onPress={() => resetTheme()}>Reset theme</Button>
</View>
);
}
ℹ️
updateTheme()andresetTheme()will change the theme returned byuseMaterial3Theme(), it will not change theme at system level
react-native-paper@pchmn/expo-material3-theme provides a theme compatible with react-native-paper, so you can combine both libraries easily:
import { useMaterial3Theme } from '@pchmn/expo-material3-theme';
import { useMemo } from 'react';
import { useColorScheme } from 'react-native';
import { Button, MD3DarkTheme, MD3LightTheme, Provider as PaperProvider } from 'react-native-paper';
function App() {
const colorScheme = useColorScheme();
const { theme } = useMaterial3Theme();
const paperTheme = useMemo(
() =>
colorScheme === 'dark' ? { ...MD3DarkTheme, colors: theme.dark } : { ...MD3LightTheme, colors: theme.light },
[colorScheme, theme]
);
return (
<PaperProvider theme={paperTheme}>
<Button>Themed react native paper button</Button>
</PaperProvider>
);
}
react-native-paper theme (Typescript)Some colors present in Material3Theme from this library are not present in MD3Theme of react-native-paper. You can create a typed useAppTheme() hook and use it instead of useTheme() hook to fix this :
import { Material3Scheme } from '@pchmn/expo-material3-theme';
import { MD3Theme, useTheme } from 'react-native-paper';
export const useAppTheme = useTheme<MD3Theme & { colors: Material3Scheme }>;
// Now use useAppTheme() instead of useTheme()
Material3ThemeProvider that includes PaperProvider// Material3ThemeProvider.tsx
import { Material3Scheme, Material3Theme, useMaterial3Theme } from '@pchmn/expo-material3-theme';
import { createContext, useContext } from 'react';
import { useColorScheme } from 'react-native';
import {
MD3DarkTheme,
MD3LightTheme,
MD3Theme,
Provider as PaperProvider,
ProviderProps,
useTheme,
} from 'react-native-paper';
type Material3ThemeProviderProps = {
theme: Material3Theme;
updateTheme: (sourceColor: string) => void;
resetTheme: () => void;
};
const Material3ThemeProviderContext = createContext<Material3ThemeProviderProps>({} as Material3ThemeProviderProps);
export function Material3ThemeProvider({
children,
sourceColor,
fallbackSourceColor,
...otherProps
}: ProviderProps & { sourceColor?: string; fallbackSourceColor?: string }) {
const colorScheme = useColorScheme();
const { theme, updateTheme, resetTheme } = useMaterial3Theme({
sourceColor,
fallbackSourceColor,
});
const paperTheme =
colorScheme === 'dark' ? { ...MD3DarkTheme, colors: theme.dark } : { ...MD3LightTheme, colors: theme.light };
return (
<Material3ThemeProviderContext.Provider value={{ theme, updateTheme, resetTheme }}>
<PaperProvider theme={paperTheme} {...otherProps}>
{children}
</PaperProvider>
</Material3ThemeProviderContext.Provider>
);
}
export function useMaterial3ThemeContext() {
const ctx = useContext(Material3ThemeProviderContext);
if (!ctx) {
throw new Error('useMaterial3ThemeContext must be used inside Material3ThemeProvider');
}
return ctx;
}
export const useAppTheme = useTheme<MD3Theme & { colors: Material3Scheme }>;
// App.tsx
import { Material3ThemeProvider, useAppTheme, useMaterial3ThemeContext } from '../Material3ThemeProvider';
import { View, Button } from 'react-native';
function App() {
return (
<Material3ThemeProvider>
<AppContent />
</Material3ThemeProvider>
);
}
function AppContent() {
const { updateTheme, resetTheme } = useMaterial3ThemeContext();
// react-native-paper theme is always in sync
const theme = useAppTheme();
return (
<View style={{ backgroundColor: theme.colors.background }}>
{/* Update theme by generating a new one based on #3E8260 color */}
<Button onPress={() => updateTheme('#3E8260')}>Update theme</Button>
{/* Reset theme to default (system or fallback) */}
<Button onPress={() => resetTheme()}>Reset theme</Button>
</View>
);
}
You can see an example app in the /example folder.
Extract zip file, and install expo-material3-theme-example-android.apk on your device.
This is a file for iOS simulator. Extract zip file, and drag and drop expo-material3-theme-example-ios into your emulator.
When Material 3 dynamic theme is changed on Android 12+ devices, it is a configuration change and the system will recreate an Activity.
This configuration change can't be disable: "Some configuration changes always cause the activity to restart. You can't disable them. For example, you can't disable the dynamic colors change introduced in API 32" (cf official doc).
So be aware that when users change their theme then go back to your app, all local state may be lost (and may cause some flickering) if your don't handle it.
This project is released under the MIT License.
FAQs
Manage Material 3 theme in your React Native App
The npm package @pchmn/expo-material3-theme receives a total of 1,594 weekly downloads. As such, @pchmn/expo-material3-theme popularity was classified as popular.
We found that @pchmn/expo-material3-theme demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
A mini Shai-Hulud campaign compromised Red Hat Cloud Services npm packages to steal developer and CI/CD secrets during installation.

Research
/Security News
The North Korean malware loader hides in a Packagist-listed package and its GitHub branch to fetch and execute remote code in a likely Contagious Interview-style lure.

Security News
The Rust project is moving toward formal rules on LLM use in contributions after months of internal debate over maintainer burden, code quality, and contributor experience.