βοΈ Enjoying the library? Support it with a star on GitHub β thank you!
π§ͺ Check out the Demo App Showcase to see
theme-csx
in action.
- β‘οΈ Light / Dark / System theme support
- π Dynamic iOS color adaptation
- πΎ MMKV-based persistent theme storage
- π§ Memoized themed styles with createThemedStyles
- π Type-safe access to theme tokens (with autocomplete)
- π Scalable for monorepos and multi-app setups
- π§© Extendable (spacing, typography, shadows, etc.)
β iOS: theme changes apply instantly
π Android: theme changes apply on app restart
# npm
npm install theme-csx
# yarn
yarn add theme-csx
# pnpm
pnpm add theme-csx
Create your own theme
object.
β colors.light is required and defines the base color palette.
β colors.dark is optional, but must only override keys already defined in colors.light.
π¨ Everything else is optional and fully customizable β feel free to add anything like spacing, typography, radius, etc.
// theme/theme.ts
export const theme = {
colors: {
light: {
background: '#ffffff',
text: '#111111',
},
dark: {
background: '#000000', // β
valid override
text: '#ffffff', // β
valid override
// error if an unknown key like "accent" is added here!
},
},
spacing: {
sm: 8,
md: 16,
lg: 24,
},
// Add any other tokens you want (typography, radius, etc.)
};
Use createAppTheme()
to initialize your theming system.
π¨ Critical:
createAppTheme()
must be called only once in your entire app. Calling it multiple times can cause unexpected behavior & theme conflicts.
You can enable persistent theme mode storage (optional) by setting { storage: true }
.
β οΈ Requiresreact-native-mmkv
if storage is enabled.
// theme/index.ts
import { createAppTheme } from 'theme-csx';
import { theme } from './theme';
export const {
AppThemeProvider,
useTheme,
useThemeMode,
useSetThemeMode,
useResetThemeMode,
useToggleThemeMode,
useCycleThemeMode,
createThemedStyles,
createStaticStyles,
types,
} = createAppTheme(theme, {
storage: true, // Optional: disables persistence if omitted or set to false
});
export type Theme = typeof types.Theme;
export type ThemeMode = typeof types.ThemeMode;
Wrap your app with AppThemeProvider
and you are all set π.
// App.tsx
import { AppThemeProvider } from '@theme';
export default function App() {
return (
<AppThemeProvider>
{/* your app code */}
</AppThemeProvider>
);
}
import { useTheme } from '@theme';
const MyComponent = () => {
const theme = useTheme();
return <View style={{ backgroundColor: theme.colors.background }} />;
};
import { View, Text } from 'react-native';
import { createThemedStyles, createStaticStyles } from '@theme';
// π¨ Styles that respond to theme mode (light/dark/system)
const useThemedStyles = createThemedStyles((theme) => ({
container: {
flex: 1,
backgroundColor: theme.colors.background,
padding: theme.spacing.md,
},
text: {
color: theme.colors.text,
},
}));
// π§± Styles that use theme tokens but remain static across theme modes
const staticStyles = createStaticStyles((theme) => ({
text: {
fontSize: 18,
fontWeight: 'bold',
color: theme.colors.light.primary, // fixed value from light mode
},
}));
const MyComponent = () => {
const styles = useThemedStyles();
return (
<View style={styles.container}>
<Text style={styles.text}>
I react to theme mode changes
</Text>
<Text style={staticStyles.text}>
I stay the same across all modes
</Text>
</View>
);
};
import { useToggleThemeMode } from '@theme';
const ToggleButton = () => {
const toggleTheme = useToggleThemeMode();
return <Button title="Toggle Theme" onPress={toggleTheme} />;
};
Once you initialize your theme system with createAppTheme()
, you get access to the following utilities:
Utility | Description |
---|---|
useTheme() |
Access the current theme (colors , colorMode , and custom tokens). |
useThemeMode() |
Get the current theme mode (light , dark , or system ). |
useSetThemeMode() |
Change the theme mode programmatically. |
useResetThemeMode() |
Reset to system theme mode (and clear stored preference if storage: true ). |
useToggleThemeMode() |
Toggle strictly between light and dark modes. |
useCycleThemeMode() |
Cycle through modes: light β dark β system β light . |
createThemedStyles() |
Create memoized themed styles using your theme object. |
createStaticStyles() |
Create static styles using your theme object.(non-reactive) |
All of these must be used within your AppThemeProvider
tree.
β
Use useTheme()
for direct access to the theme
β
Use createThemedStyles()
for most of your app β these styles respond to light/dark mode and adapt dynamically.
β
Use createStaticStyles()
only when you need styles that remain fixed across all theme modes but still leverage theme tokens.
π‘ Define createThemedStyles()
and createStaticStyles()
outside of components for maximum efficiency & performance
π« Do not call createAppTheme()
more than once per app
MIT Β© KJ-GM