Build beautiful, responsive React Native apps with Tailwind CSS — the easy way.
💡 What is NativeWind?
NativeWind lets you use Tailwind CSS classes directly in React Native components. WriteclassName="flex-1 bg-white"instead of verbose stylesheets. 🎨
📋 Prerequisites
Before we begin, make sure you have:
| Tool | Install Command / Link |
|---|---|
| Node.js (LTS) | nodejs.org |
| npm or yarn | Comes with Node.js |
| Expo CLI | npm install -g expo-cli |
| Xcode (for iOS) | App Store ⚠️ macOS only |
| Android Studio (for Android) | developer.android.com |
🍎 iOS Developers: Xcode is ~12GB and required to run the iOS Simulator. Install it early — it takes time!
🤖 Android Developers: Enable a virtual device via Android Studio's Device Manager.
🧱 Step 1: Create and Initialize Project
npx create-expo-app@latest my-app
cd my-app
✅ Test that everything works:
npm run ios
# or
npm run android
| Key | Action |
|---|---|
i |
Open iOS Simulator |
a |
Open Android Emulator |
r |
Reload the app |
d |
Open developer menu |
🔁 Step 2: Reset the Project (Optional Cleanup)
Expo's template includes demo files. Let's start fresh:
npm run reset-project
When prompted:
Do you want to move existing files to /app-example instead of deleting them? (Y/n):
👉 Press n to delete and get a clean Expo Router structure.
🌿 Step 3: Install NativeWind & Dependencies
💡 Keep your Metro bundler running in one terminal. Open a new terminal for installations.
npm install nativewind tailwindcss react-native-reanimated react-native-safe-area-context
| Package | Purpose |
|---|---|
nativewind |
Tailwind for React Native |
tailwindcss |
Core Tailwind engine |
react-native-reanimated |
Smooth animations |
react-native-safe-area-context |
Handle notches & status bars |
🌀 Step 4: Initialize Tailwind
npx tailwindcss init
This creates tailwind.config.js at your project root.
⚙️ Step 5: Update tailwind.config.js
Replace the entire file with:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./App.{js,jsx,ts,tsx}",
"./app/**/*.{js,jsx,ts,tsx}",
"./components/**/*.{js,jsx,ts,tsx}",
"./screens/**/*.{js,jsx,ts,tsx}",
],
presets: [require("nativewind/preset")],
theme: {
extend: {},
},
plugins: [],
};
🔍 The
contentarray tells Tailwind which files to scan for class names.
🎨 Step 6: Create app/globals.css
Inside your app/ folder, create globals.css:
@tailwind base;
@tailwind components;
@tailwind utilities;
This imports Tailwind's utility classes into your app.
🧠 Step 7: Configure Babel — babel.config.js
At your project root, update babel.config.js:
module.exports = function (api) {
api.cache(true);
return {
presets: [
["babel-preset-expo", { jsxImportSource: "nativewind" }],
"nativewind/babel",
],
};
};
✨ This enables NativeWind's CSS-in-JS transformation at build time.
🧩 Step 8: Customize Metro Config
Run the Expo helper:
npx expo customize metro.config.js
Then update metro.config.js:
const { getDefaultConfig } = require("expo/metro-config");
const { withNativeWind } = require("nativewind/metro");
const config = getDefaultConfig(__dirname);
module.exports = withNativeWind(config, { input: "./app/globals.css" });
🔄 This injects NativeWind's CSS processor into Expo's bundler.
📘 Step 9: Add TypeScript Support — nativewind-env.d.ts
At your project root, create:
nativewind-env.d.ts
Add this single line:
/// <reference types="nativewind/types" />
✅ Now your editor will recognize className props with autocomplete!
📂 Step 10: Update app/_layout.tsx
Import your global styles:
import { Stack } from "expo-router";
import "./globals.css";
export default function RootLayout() {
return <Stack />;
}
🧭
expo-routeruses file-based routing —_layout.tsxwraps all screens.
🧱 Step 11: Example Screen — app/index.tsx
Let's test NativeWind with a simple screen:
import { View, Text } from "react-native";
export default function Index() {
return (
<View className="flex-1 items-center justify-center bg-white">
<Text className="text-red-500 text-2xl font-bold">
Hello from NativeWind 🎉
</Text>
</View>
);
}
✅ If you see red, bold, centered text — it's working!
🚀 Step 12: Restart with Cache Clear
Final step — clear Metro's cache to apply all config changes:
npx expo start -c
When prompted:
? Clear Metro bundler cache? (y/N)
👉 Press y
🎯 You're All Set!
✅ Expo + Router
✅ NativeWind + Tailwind CSS
✅ Hot reloading with class names
✅ TypeScript support
✅ iOS & Android ready
🛠️ Troubleshooting Tips
| Issue | Solution |
|---|---|
❌ className not working |
Restart with -c, check babel.config.js
|
| ❌ iOS simulator won't launch | Ensure Xcode is installed + command line tools: xcode-select --install
|
| ❌ Styles not updating | Verify globals.css is imported in _layout.tsx
|
❌ TypeScript errors on className
|
Confirm nativewind-env.d.ts exists at root |
| ❌ Metro bundler stuck | Delete node_modules/.cache and restart |
💡 Pro Tip: Add this to your
package.jsonfor faster dev:"scripts": { "ios:clean": "npx expo start -c --ios", "android:clean": "npx expo start -c --android" }
🧪 Bonus: Quick Test Component
Try this in a new file to see NativeWind in action:
// app/components/TestCard.tsx
import { View, Text } from "react-native";
export default function TestCard() {
return (
<View className="m-4 p-6 bg-blue-100 rounded-2xl shadow-lg">
<Text className="text-blue-800 text-lg font-semibold mb-2">
🚀 NativeWind Works!
</Text>
<Text className="text-gray-600">
Style with Tailwind, no StyleSheet needed.
</Text>
</View>
);
}
Then import it in index.tsx — instant beautiful UI! 🎨
🔗 Helpful Resources
🙌 If this guide saved you time, give it a ❤️, share it with a fellow dev, or drop a comment with what you're building next!
Tags: #ReactNative #Expo #NativeWind #TailwindCSS #MobileDev #WebDevelopment #Beginners #Tutorial
Top comments (0)