Getting started
Install the OTF SDK packages, wire up theming, and ship your first screen.
The OTF SDK is published as scoped packages on npm under @otfdashkit/*. Install the ones
you need for your platform.
Bought a kit? Purchased kits are full-stack templates. Read the templates overview to see what you get and how to start from your kit repo.
Web project (Next.js, Vite, Remix, …)
npm install @otfdashkit/ui @otfdashkit/tokensThe web components are styled with Tailwind CSS v3. Install it, then add the OTF preset, the animation plugin and the component sources to your Tailwind config:
npm install -D tailwindcss@3 tailwindcss-animate postcss autoprefixerimport animate from 'tailwindcss-animate'
import { otfPreset } from '@otfdashkit/tokens/tailwind-preset'
export default {
presets: [otfPreset],
plugins: [animate],
content: ['./app/**/*.{ts,tsx}', './node_modules/@otfdashkit/ui/src/**/*.{ts,tsx}'],
}Tailwind v3 runs as a PostCSS plugin, so the app also needs a PostCSS config:
export default {
plugins: { tailwindcss: {}, autoprefixer: {} },
}If your project was scaffolded with Tailwind v4 (for example a current create-next-app --tailwind),
replace its @tailwindcss/postcss config and its @import "tailwindcss" line with the v3 setup on this page.
Import the preset from @otfdashkit/tokens/tailwind-preset, not from @otfdashkit/tokens: the
package root also loads the native config, which a web-only install can't resolve.
Add the token CSS import before the component CSS in your global stylesheet:
@import '@otfdashkit/tokens/web.css';
@import '@otfdashkit/ui/styles';
@tailwind base;
@tailwind components;
@tailwind utilities;
/* your own styles below */Set the default theme on the document before the first paint so users don't see a flash of unstyled colors:
<script
dangerouslySetInnerHTML={{
__html: `
const t = localStorage.getItem('otf-theme') || 'theme-minimal'
const s = localStorage.getItem('otf-color-scheme') || 'dark'
document.documentElement.className = \`\${t} \${s}\`
`,
}}
/>You're done. Import a component:
import { Persona, Stat, EmptyState } from '@otfdashkit/ui'
export default function Page() {
return (
<div className="p-6 grid gap-4">
<Stat label="Active users" value="12,406" delta="+12%" />
<EmptyState title="No projects yet" description="Create your first project to get started." />
</div>
)
}React Native project (Expo)
npm install @otfdashkit/ui-native @otfdashkit/tokens@otfdashkit/ui-native is built on Tamagui. Wire the provider once in your root layout:
import { Slot } from 'expo-router'
import { OTFProvider } from '@otfdashkit/ui-native'
export default function RootLayout() {
return (
<OTFProvider>
<Slot />
</OTFProvider>
)
}Then import primitives the same way you would on web:
import { YStack, Text, Card } from '@otfdashkit/ui-native'
export default function Screen() {
return (
<YStack padding="$4" gap="$3">
<Text fontSize="$8" fontWeight="700">Welcome</Text>
<Card padding="$4">Hello from OTF.</Card>
</YStack>
)
}Both platforms in one repo
If you're building one product across web + native (which is what the OTF kits do), use a monorepo and consume both packages from the same workspace. Share business logic, screens, and theme tokens — keep platform-specific glue thin. See the Templates page for the canonical layout the kits use.
Learn more
Theme + palette switching
Runtime theme switching across 4 palettes, custom palette authoring, dark/light mapping.
Components — Web
The full @otfdashkit/ui surface — primitives, composites, blocks, and advanced.
Components — Native
Primitives, layouts, and patterns built for Expo.
AI tool integration
CLAUDE.md and .cursorrules — kept in sync by @otfdashkit/ai.