Skip to Content

Built by moveinready.casa  and the community

DocumentationGetting Started

Getting Started

Quick Start

If you are looking to get started quickly, we recommend using the expo-starter  project.

Manual Installation

If you have an existing project, or want to install shadcn-native manually, you can do so by following the steps below.

Install the core dependencies

These are the core dependencies you will need to install to use any of the components. Each component may ship its own dependencies.

expo install @expo/browser-polyfill tailwind-variants@3.x.x tw-merge@3.x.x twrnc@4.x.x lucide-react-native@0.540.x nativewind@4.x.x react-native-reanimated@~3.x.x react-native-safe-area-context@5.x.x expo install -D tailwindcss@^3.4.17 prettier-plugin-tailwindcss@^0.5.11 expo install @expo/router expo install @expo/vector-icons expo install @expo/linking expo install @expo/constants expo install @expo/dev-client

Configure Nativewind

Note

Make sure to place your globals.css file in the app directory of your project.

Configure Themes

Themes are hard to get right. This is the approach we recommend. See the themes section for more information.

  • Update your tailwind.config.js file to:
tailwind.config.js
/** @type {import('tailwindcss').Config} */ export default { darkMode: "class", // Update this to your project's paths content: ["./app/**/*.{ts,tsx}", "./components/**/*.{ts,tsx}"], presets: [require("nativewind/preset")], theme: { extend: { colors: { border: "var(--border)", input: "var(--input)", ring: "var(--ring)", background: "var(--background)", foreground: "var(--foreground)", primary: { DEFAULT: "var(--primary)", foreground: "var(--primary-foreground)", }, secondary: { DEFAULT: "var(--secondary)", foreground: "var(--secondary-foreground)", }, destructive: { DEFAULT: "var(--destructive)", foreground: "var(--destructive-foreground)", }, success: { DEFAULT: "var(--success)", foreground: "var(--success-foreground)", }, warning: { DEFAULT: "var(--warning)", foreground: "var(--warning-foreground)", }, muted: { DEFAULT: "var(--muted)", foreground: "var(--muted-foreground)", }, accent: { DEFAULT: "var(--accent)", foreground: "var(--accent-foreground)", }, popover: { DEFAULT: "var(--popover)", foreground: "var(--popover-foreground)", }, card: { DEFAULT: "var(--card)", foreground: "var(--card-foreground)", }, sidebar: { DEFAULT: "var(--sidebar-background)", foreground: "var(--sidebar-foreground)", primary: "var(--sidebar-primary)", "primary-foreground": "var(--sidebar-primary-foreground)", accent: "var(--sidebar-accent)", "accent-foreground": "var(--sidebar-accent-foreground)", border: "var(--sidebar-border)", ring: "var(--sidebar-ring)", }, }, borderRadius: { xl: "calc(var(--radius) + 4px)", lg: "var(--radius)", md: "calc(var(--radius) - 2px)", sm: "calc(var(--radius) - 4px)", full: "100%", }, }, }, plugins: [], };
  • Update your app/globals.css file to:
app/globals.css
@tailwind base; @tailwind components; @tailwind utilities; @layer base { :root { --radius: 0.625rem; --background: #ffffff; --foreground: #252525; --card: #ffffff; --card-foreground: #252525; --popover: #ffffff; --popover-foreground: #252525; --primary: #343434; --primary-foreground: #fbfbfb; --secondary: #f7f7f7; --secondary-foreground: #343434; --success: #22c55e; --warning: #eab308; --muted: #f7f7f7; --muted-foreground: #8e8e8e; --accent: #f7f7f7; --accent-foreground: #343434; --destructive: #ef4444; --border: #ebebeb; --input: #ebebeb; --ring: #b5b5b5; --chart-1: #f97316; --chart-2: #06b6d4; --chart-3: #3b82f6; --chart-4: #84cc16; --chart-5: #f59e0b; --sidebar: #fbfbfb; --sidebar-foreground: #252525; --sidebar-primary: #343434; --sidebar-primary-foreground: #fbfbfb; --sidebar-accent: #f7f7f7; --sidebar-accent-foreground: #343434; --sidebar-border: #ebebeb; --sidebar-ring: #b5b5b5; } .dark:root { --background: #252525; --foreground: #fbfbfb; --card: #343434; --card-foreground: #fbfbfb; --popover: #444444; --popover-foreground: #fbfbfb; --primary: #ebebeb; --primary-foreground: #343434; --secondary: #444444; --secondary-foreground: #fbfbfb; --muted: #444444; --muted-foreground: #b5b5b5; --accent: #5f5f5f; --accent-foreground: #fbfbfb; --destructive: #dc2626; --success: #16a34a; --warning: #ca8a04; --border: rgba(255, 255, 255, 0.1); --input: rgba(255, 255, 255, 0.15); --ring: #8e8e8e; --chart-1: #8b5cf6; --chart-2: #10b981; --chart-3: #f59e0b; --chart-4: #ec4899; --chart-5: #dc2626; --sidebar: #343434; --sidebar-foreground: #fbfbfb; --sidebar-primary: #8b5cf6; --sidebar-primary-foreground: #fbfbfb; --sidebar-accent: #444444; --sidebar-accent-foreground: #fbfbfb; --sidebar-border: rgba(255, 255, 255, 0.1); --sidebar-ring: #707070; } }
  • Add the theme.ts file to your project:
lib/utils/theme.ts
import {useColorScheme} from "react-native"; export const theme = { light: { radius: "0.625rem", background: "#ffffff", foreground: "#252525", card: "#ffffff", cardForeground: "#252525", popover: "#ffffff", popoverForeground: "#252525", primary: "#343434", primaryForeground: "#fbfbfb", secondary: "#f7f7f7", secondaryForeground: "#343434", success: "#22c55e", warning: "#eab308", muted: "#f7f7f7", mutedForeground: "#8e8e8e", accent: "#f7f7f7", accentForeground: "#343434", destructive: "#ef4444", border: "#ebebeb", input: "#ebebeb", ring: "#b5b5b5", chart1: "#f97316", chart2: "#06b6d4", chart3: "#3b82f6", chart4: "#84cc16", chart5: "#f59e0b", sidebar: "#fbfbfb", sidebarForeground: "#252525", sidebarPrimary: "#343434", sidebarPrimaryForeground: "#fbfbfb", sidebarAccent: "#f7f7f7", sidebarAccentForeground: "#343434", sidebarBorder: "#ebebeb", sidebarRing: "#b5b5b5", }, dark: { background: "#252525", foreground: "#fbfbfb", card: "#343434", cardForeground: "#fbfbfb", popover: "#444444", popoverForeground: "#fbfbfb", primary: "#ebebeb", primaryForeground: "#343434", secondary: "#444444", secondaryForeground: "#fbfbfb", muted: "#444444", mutedForeground: "#b5b5b5", accent: "#5f5f5f", accentForeground: "#fbfbfb", destructive: "#dc2626", success: "#16a34a", warning: "#ca8a04", border: "rgba(255, 255, 255, 0.1)", input: "rgba(255, 255, 255, 0.15)", ring: "#8e8e8e", chart1: "#8b5cf6", chart2: "#10b981", chart3: "#f59e0b", chart4: "#ec4899", chart5: "#dc2626", sidebar: "#343434", sidebarForeground: "#fbfbfb", sidebarPrimary: "#8b5cf6", sidebarPrimaryForeground: "#fbfbfb", sidebarAccent: "#444444", sidebarAccentForeground: "#fbfbfb", sidebarBorder: "rgba(255, 255, 255, 0.1)", sidebarRing: "#707070", }, }; export const useTheme = () => { const colorScheme = useColorScheme(); return theme[colorScheme || "light"]; }; // Suppress SVGElement error class SVGElement {} // @ts-ignore globalThis.SVGElement = SVGElement;
  • Optional: Theme your stack navigator:
app/_layout.tsx
import {useTheme} from "@/lib/utils/theme"; import {Stack, StatusBar} from "expo-router"; import {useColorScheme} from "react-native"; import "./global.css"; export default function RootLayout() { const theme = useTheme(); const colorScheme = useColorScheme(); return ( <> <StatusBar style={colorScheme === "dark" ? "light" : "dark"} /> <Stack screenOptions={{ title: "Expo Starter", contentStyle: {backgroundColor: theme.background}, headerTitleStyle: {color: theme.foreground}, headerStyle: {backgroundColor: theme.background}, }} /> </> ); }
  • Web You may need to manually add the dark class to the body element on web. Add the following to your root layout:
// Handle dark mode class for web useEffect(() => { if (Platform.OS === "web") { // Type assertion for web platform where document is available const doc = (globalThis as any).document; if (doc) { const root = doc.documentElement; if (colorScheme === "dark") { root.classList.add("dark"); } else { root.classList.remove("dark"); } } } }, [colorScheme]);
Note

This theme is the base neutral theme from shadcn/ui. See more themes here shadcn/themes 

See the themes section for more information.

Configure the Shadcn CLI

Note

If you are adding components manually, you can skip this step.

Important

Do not use the shadcn init command. It will break your configuration. We are working on our own CLI.

Create a components.json file. This is a list of all the components you want to use.

components.json
{ "$schema": "https://ui.shadcn.com/schema.json", "style": "new-york", "rsc": true, "tsx": true, "tailwind": { "config": "", "css": "app/globals.css", "baseColor": "neutral", "cssVariables": true, "prefix": "" }, "aliases": { "components": "@/components", "utils": "@/lib/utils", "ui": "@/components/ui", "lib": "@/lib", "hooks": "@/hooks" }, "iconLibrary": "lucide" }

For more information on the components.json file, see the components.json documentation.

Configure TypeScript

Update your tsconfig.json file to:

tsconfig.json
{ "extends": "@react-native/typescript-config", "compilerOptions": { "target": "esnext", "types": ["nativewind", "react-native"], "jsxImportSource": "nativewind", "jsx": "preserve", "esModuleInterop": true, "allowSyntheticDefaultImports": true, "moduleResolution": "bundler", "skipLibCheck": true, "baseUrl": ".", "paths": { "@/*": ["./*"] } }, "include": [ "**/*.ts", "**/*.tsx", ".expo/types/**/*.ts", "expo-env.d.ts", "nativewind-env.d.ts" ], "exclude": ["node_modules"] }

Add a Component

Test your setup by adding a component to your project.

pnpm dlx shadcn@latest add https://shadcn-native.moveinready.casa/registry/button

All done! You can now start building your app.

Troubleshooting

Jest Cannot find module '@/lib/utils/theme'

If you are testing with Jest you may run into this error. To fix it add the following to your jest config:

moduleNameMapper: { "^@/(.*)": "<rootDir>/registry/$1", },

Styles not applying with Expo

Restart your Expo server.

expo start --clear

Styles not applying (React Native or Expo)

If your styles still aren’t applying, make sure you are importing the globals.css file in your root layout.

Dark mode not working (web)

Add the following to your root layout:

// Handle dark mode class for web useEffect(() => { if (Platform.OS === "web") { // Type assertion for web platform where document is available const doc = (globalThis as any).document; if (doc) { const root = doc.documentElement; if (colorScheme === "dark") { root.classList.add("dark"); } else { root.classList.remove("dark"); } } } }, [colorScheme]);

shadcn-native

Built by moveinready.casa and the community