Bring your design system

Already have colours, a font and a corner radius? Point ExpoKit's tokens at them once in KitProvider, and every component you add matches your app — no edits to the copied files.

Start with init

init asks for a brand colour, font, radius and light / dark, or takes them as flags. It adds lib/kit.tsx and writes lib/kit-theme.tsx: an <AppTheme> wrapper around KitProvider. Wrap your root layout in it, then fill in colors below.

Which token is which

Every component reads these from useKit().colors. You don't have to set them all: anything you leave out keeps the kit default for that scheme.

PropTypeDefault
background

Screen and page fill. Point it at your screen background.

string#ffffff
foreground

Main text and icons. Point it at your primary text colour.

string#09090b
card / cardForeground

Cards, inputs, sheets — and the text on them. Point it at your surface and its text.

string#ffffff / #09090b
popover

Raised surfaces: toasts, menus. Point it at your elevated surface.

string#ffffff
muted

Subtle fills: tracks, skeletons, pressed rows. Point it at your subtle / secondary surface.

string#f4f4f5
mutedForeground

Secondary text, placeholders, captions. Point it at your secondary text.

string#71717a
border / input

Hairlines; field outlines. Point it at your divider and input-border colours.

string#e4e4e7 / #d4d4d8
primary / primaryForeground

Default solid buttons and their label. Point it at your primary button fill and label.

string#18181b / #fafafa
secondary / secondaryForeground

Quiet buttons and chips. Point it at your secondary button fill and label.

string#f4f4f5 / #18181b
accent / accentForeground

Brand colour: focus rings, selection, accent buttons. Point it at your brand colour (or pass accent=).

string#18181b / #ffffff
success / warning / danger

Status colours: toasts, alerts, validation. Point it at your semantic colours.

stringgreen / amber / red
dangerForeground

Text on a danger fill. Point it at usually white.

string#ffffff
ring

Focus outline; follows accent when you pass one. Point it at your focus colour.

string#18181b
overlay

Scrim behind sheets and dialogs. Point it at your backdrop, with alpha.

stringrgba(0,0,0,0.4)

The bridge

Keep your design system the source of truth and map it in one place. Light and dark are separate maps, so a token can point at different values per scheme.

src/lib/kit-theme.tsx
import type { ReactNode } from "react"; import { KitProvider } from "@/lib/kit";import { tokens } from "@/theme/tokens"; // your existing design system export function AppTheme({ children }: { children: ReactNode }) {  return (    <KitProvider      scheme="system"      accent={tokens.brand[500]}      radius={tokens.radius.md}      fontFamily={tokens.font.body}      colors={{        light: {          background: tokens.light.bg,          foreground: tokens.light.text,          card: tokens.light.surface,          cardForeground: tokens.light.text,          popover: tokens.light.surfaceRaised,          muted: tokens.light.subtle,          mutedForeground: tokens.light.textSecondary,          border: tokens.light.divider,          input: tokens.light.inputBorder,          primary: tokens.brand[600],          primaryForeground: "#ffffff",          danger: tokens.red[500],        },        dark: {          background: tokens.dark.bg,          foreground: tokens.dark.text,          card: tokens.dark.surface,          muted: tokens.dark.subtle,          mutedForeground: tokens.dark.textSecondary,          border: tokens.dark.divider,        },      }}    >      {children}    </KitProvider>  );}
src/app/_layout.tsx
import { Stack } from "expo-router";import { AppTheme } from "@/lib/kit-theme"; export default function RootLayout() {  return (    <AppTheme>      <Stack />    </AppTheme>  );}

Radius and font

radius is your base corner in points (default 12); the kit derives sm, lg and xl from it and scales pills and bars to match, so radius={0} gives a square UI. fontFamily must be a font your app has loaded (for example with expo-font) before the first screen renders.

Light and dark

scheme="system" follows the device. If your app has its own appearance setting, pass its value instead — scheme={appearance} with "light" or "dark" — and the kit follows your switch rather than the device's.

Use the same tokens in your own screens with useKit(), so custom components and kit components can't drift apart. Keep the bridge in kit-theme.tsx rather than editing kit.tsx: then update can refresh kit.tsx without stopping on your changes.