Skip to main content
Shipnative uses Unistyles 3.0 for styling. Theme support and dark mode work automatically.

Quick Reference

The Pattern

import { StyleSheet, useUnistyles } from 'react-native-unistyles'

function MyComponent() {
  const { theme } = useUnistyles()
  
  return (
    <View style={styles.container}>
      <Text style={styles.title}>Hello!</Text>
    </View>
  )
}

const styles = StyleSheet.create((theme) => ({
  container: {
    flex: 1,
    backgroundColor: theme.colors.background,
    padding: theme.spacing.md,
  },
  title: {
    fontSize: theme.typography.sizes['2xl'],
    fontFamily: theme.typography.fonts.bold,
    color: theme.colors.foreground,
  },
}))

Common Theme Values

CategoryValues
Colorstheme.colors.primary, background, foreground, card, error, muted
Neutral Palettetheme.colors.neutral100 through neutral900 (Modern Slate palette)
Spacingtheme.spacing.xs (4), sm (8), md (16), lg (24), xl (32)
Typographytheme.typography.sizes.base, lg, xl, 2xl
Fontstheme.typography.fonts.regular, medium, bold
Radiustheme.radius.sm, md, lg, full
Shadowstheme.shadows.sm, md, lg
Full theme definition: apps/app/app/theme/unistyles.ts

Key Rules

Never hardcode values. Always use theme tokens.
//  DON'T
const styles = StyleSheet.create({
  container: {
    backgroundColor: '#ffffff',
    padding: 16,
    color: '#000000',
  }
})

//  DO
const styles = StyleSheet.create((theme) => ({
  container: {
    backgroundColor: theme.colors.background,
    padding: theme.spacing.md,
    color: theme.colors.foreground,
  }
}))
This ensures:
  • Dark mode works automatically
  • Consistent design across your app
  • Easy theme customization later

Dark Mode

It’s automatic! Semantic color names switch between light and dark:
// Works in both light and dark mode
const styles = StyleSheet.create((theme) => ({
  container: {
    backgroundColor: theme.colors.background, // white in light, dark gray in dark
  },
  text: {
    color: theme.colors.foreground, // black in light, white in dark
  },
}))
No conditional logic needed. Just use theme colors and it works.

Detecting Dark Mode

import { UnistylesRuntime } from 'react-native-unistyles'

// Check current theme
const isDark = UnistylesRuntime.themeName === "dark"

// Change theme programmatically
UnistylesRuntime.setTheme("dark")
UnistylesRuntime.setTheme("light")

// Follow system theme
UnistylesRuntime.setAdaptiveThemes(true)
Migration Note: The old useAppTheme() hook has been removed. Always use useUnistyles() and UnistylesRuntime for theme access and switching.

Component Showcase

Shipnative includes a visual gallery of all components. Open it via:
  • iOS Simulator: Cmd + D → Component Showcase
  • Android Emulator: Cmd + M → Component Showcase
  • Physical Device: Shake → Component Showcase
You’ll see every component with:
  • All variants and sizes
  • Light and dark mode versions
  • Copy-paste code snippets

Built-in Components

These are ready to use from @/components:
ComponentProps
Buttonvariant: filled, outlined, ghost, danger
TextFieldlabel, error, helper, secureTextEntry
Cardpreset: default, elevated, outlined
Textpreset: heading, subheading, body, caption
Avatarsource, initials, size
BadgeStatus indicators
SpinnerLoading indicator
DividerHorizontal separator
import { Button, Card, Text, TextField } from '@/components'

<Card preset="elevated">
  <Text preset="heading">Welcome</Text>
  <TextField label="Email" placeholder="you@example.com" />
  <Button variant="filled" onPress={handleSubmit}>
    Continue
  </Button>
</Card>

Variants

Unistyles lets you define style variants for different states:
import { StyleSheet, useUnistyles } from 'react-native-unistyles'
import { Pressable, Text } from 'react-native'

type ButtonVariant = 'filled' | 'outlined' | 'ghost'
type ButtonSize = 'sm' | 'md' | 'lg'

interface ButtonProps {
  variant?: ButtonVariant
  size?: ButtonSize
  onPress: () => void
  children: React.ReactNode
}

function Button({ variant = 'filled', size = 'md', onPress, children }: ButtonProps) {
  return (
    <Pressable 
      style={[
        styles.base,
        styles.variants({ variant, size })
      ]} 
      onPress={onPress}
    >
      <Text style={styles.text({ variant })}>{children}</Text>
    </Pressable>
  )
}

const styles = StyleSheet.create((theme) => ({
  base: {
    borderRadius: theme.radius.md,
    justifyContent: 'center',
    alignItems: 'center',
  },
  variants: {
    variants: {
      variant: {
        filled: {
          backgroundColor: theme.colors.primary,
        },
        outlined: {
          borderWidth: 1,
          borderColor: theme.colors.border,
          backgroundColor: 'transparent',
        },
        ghost: {
          backgroundColor: 'transparent',
        },
      },
      size: {
        sm: { height: 36, paddingHorizontal: theme.spacing.md },
        md: { height: 44, paddingHorizontal: theme.spacing.lg },
        lg: { height: 56, paddingHorizontal: theme.spacing.xl },
      },
    },
  },
  text: {
    variants: {
      variant: {
        filled: { color: theme.colors.primaryForeground },
        outlined: { color: theme.colors.foreground },
        ghost: { color: theme.colors.primary },
      },
    },
  },
}))

Responsive Styles

const styles = StyleSheet.create((theme, runtime) => ({
  container: {
    flexDirection: 'column',
    padding: theme.spacing.md,
    
    // Tablet and up
    variants: {
      breakpoint: {
        md: {
          flexDirection: 'row',
          maxWidth: 800,
          alignSelf: 'center',
        },
      },
    },
  },
}))
Breakpoints are defined in apps/app/app/theme/unistyles.ts.

Common Mistakes

MistakeFix
Hardcoded colors like #000000Use theme.colors.foreground
Hardcoded spacing like 16Use theme.spacing.md
Inline styles everywhereUse StyleSheet.create
Missing theme functionUse StyleSheet.create((theme) => ({ ... }))
Using NativeWind/TailwindNativeWind was removed, use Unistyles

Customizing the Theme

Edit apps/app/app/theme/unistyles.ts to change:
export const lightTheme = {
  colors: {
    primary: '#6366F1',        // Your brand color
    primaryForeground: '#fff',
    background: '#ffffff',
    foreground: '#000000',
    // ... more colors
  },
  spacing: {
    xs: 4,
    sm: 8,
    md: 16,
    lg: 24,
    xl: 32,
  },
  // ... typography, radius, shadows
}

export const darkTheme = {
  colors: {
    primary: '#818CF8',        // Slightly lighter for dark mode
    primaryForeground: '#fff',
    background: '#0a0a0a',
    foreground: '#ffffff',
    // ... matching structure
  },
  // Same spacing, typography, etc.
}

Resources

  • Unistyles Documentation
  • Theme file: apps/app/app/theme/unistyles.ts
  • Components: apps/app/app/components/
  • Component Showcase: Dev Menu in running app