◉RORK LABJP
●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SDK 58 — Beta since 09/15 with no stable date yet; running projects in Expo Go has required login since 09/03●WIDGET — A write-up traces an iOS widget that renders black only in production builds●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SDK 58 — Beta since 09/15 with no stable date yet; running projects in Expo Go has required login since 09/03●WIDGET — A write-up traces an iOS widget that renders black only in production builds●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…
Articles/Dev Tools
⬡ Dev Tools/2026-04-02Beginner

How to Add NativeWind to Your Rork App: Tailwind CSS Styling for React Native

Learn how to set up NativeWind in your Rork app and style components with Tailwind CSS utility classes. Covers installation, basic layouts, dark mode, and responsive design with practical code examples.

Rork585NativeWindTailwind CSSstylingReact Native239UI10

Setup and context — What Is NativeWind?

If you've ever wished you could style your Rork app's UI with the same ease as web development, NativeWind is the answer. Rork generates React Native code, which typically uses StyleSheet.create for styling — but NativeWind brings the beloved Tailwind CSS utility-first approach directly to React Native.

With NativeWind, you can write className="bg-blue-500 p-4 rounded-lg" on any React Native component, just like you would in a web project. It pairs beautifully with Rork's Expo-based output and can significantly speed up your UI development once configured.

Why Use NativeWind in Your Rork App

There are several compelling reasons to add NativeWind to your Rork project.

Familiar syntax for web developers. If you already know Tailwind CSS, the learning curve is nearly zero. Many Rork users come from a web background, so being able to use the same class names across platforms is a huge productivity win.

Cleaner, more readable code. Traditional StyleSheet.create separates style definitions from component markup, which can hurt readability in larger files. NativeWind keeps styles inline, making components easier to scan and understand at a glance.

Dark mode with minimal effort. Adding the dark: prefix to any class is all it takes to support dark mode — no conditional logic or theme contexts needed.

Setup Instructions

Requirements

  • A Rork-generated Expo project
  • Node.js 18 or higher
  • Expo SDK 50 or higher

Installing Packages

Start by installing NativeWind and Tailwind CSS:

# Install NativeWind v4 and Tailwind CSS
npx expo install nativewind tailwindcss
 
# Generate the Tailwind config file
npx tailwindcss init

Configuring tailwind.config.js

Edit the generated tailwind.config.js to point to your project's source files:

// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  // Apply the NativeWind v4 preset
  presets: [require('nativewind/preset')],
  content: [
    './app/**/*.{js,jsx,ts,tsx}',
    './components/**/*.{js,jsx,ts,tsx}',
    './src/**/*.{js,jsx,ts,tsx}',
  ],
  theme: {
    extend: {
      // Define custom brand colors here
      colors: {
        primary: '#6366f1',
        secondary: '#8b5cf6',
      },
    },
  },
  plugins: [],
};

Updating babel.config.js

Enable NativeWind by updating your Babel configuration:

// babel.config.js
module.exports = function (api) {
  api.cache(true);
  return {
    presets: [
      ['babel-preset-expo', { jsxImportSource: 'nativewind' }],
      'nativewind/babel',
    ],
  };
};

Updating metro.config.js

Configure the Metro bundler to work with NativeWind:

// metro.config.js
const { getDefaultConfig } = require('expo/metro-config');
const { withNativeWind } = require('nativewind/metro');
 
const config = getDefaultConfig(__dirname);
 
module.exports = withNativeWind(config, { input: './global.css' });

Creating global.css

Create a global.css file at the project root:

/* global.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

Importing CSS in Your App Entry Point

Import the CSS file in your app's root layout (app/_layout.tsx):

// app/_layout.tsx
import '../global.css';
import { Stack } from 'expo-router';
 
export default function RootLayout() {
  return <Stack />;
}

Basic Usage

With the setup complete, let's look at how to use NativeWind in practice.

Text and Layout

// components/WelcomeCard.tsx
import { View, Text } from 'react-native';
 
export function WelcomeCard() {
  return (
    // flex-col stacks children vertically, p-6 adds padding, shadow-md gives depth
    <View className="flex-col p-6 bg-white rounded-2xl shadow-md mx-4 my-2">
      {/* text-2xl sets font size, font-bold makes it heavy, text-gray-800 sets color */}
      <Text className="text-2xl font-bold text-gray-800 mb-2">
        Welcome!
      </Text>
      {/* text-base is default size, text-gray-500 is muted, leading-relaxed improves readability */}
      <Text className="text-base text-gray-500 leading-relaxed">
        This is a sample component styled with NativeWind —
        just like Tailwind CSS on the web.
      </Text>
    </View>
  );
}

Button Component

// components/PrimaryButton.tsx
import { TouchableOpacity, Text } from 'react-native';
 
type Props = {
  label: string;
  onPress: () => void;
  variant?: 'primary' | 'secondary';
};
 
export function PrimaryButton({ label, onPress, variant = 'primary' }: Props) {
  return (
    <TouchableOpacity
      onPress={onPress}
      // active:opacity-80 reduces opacity on press for tactile feedback
      className={`
        py-4 px-8 rounded-full active:opacity-80
        ${variant === 'primary' ? 'bg-indigo-500' : 'bg-purple-500'}
      `}
    >
      <Text className="text-white font-semibold text-base text-center">
        {label}
      </Text>
    </TouchableOpacity>
  );
}

Flexbox Grid Layout

NativeWind makes React Native's Flexbox system intuitive with Tailwind's familiar class names:

// components/CardGrid.tsx
import { View, Text } from 'react-native';
 
const items = ['🍎 Apple', '🍊 Orange', '🍋 Lemon', '🍇 Grape'];
 
export function CardGrid() {
  return (
    // flex-row flex-wrap creates a wrapping horizontal layout
    <View className="flex-row flex-wrap gap-3 p-4">
      {items.map((item) => (
        <View
          key={item}
          // w-[48%] sets each card to 48% width for a 2-column grid
          className="w-[48%] bg-yellow-50 border border-yellow-200 rounded-xl p-4 items-center"
        >
          <Text className="text-3xl mb-1">{item.split(' ')[0]}</Text>
          <Text className="text-sm font-medium text-gray-700">
            {item.split(' ')[1]}
          </Text>
        </View>
      ))}
    </View>
  );
}
// Output: a 2-column grid of fruit cards

Dark Mode Support

NativeWind's dark mode support is one of its most powerful features. Just prefix any class with dark: and you're done:

// components/ThemedCard.tsx
import { View, Text, useColorScheme } from 'react-native';
 
export function ThemedCard() {
  const colorScheme = useColorScheme();
 
  return (
    // dark: prefix applies styles only in dark mode
    <View className="
      p-6 mx-4 my-2 rounded-2xl
      bg-white dark:bg-gray-800
      border border-gray-100 dark:border-gray-700
    ">
      <Text className="
        text-xl font-bold mb-2
        text-gray-900 dark:text-white
      ">
        Theme-Aware Card
      </Text>
      <Text className="
        text-sm leading-relaxed
        text-gray-600 dark:text-gray-300
      ">
        This card adapts automatically to light or dark mode.
        Current theme: {colorScheme === 'dark' ? '🌙 Dark' : '☀️ Light'}
      </Text>
    </View>
  );
}

Responsive Design

Tablet-friendly responsive layouts are straightforward with sm: and md: breakpoints:

// components/ResponsiveLayout.tsx
import { View, Text } from 'react-native';
 
export function ResponsiveLayout() {
  return (
    // Stacked on phones, side-by-side on tablets (768px+)
    <View className="flex-col sm:flex-row p-4 gap-4">
      <View className="flex-1 bg-blue-50 rounded-xl p-6">
        <Text className="text-lg font-bold text-blue-800">Left Panel</Text>
        <Text className="text-sm text-blue-600 mt-2">
          Appears on top on mobile devices
        </Text>
      </View>
      <View className="flex-1 bg-green-50 rounded-xl p-6">
        <Text className="text-lg font-bold text-green-800">Right Panel</Text>
        <Text className="text-sm text-green-600 mt-2">
          Sits side by side on tablets
        </Text>
      </View>
    </View>
  );
}

Handy NativeWind Classes to Know

Here's a quick reference for the most-used NativeWind utilities:

Layout

  • flex-1 — fills available space (flex: 1)
  • flex-row — horizontal layout (flexDirection: 'row')
  • items-center — centers children vertically
  • justify-between — space between children

Spacing

  • p-4 — padding 16px
  • m-2 — margin 8px
  • gap-3 — 12px gap between children
  • mb-4 — margin-bottom 16px

Typography

  • text-xl — font size 20px
  • font-bold — bold weight
  • text-gray-700 — medium gray text color
  • leading-relaxed — comfortable line height

Visuals

  • bg-white — white background
  • rounded-xl — 12px border radius
  • shadow-md — medium drop shadow
  • border border-gray-200 — light gray border

Applying NativeWind to Rork-Generated Code

When working with Rork output, you'll typically replace style props with className:

// Rork-generated code (before)
<View style={{ padding: 16, backgroundColor: '#fff', borderRadius: 12 }}>
  <Text style={{ fontSize: 18, fontWeight: 'bold', color: '#111' }}>
    Title
  </Text>
</View>
 
// After applying NativeWind (after)
<View className="p-4 bg-white rounded-xl">
  <Text className="text-lg font-bold text-gray-900">
    Title
  </Text>
</View>

For a deeper dive into structuring reusable components in your Rork project, check out How to Design Reusable React Native Components in Rork. It covers maintainable UI architecture patterns that pair perfectly with NativeWind.

Common Errors and Fixes

Error 1: className has no effect

Double-check your Metro and Babel configs. After making changes, always clear the cache and restart the dev server with expo start --clear.

Error 2: TypeScript type errors on className

Add the NativeWind type reference to your tsconfig.json:

{
  "compilerOptions": {
    "types": ["nativewind/types"]
  }
}

Error 3: Custom classes aren't working

Make sure the file paths in tailwind.config.js under content actually cover the files where you're using NativeWind. Misconfigured paths mean Tailwind can't detect the classes and won't generate the corresponding styles.

If you'd like to improve your overall Rork app UX alongside styling, Rork App UX Design Patterns: Complete Guide is a great companion resource covering interaction design, micro-animations, and screen flow best practices.

Summary

Adding NativeWind to your Rork project unlocks the full power of Tailwind CSS in your React Native UI. While the initial setup involves a few configuration files, the payoff is a dramatically faster and more readable styling workflow — especially if you're already comfortable with Tailwind on the web.

Between dark mode support, responsive breakpoints, and a rich utility class library, NativeWind gives you everything you need to build polished, consistent UIs without wrestling with StyleSheet boilerplate. Give it a try in your next Rork project and see how quickly things come together.

Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

⬡ Dev Tools2026-09-04
EAS secret visibility does not keep a value out of your app — deciding prefix and visibility separately
The EXPO_PUBLIC_ prefix decides what ships inside your app; EAS visibility decides who can read it. Why stacking them blanks a value on OTA updates, and how to check your build.
⬡ Dev Tools2026-08-22
Every bulk replace exited zero. The damage was in the lines I did not delete
Run a bulk replace over generated code and the breakage lands on the neighbouring lines, not the matched ones. Here is what broke in a live project, and a dependency-free guard that checks the invariants a replace must preserve.
⬡ Dev Tools2026-08-14
Find the native edits expo prebuild will erase before you upgrade to SDK 57
Expo SDK 57 makes expo prebuild clear and regenerate ios and android by default. Here is how to audit your hand edits first, move them into config plugins, and why 57.0.9 matters for Reanimated apps.