How to Add NativeWind (Tailwind for React Native) in an Expo Project

If you love the speed and flexibility of Tailwind CSS, you’ll be happy to know you can use it directly in React Native through NativeWind. With the release of NativeWind v4, the setup is smoother and supports Expo SDK 50+ and React Native 0.74+.

In this guide, we’ll walk step-by-step to add NativeWind to a new Expo project.

Step 1: Install Dependencies

In your Expo project folder, run:

npx expo install nativewind react-native-reanimated react-native-safe-area-context
npm i -D tailwindcss prettier-plugin-tailwindcss

  • nativewind → Tailwind styling for RN
  • react-native-reanimated & react-native-safe-area-context → required peer deps
  • tailwindcss → the actual Tailwind engine
  • prettier-plugin-tailwindcss → keeps your class names sorted (optional but nice)

Step 2: Initialize Tailwind

Create a Tailwind config:

npx tailwindcss init

Edit the generated tailwind.config.js to include your files and the NativeWind preset:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./App.{js,jsx,ts,tsx}",
    "./app/**/*.{js,jsx,ts,tsx}",
    "./src/**/*.{js,jsx,ts,tsx}"
  ],
  presets: [require("nativewind/preset")],
  theme: {
    extend: {},
  },
  plugins: [],
};

Make sure the content globs match where your .tsx files live.

Step 3: Create a Global CSS File

Create a file named global.css in your project root:

@tailwind base;
@tailwind components;
@tailwind utilities;

This is the input file NativeWind uses to generate classes.

Step 4: Configure Babel

Edit babel.config.js:

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

This tells Expo to process JSX with NativeWind.

Step 5: Configure Metro

Edit 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" });

Now Metro will read your global CSS file when bundling.

Step 6: Import Global CSS

At the very top of your App.tsx (or entry file):

import "./global.css";

Step 7: Web Setup (Optional)

If you want to run your project in the browser (expo start --web), add this to app.json:

{
  "expo": {
    "web": {
      "bundler": "metro"
    }
  }
}

Step 8: TypeScript Setup

If you’re using TypeScript, create a file called nativewind-env.d.ts (the name matters):

/// <reference types="nativewind/types" />

Step 9: Restart with Cache Clear

npx expo start -c
This ensures Tailwind classes are picked up correctly.

Step 10: Test It Out 🎉

Try this in App.tsx:

import { View, Text } from "react-native";
import "@/global.css";

export default function App() {
  return (
    <View className="flex-1 items-center justify-center bg-white">
      <Text className="text-xl font-bold text-blue-500">
        Welcome to NativeWind!
      </Text>
    </View>
  );
}

If you see a blue bold heading, congrats! NativeWind is working.


Common Gotchas
  • Classes not working? Double-check content paths in tailwind.config.js.
  • Not updating styles? Run expo start -c to clear cache.
  • Tailwind v4? Not supported yet — use Tailwind v3.4.

Tripti

Leave a Reply

Your email address will not be published. Required fields are marked *