Skip to main content

Overview

NativeWind provides a Babel plugin that transforms your styles at build time. This plugin is a thin wrapper around react-native-css/babel that ensures optimal performance by processing CSS during compilation rather than at runtime.
The Babel plugin is typically configured automatically when using Expo. Manual configuration is only needed for custom setups or React Native CLI projects.

Installation

The Babel plugin is exported from the nativewind/babel package:
import nativewindBabel from 'nativewind/babel';

Configuration

The NativeWind Babel plugin re-exports the react-native-css/babel plugin with all its functionality. It doesn’t add any additional configuration options but provides a consistent import path for NativeWind users.

Basic Setup

Add the plugin to your babel.config.js:
babel.config.js
module.exports = function (api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    plugins: ['nativewind/babel'],
  };
};

With React Native CLI

babel.config.js
module.exports = {
  presets: ['module:@react-native/babel-preset'],
  plugins: ['nativewind/babel'],
};

TypeScript Projects

babel.config.js
module.exports = function (api) {
  api.cache(true);
  return {
    presets: [
      'babel-preset-expo',
      '@babel/preset-typescript',
    ],
    plugins: ['nativewind/babel'],
  };
};

Environment-Specific Configuration

You can configure different behavior for development and production:
babel.config.js
module.exports = function (api) {
  api.cache(true);
  
  const isProduction = api.env('production');
  
  return {
    presets: ['babel-preset-expo'],
    plugins: [
      'nativewind/babel',
      // Add other plugins based on environment
      ...(isProduction ? [] : ['react-native-reanimated/plugin']),
    ],
  };
};

Plugin Order

Plugin order matters in Babel. The NativeWind plugin should generally be placed before other transformation plugins.
babel.config.js
module.exports = {
  presets: ['babel-preset-expo'],
  plugins: [
    'nativewind/babel',
    'react-native-reanimated/plugin', // Must be last
  ],
};
Common plugin ordering rules:
  1. NativeWind plugin - Early in the plugin list
  2. Transform plugins - Middle
  3. Reanimated plugin - Always last (if used)

How It Works

The Babel plugin performs several transformations at build time:
  1. CSS Extraction - Extracts Tailwind classes from className props
  2. Style Generation - Generates optimized StyleSheet objects
  3. Runtime Optimization - Reduces runtime CSS parsing overhead
  4. Type Safety - Works with TypeScript to provide type-safe styling
By processing styles during compilation, NativeWind achieves near-native performance compared to runtime CSS parsing.

Testing Configuration

When running tests with Jest, ensure your Babel configuration applies:
babel.config.js
module.exports = function (api) {
  api.cache(true);
  
  const isTest = api.env('test');
  
  if (isTest) {
    return {
      presets: ['babel-preset-expo'],
      plugins: ['nativewind/babel'],
    };
  }
  
  return {
    presets: ['babel-preset-expo'],
    plugins: ['nativewind/babel'],
  };
};

Re-exported Functionality

The nativewind/babel package re-exports all exports from react-native-css/babel:
export { default } from "react-native-css/babel";
export * from "react-native-css/babel";
This means you get access to all the underlying functionality while maintaining a consistent import path within the NativeWind ecosystem.

Common Patterns

Monorepo Setup

babel.config.js
const path = require('path');

module.exports = function (api) {
  api.cache(true);
  
  return {
    presets: ['babel-preset-expo'],
    plugins: [
      'nativewind/babel',
      [
        'module-resolver',
        {
          root: ['./src'],
          alias: {
            '@components': './src/components',
          },
        },
      ],
    ],
  };
};

With Custom Transformers

babel.config.js
module.exports = {
  presets: ['babel-preset-expo'],
  plugins: [
    'nativewind/babel',
    '@babel/plugin-proposal-export-namespace-from',
    ['@babel/plugin-transform-react-jsx', { runtime: 'automatic' }],
  ],
};

Troubleshooting

Styles not applying

  1. Verify the plugin is in your babel.config.js
  2. Clear Babel cache: npx expo start --clear
  3. Ensure preset order is correct

Build errors

If you encounter build errors:
# Clear all caches
rm -rf node_modules/.cache
npx expo start --clear

# For React Native CLI
rm -rf $TMPDIR/metro-* && npx react-native start --reset-cache

TypeScript errors

Ensure you have both:
  • Babel plugin configured
  • Metro config with withNativewind
  • TypeScript types generated (check for nativewind-env.d.ts)

Performance Considerations

The Babel plugin performs heavy lifting at build time, not runtime. This means:
  • Slower builds (one-time cost)
  • Faster app performance (ongoing benefit)
  • Smaller bundle size (optimized styles)
For large projects, consider:
  • Using persistent caching
  • Enabling Babel’s cache: api.cache(true)
  • Running builds in production mode for optimal output