Quick Start
From zero to a fully themed, type-safe, responsive component tree — in one page.
npx stareezy create my-app --template next. This scaffolds a pre-wired Next.js 15 project with everything set up. Skip to step 4 if you use the CLI.1. Scaffold with the CLI
The @stareezy-ui/cli creates a fully pre-wired project with one command. Choose your template:
# Next.js 15 App Router (React 19)
npx stareezy create my-app --template next
# Vite + React 19
npx stareezy create my-app --template vite
# Expo SDK 56 (React Native 0.85)
npx stareezy create my-app --template expoOmit --template to get an interactive prompt. Each template ships with stareezy.config.ts, the compiler plugin, ThemeProvider, and a demo screen.
npx stareezy init to add the config and wiring, or npx stareezy add button input card to install specific components.2. Manual install (skip if you used the CLI)
# pnpm (recommended)
pnpm add @stareezy-ui/tokens @stareezy-ui/components
pnpm add -D @stareezy-ui/compiler
# yarn
yarn add @stareezy-ui/tokens @stareezy-ui/components
yarn add -D @stareezy-ui/compiler
# npm
npm install @stareezy-ui/tokens @stareezy-ui/components
npm install -D @stareezy-ui/compiler3. Create your config
Create stareezy.config.ts at the root of your project. The module augmentation makes your config flow into the type system — so autocomplete and type errors reflect your exact setup.
// stareezy.config.ts
import { createUi, themes } from '@stareezy-ui/tokens'
export const ui = createUi({
// Five built-in themes
themes: {
aurora: themes.aurora,
dark: themes.dark,
light: themes.light,
'steins-gate': themes['steins-gate'],
quasar: themes.quasar,
},
// Responsive breakpoints (mobile-first, min-width in px)
// These become the valid keys for responsive objects and $-prefixed props
media: {
sm: 480, md: 768, lg: 1024, xl: 1280, '2xl': 1536,
},
// Prop shorthands — become valid props on Box and every component
shorthands: {
p: 'padding', px: 'paddingHorizontal', py: 'paddingVertical',
m: 'margin', mx: 'marginHorizontal', my: 'marginVertical',
br: 'borderRadius', w: 'width', h: 'height', f: 'flex',
} as const, // ← as const is required
})
// Module augmentation — makes BreakpointKey + shorthands flow into BoxProps
declare module '@stareezy-ui/tokens' {
interface SzrCustomConfig extends typeof ui {}
}
export default ui4. Wrap your app with ThemeProvider
// Next.js: app/providers.tsx (note: "use client" required)
'use client'
import { ThemeProvider } from '@stareezy-ui/tokens'
export function Providers({ children }: { children: React.ReactNode }) {
return <ThemeProvider defaultTheme="aurora">{children}</ThemeProvider>
}
// Next.js: app/layout.tsx
import { Providers } from './providers'
export default function RootLayout({ children }) {
return (
<html lang="en">
<body><Providers>{children}</Providers></body>
</html>
)
}
// Vite / Expo: wrap App directly
import { ThemeProvider } from '@stareezy-ui/tokens'
function App() {
return <ThemeProvider defaultTheme="aurora"><AppContent /></ThemeProvider>
}5. Use theme-reactive props
The t accessor returns ThemeToken references. They resolve to the current theme's value at render time and update automatically when the theme switches.
import { t } from '@stareezy-ui/tokens'
import { Box, Text, Button } from '@stareezy-ui/components'
function Card() {
return (
<Box
bg={t.backgrounds.secondary}
borderColor={t.border.primaryBrand}
p={16}
rounded={12}
>
<Text
type="M-heading-bold"
style={{ color: t.text.primary }}
text="Theme-reactive"
/>
<Text
type="M-paragraph-regular"
style={{ color: t.text.secondary }}
text="This switches with the theme automatically."
/>
<Button type="Primary" text="Click me" mt={12} />
</Box>
)
}
// aurora → bg: dark surface, border: #00ff88
// quasar → bg: deep violet, border: #a855f7
// light → bg: white, border: #024cce6. Use responsive props
All components accept responsive objects and $-prefixed breakpoint groups — derived from your createUi({ media }) config.
// Responsive object syntax — mobile-first cascade
<Box p={{ base: 8, md: 16, lg: 24 }} flexDirection={{ base: 'column', lg: 'row' }} />
// $-prefixed group syntax — equivalent, but groups multiple props per breakpoint
<Box $md={{ p: 16, br: 8 }} $lg={{ p: 24, br: 12, flexDirection: 'row' }} />
// Works on EVERY component — not just Box
<Button p={{ base: 8, md: 12 }} w={{ base: '100%', md: 'auto' }} />
<Input w={{ base: '100%', md: 360 }} mb={8} />
<Card p={{ base: 12, md: 20 }} $lg={{ flexDirection: 'row' }} />
<Drawer open={open} onClose={close} $md={{ p: 24 }} />
// Custom shorthands are also responsive:
<Box br={{ base: 4, md: 8, lg: 12 }} /> // borderRadius
<Box w={{ base: '100%', md: 320 }} /> // width7. Use static tokens
import { colors, spacing, radius } from '@stareezy-ui/tokens'
// Static tokens — same value regardless of theme
<Box bg={colors.celurenBlue[500]} p={spacing[4]} rounded={radius.md} />
// Raw .value for non-Box contexts (canvas, SVG, StyleSheet, etc.)
const style = {
backgroundColor: colors.celurenBlue[500].value, // "#024CCE"
padding: spacing[4].value, // 16
borderRadius: radius.md.value, // 8
}8. React Server Components
Import layout primitives from the "./server" entry — hook-free, safe in Next.js App Router Server Components.
// app/page.tsx — Server Component (default in Next.js App Router)
import { Box, Stack, Text } from '@stareezy-ui/components/server'
import { HeroActions } from './HeroActions' // 'use client'
export default async function Page() {
const data = await fetchData() // server-side, no useEffect needed
return (
<Box p={{ base: 16, md: 32 }}>
<Stack gap={16}>
<Text style={{ fontSize: 32, fontWeight: 800 }}>{data.title}</Text>
<HeroActions /> {/* Only this needs "use client" */}
</Stack>
</Box>
)
}9. Switch themes
import { useThemeSwitch } from '@stareezy-ui/tokens'
function ThemeSwitcher() {
const { theme, setTheme, toggleTheme } = useThemeSwitch()
return (
<div style={{ display: 'flex', gap: 8 }}>
{['aurora', 'dark', 'light', 'steins-gate', 'quasar'].map((name) => (
<button
key={name}
onClick={() => setTheme(name)}
style={{ fontWeight: theme === name ? 700 : 400 }}
>
{name}
</button>
))}
</div>
)
}10. Add the compiler (optional but recommended)
// vite.config.ts
import { stareezyVitePlugin } from '@stareezy-ui/compiler'
export default { plugins: [stareezyVitePlugin()] }
// next.config.ts
import { stareezyVitePlugin } from '@stareezy-ui/compiler'
export default {
webpack(config) {
config.plugins.push(stareezyVitePlugin())
return config
}
}// metro.config.js
const { getDefaultConfig } = require('expo/metro-config')
const config = getDefaultConfig(__dirname)
config.transformer = {
...config.transformer,
babelTransformerPath: require.resolve('@stareezy-ui/compiler/metro'),
}
module.exports = configstareezy.config.ts from your project root automatically — no path argument needed.11. Add components to an existing project
Use stareezy add to install specific components with automatic transitive dependency resolution:
npx stareezy add button input card
npx stareezy add drawer tooltip table pagination breadcrumb