Dark mode
Dark mode is not a second stylesheet. Components reference ramp positions
($color3, $color11) and semantic tokens ($background, $borderColor), and
the ramp resolves differently per scheme — so a component written once is correct
in both.
Choosing the scheme
<Provider defaultColorScheme="system"> // follow the OS (recommended)
<Provider defaultColorScheme="dark"> // start dark, user can change
<Provider forceColorScheme="light"> // pin it; ignores the OSReading and changing it
import { useColorScheme } from "@knitui/core";
function ThemeToggle() {
const { colorScheme, setColorScheme, toggleColorScheme } = useColorScheme();
return (
<ActionIcon aria-label="Toggle theme" onPress={toggleColorScheme}>
{colorScheme === "dark" ? <IconMoon /> : <IconSun />}
</ActionIcon>
);
}setColorScheme also accepts "system", so a three-way control is
light / dark / system rather than a boolean.
Persisting the choice
The kit does not pick a storage mechanism for you — that is an app decision
(AsyncStorage, localStorage, a user record). Store the preference and pass it
as defaultColorScheme:
const stored = await AsyncStorage.getItem("color-scheme");
<Provider defaultColorScheme={stored ?? "system"}>Avoiding a flash on the web
A static or server-rendered page ships one HTML file for everyone, so the first paint is whatever the server assumed. Two mitigations, both cheap:
- Default to
"system"and let CSSprefers-color-schemecover the first frame for your own chrome, correcting to the stored preference on mount. - Write the resolved scheme onto the root element so non-kit CSS can follow:
useEffect(() => {
document.documentElement.dataset.theme = colorScheme;
}, [colorScheme]);This site does both — its prose and chrome are plain CSS keyed off
prefers-color-scheme with a [data-theme] override, while the components read
Tamagui's themes.
Testing both
Stories in this repo carry a scheme toggle in the Storybook toolbar, and the docs have one in the header. Check dark before shipping a component, not after: the usual failure is a hard-coded hex or a shadow that vanishes.