DEV Community

Cover image for โšก๏ธ Complete Setup Guide: Expo + NativeWind (2026 Edition)
Nabin Kandel
Nabin Kandel

Posted on

โšก๏ธ Complete Setup Guide: Expo + NativeWind (2026 Edition)

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. Write className="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
Enter fullscreen mode Exit fullscreen mode

โœ… Test that everything works:

npm run ios
# or
npm run android
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode

When prompted:

Do you want to move existing files to /app-example instead of deleting them? (Y/n):
Enter fullscreen mode Exit fullscreen mode

๐Ÿ‘‰ 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
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode

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: [],
};
Enter fullscreen mode Exit fullscreen mode

๐Ÿ” The content array 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;
Enter fullscreen mode Exit fullscreen mode

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",
    ],
  };
};
Enter fullscreen mode Exit fullscreen mode

โœจ 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
Enter fullscreen mode Exit fullscreen mode

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" });
Enter fullscreen mode Exit fullscreen mode

๐Ÿ”„ 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
Enter fullscreen mode Exit fullscreen mode

Add this single line:

/// <reference types="nativewind/types" />
Enter fullscreen mode Exit fullscreen mode

โœ… 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 />;
}
Enter fullscreen mode Exit fullscreen mode

๐Ÿงญ expo-router uses file-based routing โ€” _layout.tsx wraps 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>
  );
}
Enter fullscreen mode Exit fullscreen mode

โœ… 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
Enter fullscreen mode Exit fullscreen mode

When prompted:

? Clear Metro bundler cache? (y/N)
Enter fullscreen mode Exit fullscreen mode

๐Ÿ‘‰ 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.json for 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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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 (1)

Collapse
 
alexandersstudi profile image
Alexander

Mapping your Figma variables directly into the tailwind.config.js file is the best way to scale a NativeWind setup. It turns the configuration into a strict design system contract for your React Native components. Piping Style Dictionary outputs straight into those Tailwind theme extensions keeps everything perfectly synced.