k8ordo
  • UI
  • Form
  • State
  • Router
  • Static
  • Server
  • i18n
  • Color scheme
Switch to dark mode
k8ordo

React libraries that use Baseline features without holding back.

Packages
  • @k8ordo/ui
  • @k8ordo/form
  • @k8ordo/state
  • @k8ordo/router
  • @k8ordo/static
  • @k8ordo/server
  • @k8ordo/i18n
  • @k8ordo/color-scheme
UI
  • Get Started
  • Theming
  • i18n
  • Components
  • Hooks
  • Helpers
  • AI Chat
  • Generative UI
  • AI Agents
  • Storybook
Resources
  • GitHub
  • npm

© 2026 k8o — MIT License

Typeset in Noto Sans JP & M PLUS 2

@k8ordo/color-scheme

Owns the colour-scheme axis of an application. The visitor’s preference (light, dark, or nothing, which follows the system) lives in localStorage, is resolved against the system, and becomes the `dark` class on `<html>`. One provider in the root layout renders the inline script that puts it there before the first paint and keeps it there after hydration; a hook reads it.

npmGitHub

This site is the demo

The switcher in the header and the choices below are the same useColorScheme(). Choosing “system” removes the stored row and follows the OS again.

On screen
light
Preference
system

The whole of it

One provider in the root layout, one hook in the switcher. There is nothing else to write.

Features

  • Right from the first paint<ColorSchemeProvider> renders an inline script as its first child. It reads the row the provider writes and puts dark on before React loads, so a dark page never flashes light. Nothing goes in <head>.
  • Absence follows the systemA preference is stored only when the visitor chose one. Otherwise the provider’s defaultPreference applies (system unless told otherwise), following prefers-color-scheme as it changes — never pinned to what the system said on the first visit.
  • Stored through @k8ordo/stateOne defineLocalState('color-scheme') is where it lives. The key and the JSON envelope are never spelled here; cross-tab sync and salvage of an old row are state’s.
  • One place decides, any place readsOnly the provider writes the class. useColorScheme() is a hook that reads { scheme, preference, setPreference } and nothing more, so a switcher and a preview cannot disagree.

Design guide

The guide ships inside the npm package. An AI coding assistant reads the exact installed version out of node_modules/@k8ordo/color-scheme/docs/.

Home
// routes/layout.tsx — Provider を body の中で全部に被せる。
// 先頭にインラインスクリプトを描くので、最初の描画から dark が付いている
import { ColorSchemeProvider } from '@k8ordo/color-scheme';

<html suppressHydrationWarning>
  <body>
    <ColorSchemeProvider>{children}</ColorSchemeProvider>
  </body>
</html>

// components/scheme-switcher.tsx
'use client';
import { useColorScheme } from '@k8ordo/color-scheme';

const { scheme, preference, setPreference } = useColorScheme();
setPreference(scheme === 'dark' ? 'light' : 'dark'); // 切り替える
setPreference('system'); // 保存行を消してシステムに追従する

// 訪問者が選ぶまでダークで始めたいなら、1 回だけ言う
<ColorSchemeProvider defaultPreference="dark">