Setting Up Tailwind CSS with NativeWind in Expo

Setting Up Tailwind CSS with NativeWind in Expo: A Simplified Approach
This has been on my mind lately as I navigate frontend development in React Native using Expo. Whenever I encounter a new library or framework, I always worry about version mismatches and setup issues. After several frustrating hours trying to get NativeWind working with Tailwind CSS in an Expo project, I've simplified it down to a few key steps.
The First Steps
For those still struggling, here’s what we’re going to do:
- Install the Necessary Packages
- Set Up Tailwind CSS Properly
- Configure Babel and Metro
- Import Your CSS File Correctly
- Tweak app.json for Web Builds (Optional)
- TypeScript Setup (Optional)
Install the Necessary Packages
Let's start by installing just what we need, not everything in the world:
npm install nativewind
npm install --dev tailwindcss prettier-plugin-tailwindcss
These are the bare essentials to get Tailwind and NativeWind up and running. No extra dependencies or version conflicts.
Set Up Tailwind CSS Properly
Next, we need to set up Tailwind CSS in a way that works with NativeWind:
- Generate the
tailwind.config.jsfile:
npx tailwindcss init -p
- Configure your
tailwind.config.jsfile correctly:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/**/*.{js,jsx,ts,tsx}", "./pages/**/*.{js,jsx,ts,tsx}"],
presets: [require("nativewind/preset")],
theme: {
extend: {},
},
plugins: [],
};
- Create a
global.cssfile and add the Tailwind directives:
@tailwind base;
@tailwind utilities;
@tailwind themes;
Configure Babel and Metro
Now, we need to make sure our build tools are aware of these changes:
- If you don't have a
babel.config.js, create one with this content:
module.exports = function (config) {
config.set(true);
return {
presets: [
["@babel-preset-expo", { runtime: "automatic" }],
"@nativewind/babel-preset"
]
};
}
- Create a
metro.config.jsfile if you don’t have one, and add this:
const { defaultConfig } = require("expo/metro-config");
const { withTheme } = require("theming/metro");
const expConfig = defaultConfig(__dirname);
module.exports = withTheme(expConfig, { themeFile: "./theme.css" });
Import Your CSS File
Ensure that your global.css file is imported at the root of your app:
import "./styles.css";
export default function MyApplication() {
/* Your Application Logic Here */
}
Tweak app.json for Web Builds (Optional)
If you’re working on a project with both web and native builds, make sure Metro is used for web builds in app.json:
{
"react-native": {
"ios": {
"packagerConfig": "metro"
}
}
}
TypeScript Setup (Optional)
For those using TypeScript, create a nativewind-env.d.ts file at the root of your project and add this:
/// <reference types="nativewind/types" />
Result
That's it. By following these steps, you should be able to set up Tailwind CSS with NativeWind in an Expo project without running into version conflicts or setup issues. The only real difference is that I skipped the extra packages and fixed versions recommended by some official documentation.
Happy styling! 🚀