React Native
NativeWind works with both Expo and framework-less React Native projects but Expo provides a more streamlined experience.
Web: If you wish to use Metro to bundle for website or App Clip and you are not using Expo, you will need either: Expo's Metro config @expo/metro-config
or manually use Tailwind CLI to generate a CSS file.
Installation
1. Install NativeWind
You will need to install nativewind
and it's peer dependencies tailwindcss
, react-native-reanimated
and react-native-safe-area-context
- npm
- yarn
- pnpm
- Expo
npm install nativewind tailwindcss react-native-reanimated react-native-safe-area-context
yarn add nativewind tailwindcss react-native-reanimated react-native-safe-area-context
pnpm install nativewind tailwindcss react-native-reanimated react-native-safe-area-context
npx expo install nativewind tailwindcss react-native-reanimated react-native-safe-area-context
Non-Expo projects
Run pod-install
to finish installation of react-native-reanimated
npx pod-install
2. Setup Tailwind CSS
Run npx tailwindcss init
to create a tailwind.config.js
file
Add the paths to all of your component files in your tailwind.config.js file.
/** @type {import('tailwindcss').Config} */
module.exports = {
// NOTE: Update this to include the paths to all of your component files.
content: ["./app/**/*.{js,jsx,ts,tsx}"],
presets: [require("nativewind/preset")],
theme: {
extend: {},
},
plugins: [],
}
Create a CSS file and add the Tailwind directives
@tailwind base;
@tailwind components;
@tailwind utilities;
From here onwards, replace ./global.css
with the relative path to the CSS file you just created
3. Add the Babel preset
- Expo SDK 50+
- Expo SDK 49
- Framework-less
module.exports = function (api) {
api.cache(true);
return {
presets: [
["babel-preset-expo", { jsxImportSource: "nativewind" }],
"nativewind/babel",
],
};
};
module.exports = function (api) {
api.cache(true);
return {
presets: [
["babel-preset-expo", { jsxImportSource: "nativewind" }],
"nativewind/babel",
],
plugins: [
// Required for expo-router
"expo-router/babel",
"react-native-reanimated/plugin",
]
};
};
module.exports = {
- presets: ['<existing presets>'],
+ presets: ['<existing presets>', 'nativewind/babel'],
};
4. Modify your metro.config.js
- Expo SDK 49
- Expo SDK 50+
- Framework-less
const { getDefaultConfig } = require("expo/metro-config");
const { withNativeWind } = require('nativewind/metro');
const config = getDefaultConfig(__dirname, { isCSSEnabled: true })
module.exports = withNativeWind(config, { input: './global.css' })
const { getDefaultConfig } = require("expo/metro-config");
const { withNativeWind } = require('nativewind/metro');
const config = getDefaultConfig(__dirname)
module.exports = withNativeWind(config, { input: './global.css' })
const { getDefaultConfig, mergeConfig } = require("@react-native/metro-config");
const { withNativeWind } = require("nativewind/metro");
const config = mergeConfig(getDefaultConfig(__dirname), {
/* your config */
});
module.exports = withNativeWind(config, { input: "./global.css" });
5. Import your CSS file
import "./global.css"
export default App() {
/* Your App */
}
6. Modify your app.json
(Expo only)
Switch the bundler to use the Metro bundler
{
"expo": {
"web": {
"bundler": "metro"
}
}
}
7. TypeScript (optional)
Please follow the TypeScript guide.