Styling

Get started with styling your app.

To build the mobile user interface, TurboStarter comes with Nativewind pre-configured.

Why Nativewind?

Nativewind brings Tailwind CSS utilities to React Native. It lets you style with familiar classes while keeping native performance and platform-appropriate primitives.

Tailwind configuration

In the packages/ui/shared/src/styles directory, you will find shared CSS files with Tailwind configuration. To change global styles, edit the files in this folder.

Here is an example of a shared CSS file that includes the Tailwind CSS configuration:

packages/ui/shared/src/styles/globals.css
@import "tailwindcss";
@import "./themes.css";

@custom-variant dark (&:is(.dark *));

:root {
  --radius: 0.65rem;
}

@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-card: var(--card);
  --color-card-foreground: var(--card-foreground);
  --color-popover: var(--popover);
  --color-popover-foreground: var(--popover-foreground);
  --color-primary: var(--primary);
  --color-primary-foreground: var(--primary-foreground);
  --color-secondary: var(--secondary);
  --color-secondary-foreground: var(--secondary-foreground);
  --color-muted: var(--muted);
  --color-muted-foreground: var(--muted-foreground);
  ...
}

For colors, we rely strictly on CSS Variables in OKLCH format to allow for easy theme management without the need for any JavaScript.

Also, each app has its own globals.css file, which extends the shared config and allows you to override global styles.

Here is an example of an app's globals.css file:

apps/mobile/src/assets/styles/globals.css
import type { Config } from "tailwindcss";
@import "@turbostarter/ui/globals.css";
@import "nativewind/theme";

@theme inline {
  --font-sans: "Geist_400Regular", "sans-serif";
  --font-sans-medium: "Geist_500Medium", "sans-serif";
  --font-sans-semibold: "Geist_600SemiBold", "sans-serif";
  --font-sans-bold: "Geist_700Bold", "sans-serif";
  --font-mono: "GeistMono_400Regular", "monospace";
}

This keeps a clear separation of concerns and a consistent structure for the Tailwind CSS configuration across apps.

Themes

TurboStarter comes with 9+ predefined themes, which you can use to quickly change the look and feel of your app.

They're defined in the packages/ui/shared/src/styles/themes directory. Each theme is a set of variables that can be overridden:

packages/ui/shared/src/styles/themes/orange.css
.theme-orange {
  --background: oklch(1 0 0);
  --foreground: oklch(0.141 0.005 285.823);
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.141 0.005 285.823);
  ...
}

These variables are consumed across platforms. On mobile, the theme provider injects the shared variables into the root view, so Nativewind utility classes like bg-background and text-foreground resolve correctly.

Feel free to add your own themes or override the existing ones to match your brand's identity.

To apply a theme to your app, wrap your tree with the theme provider, which passes the correct variables to your components and screens. It's located at providers/theme.tsx:

apps/mobile/src/lib/providers/theme.tsx
export default function ThemeProvider({
  children,
}: {
  children: React.ReactNode;
}) {
  const { isDark } = useTheme();
  const config = useThemeConfig((state) => state.config);

  return (
    <NavigationThemeProvider value={isDark ? DarkTheme : DefaultTheme}>
      <View
        className={cn("will-change-container flex-1", {
          dark: isDark,
        })}
      >
        <View className={cn("bg-background flex-1", `theme-${config.color}`)}>
          {children}
        </View>
      </View>
    </NavigationThemeProvider>
  );
}

Dark mode

TurboStarter comes with built-in dark mode support.

Each theme has a corresponding set of dark mode variables, which are used to switch the theme to its dark mode counterpart.

packages/ui/shared/src/styles/themes/orange.css
.theme-orange {
  ...
  @variant dark {
    --background: oklch(0.141 0.005 285.823);
    --foreground: oklch(0.985 0 0);
    --card: oklch(0.21 0.006 285.885);
    --card-foreground: oklch(0.985 0 0);
    ...
  }
}

Nativewind reads the system color scheme via useColorScheme and applies dark: variants automatically. With the provider injecting shared variables, dark mode works out of the box.

You can also define the default theme mode and color in the app configuration.

How is this guide?

Last updated on

On this page

Ship your startup everywhere. In minutes.Get TurboStarter