Skip to main content

React Native CLI Integration

NativeWind works with React Native CLI projects, providing Tailwind CSS styling for native iOS and Android applications. This guide covers setup for React Native 0.81.4 and newer.
This guide is for projects using React Native CLI. If you’re using Expo, see the Expo Setup Guide.

Prerequisites

Before starting, ensure you have:
  • Node.js 20+ installed
  • React Native CLI environment set up (Setup Guide)
  • iOS development environment (macOS only) with Xcode
  • Android development environment with Android Studio

Installation

1

Create a New Project (Optional)

If you don’t have an existing project:
npx react-native init MyApp
cd MyApp
For TypeScript:
npx react-native init MyApp --template react-native-template-typescript
cd MyApp
2

Install Dependencies

Install NativeWind and its peer dependencies:
npm install nativewind tailwindcss react-native-css
For Tailwind CSS v4:
npm install @tailwindcss/postcss
3

Install Additional Dependencies

Install required React Native packages:
npm install react-native-reanimated react-native-worklets
These packages enable:
  • react-native-reanimated: Smooth animations and transitions
  • react-native-worklets: Background thread execution for better performance
4

Link Native Dependencies (if needed)

For React Native 0.60+, auto-linking handles most native dependencies. However, you may need to run:
iOS
cd ios && pod install && cd ..
For Android, native dependencies are linked automatically during build.
After installing react-native-reanimated, you must configure Babel (see next section) and rebuild your app.

Configuration

1

Configure Metro Bundler

Create or update metro.config.js in your project root:
metro.config.js
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const { withNativewind } = require('nativewind/metro');

const config = getDefaultConfig(__dirname);

module.exports = withNativewind(config);
The withNativewind wrapper:
  • Processes CSS files through the NativeWind compiler
  • Generates TypeScript definitions automatically
  • Enables className prop on all React Native components
2

Configure Babel

Update babel.config.js to include React Native Reanimated:
babel.config.js
module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    'react-native-reanimated/plugin',
  ],
};
The Reanimated plugin must be listed last in the plugins array.
3

Configure PostCSS

Create postcss.config.mjs in your project root:
postcss.config.mjs
export default {
  plugins: {
    '@tailwindcss/postcss': {},
  },
};
4

Create Global CSS File

Create global.css in your project root:
global.css
@import "tailwindcss/theme.css" layer(theme);
@import "tailwindcss/preflight.css" layer(base);
@import "tailwindcss/utilities.css";
@import "nativewind/theme";
This imports all necessary Tailwind CSS layers and NativeWind theme extensions.
5

Import Global CSS

Import the CSS file at the top of your App.tsx or index.js:
App.tsx
import './global.css';
import React from 'react';
import { View, Text } from 'react-native';

function App(): React.JSX.Element {
  return (
    <View className="flex-1 justify-center items-center bg-white">
      <Text className="text-2xl font-bold text-blue-500">
        Hello NativeWind!
      </Text>
    </View>
  );
}

export default App;
6

Configure TypeScript (Optional)

NativeWind automatically generates nativewind-env.d.ts:
nativewind-env.d.ts
/// <reference types="react-native-css/types" />
Ensure your tsconfig.json includes this file:
tsconfig.json
{
  "extends": "@tsconfig/react-native/tsconfig.json",
  "compilerOptions": {
    "types": ["react-native-css/types"]
  },
  "include": [
    "**/*.ts",
    "**/*.tsx",
    "nativewind-env.d.ts"
  ]
}

Platform-Specific Configuration

iOS Configuration

1

Install CocoaPods Dependencies

cd ios
pod install
cd ..
2

Update Info.plist for Dark Mode (Optional)

To support dark mode, add to ios/YourApp/Info.plist:
<key>UIUserInterfaceStyle</key>
<string>Automatic</string>

Android Configuration

1

Update MainActivity for Reanimated

If using React Native Reanimated, update android/app/src/main/java/.../MainActivity.java:
MainActivity.java
package com.yourapp;

import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactActivityDelegate;
import android.os.Bundle;

public class MainActivity extends ReactActivity {
  @Override
  protected String getMainComponentName() {
    return "YourApp";
  }
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(null);
  }
  
  @Override
  protected ReactActivityDelegate createReactActivityDelegate() {
    return new DefaultReactActivityDelegate(
      this,
      getMainComponentName(),
      DefaultNewArchitectureEntryPoint.getFabricEnabled()
    );
  }
}
2

Enable Dark Mode (Optional)

Update android/app/src/main/res/values/styles.xml:
styles.xml
<resources>
  <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
    <!-- Your customizations -->
  </style>
</resources>

Usage

Start using Tailwind classes in your components:
App.tsx
import './global.css';
import React from 'react';
import {
  SafeAreaView,
  ScrollView,
  View,
  Text,
  Pressable,
  StatusBar,
  useColorScheme,
} from 'react-native';

function App(): React.JSX.Element {
  const isDarkMode = useColorScheme() === 'dark';
  
  return (
    <SafeAreaView className="flex-1 bg-white dark:bg-gray-900">
      <StatusBar
        barStyle={isDarkMode ? 'light-content' : 'dark-content'}
        backgroundColor="transparent"
      />
      <ScrollView
        contentInsetAdjustmentBehavior="automatic"
        className="flex-1">
        <View className="p-6">
          <View className="bg-white dark:bg-gray-800 rounded-lg shadow-lg p-6 mb-4">
            <Text className="text-3xl font-bold text-gray-900 dark:text-white mb-2">
              Welcome to NativeWind
            </Text>
            <Text className="text-base text-gray-600 dark:text-gray-300 mb-4">
              Style your React Native app with Tailwind CSS
            </Text>
            <Pressable className="bg-blue-500 active:bg-blue-700 px-4 py-3 rounded-md">
              <Text className="text-white font-semibold text-center">
                Get Started
              </Text>
            </Pressable>
          </View>
        </View>
      </ScrollView>
    </SafeAreaView>
  );
}

export default App;

Running Your App

npm start
# or
npx react-native start

# Clear cache if needed
npm start -- --reset-cache
After making configuration changes, rebuild your app completely:
# iOS
cd ios && rm -rf build Pods Podfile.lock && pod install && cd ..

# Android
cd android && ./gradlew clean && cd ..

Platform-Specific Styling

iOS Specific Features

import { View, Text, Platform } from 'react-native';

function Card() {
  return (
    <View className="bg-white ios:shadow-lg rounded-lg p-4">
      <Text className="text-lg font-semibold">
        iOS-specific shadow
      </Text>
    </View>
  );
}

Android Specific Features

Use elevation-* for better shadows on Android:
function Card() {
  return (
    <View className="bg-white android:elevation-4 rounded-lg p-4">
      <Text className="text-lg font-semibold">
        Android elevation
      </Text>
    </View>
  );
}

Troubleshooting

  1. Verify global.css is imported at the top of your app entry
  2. Clear Metro cache: npm start -- --reset-cache
  3. Rebuild the app completely (clean build folders)
  4. Check metro.config.js includes withNativewind
  5. Ensure postcss.config.mjs exists and is configured correctly
  1. Verify nativewind-env.d.ts exists
  2. Add "types": ["react-native-css/types"] to tsconfig.json
  3. Restart TypeScript server in your editor
  4. Check that react-native-css is installed
  1. Clean build folder: cd ios && rm -rf build && cd ..
  2. Reinstall pods: cd ios && pod deintegrate && pod install && cd ..
  3. Clean Xcode derived data
  4. Ensure CocoaPods version is up to date: pod --version
  1. Clean Gradle cache: cd android && ./gradlew clean && cd ..
  2. Delete android/.gradle and android/app/build folders
  3. Invalidate caches in Android Studio
  4. Check minimum SDK version is set correctly
  1. Ensure react-native-reanimated/plugin is last in babel.config.js
  2. Rebuild the app after adding the plugin
  3. Clear Metro cache: npm start -- --reset-cache
  4. Verify correct Reanimated version is installed
  1. Check useColorScheme() hook returns correct value
  2. Use dark: prefix for dark mode classes
  3. Configure platform-specific dark mode settings (Info.plist for iOS, styles.xml for Android)
  4. Test on physical device with dark mode enabled

Advanced Configuration

Custom Metro Configuration

For monorepo or advanced setups:
metro.config.js
const path = require('path');
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const { withNativewind } = require('nativewind/metro');

const config = getDefaultConfig(__dirname);

// Add custom resolver configuration
config.resolver.nodeModulesPaths = [
  path.resolve(__dirname, 'node_modules'),
];

// Add watch folders for monorepo
config.watchFolders = [
  path.resolve(__dirname, '../shared'),
];

module.exports = withNativewind(config, {
  // Disable TypeScript generation if needed
  disableTypeScriptGeneration: false,
  // Custom TypeScript env path
  typescriptEnvPath: 'nativewind-env.d.ts',
  // Enable global className polyfill
  globalClassNamePolyfill: true,
});

Hermes Configuration

NativeWind works with Hermes (React Native’s default JavaScript engine). Ensure Hermes is enabled in your project:
ios/Podfile
use_react_native!(
  :path => config[:reactNativePath],
  :hermes_enabled => true
)
android/app/build.gradle
project.ext.react = [
  enableHermes: true,
]

Brownfield Integration

For integrating NativeWind into existing native apps:
  1. Follow all setup steps above
  2. Ensure React Native is properly integrated
  3. Import global.css in your React Native root component
  4. Rebuild native code after configuration changes

Next Steps

Styling Guide

Learn how to style components with NativeWind

Dark Mode

Implement dark mode in your app

Custom Configuration

Customize NativeWind for your needs

Migration Guide

Migrate from other styling solutions