Dark mode

native-mate resolves dark/light tokens synchronously from useColorScheme(), so there is zero flicker on mount — even on Android.

Automatic (follows system)

Default behaviour — ThemeProvider reads the device colour scheme.

tsx
1
2
3
<ThemeProvider preset="zinc">
  {/* automatically light or dark based on system settings */}
</ThemeProvider>

Force a mode

tsx
1
2
3
4
5
// Always dark
<ThemeProvider preset="zinc" forcedColorScheme="dark">

// Always light
<ThemeProvider preset="zinc" forcedColorScheme="light">

Let the user toggle

ThemeContext.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
import { useState } from 'react'
import { ThemeProvider } from '@native-mate/core'

export function AppThemeProvider({ children }: { children: React.ReactNode }) {
  const [mode, setMode] = useState<'light' | 'dark' | undefined>(undefined)

  return (
    <ThemeProvider preset="zinc" forcedColorScheme={mode}>
      {children}
      {/* pass setMode down via context or state manager */}
    </ThemeProvider>
  )
}

Reading mode inside a component

tsx
1
2
3
4
5
6
7
8
9
10
11
12
import { useTheme } from '@native-mate/core'

function MyComponent() {
  const theme = useTheme()
  const isDark = theme.colorScheme === 'dark'

  return (
    <View style={{ backgroundColor: isDark ? '#000' : '#fff' }}>
      {/* ... */}
    </View>
  )
}

Why no flicker?

useColorScheme() is synchronous in React Native — the OS colour scheme is known before the first render. ThemeProvider resolves tokens with useMemo, so the correct theme is available immediately without any effect-based switching.