Skip to main content

Overview

The NativeWind Tailwind CSS plugin extends Tailwind with React Native-specific functionality. It provides the @map variant for mapping CSS properties to platform-specific style names, enabling advanced style transformations.

Installation

Import the plugin in your Tailwind configuration:
import nativewind from 'nativewind';
Or using CommonJS:
const nativewind = require('nativewind');

Plugin Type

const nativewind: PluginCreator
The plugin is created using Tailwind’s plugin.withOptions() API, which allows for future extensibility with custom options.

Configuration

Basic Setup

Add the plugin to your tailwind.config.js or tailwind.config.ts:
tailwind.config.js
import nativewind from 'nativewind';

export default {
  content: ['./app/**/*.{js,jsx,ts,tsx}'],
  presets: [require('nativewind/preset')],
  plugins: [nativewind],
};

With Tailwind CSS v4

tailwind.config.ts
import type { Config } from 'tailwindcss';
import nativewind from 'nativewind';

export default {
  content: ['./app/**/*.{js,jsx,ts,tsx}'],
  plugins: [nativewind],
} satisfies Config;

CommonJS Syntax

tailwind.config.js
const nativewind = require('nativewind');

module.exports = {
  content: ['./app/**/*.{js,jsx,ts,tsx}'],
  plugins: [nativewind],
};

The @map Variant

The primary feature of the NativeWind plugin is the @map variant, which enables CSS property mapping for React Native.

Syntax

@map[-<value>][/<modifier>]:<utility-class>

Parameters

value
string
The CSS property name to map. This value is automatically converted to kebab-case.
modifier
string
The target style property name in React Native. Used when remapping property names.

Basic Usage

Map a style value to a different property:
// Maps text color to a custom native property
<View className="@map-text-color:text-red-500" />
This generates:
@nativeMapping text-color; @media all {
  /* text-red-500 styles */
}

With Value and Modifier

Map a specific value to a specific target:
<View className="@map-shadowColor/elevation:shadow-lg" />
Generates:
@nativeMapping {
  elevation: shadow-color;
}
@media all {
  /* shadow-lg styles */
}

Modifier Only

Move the last style value to a custom property:
<View className="@map/customProp:bg-blue-500" />
Generates:
@nativeMapping customProp; @media all {
  /* bg-blue-500 styles */
}

How It Works

The plugin uses Tailwind’s matchVariant API to create a custom variant:
  1. Value Transformation - Converts camelCase to kebab-case
  2. Escape Handling - Properly escapes special characters like &
  3. @media Wrapper - Wraps mappings in @media all to work around Tailwind’s internal behavior

Kebab-Case Conversion

The plugin automatically converts property names:
// Input
"@map-shadowColor:shadow-lg"

// Converted to
"@map-shadow-color:shadow-lg"
Implementation:
function kebabCase(str: string) {
  return str.replace(
    /[A-Z]+(?![a-z])|[A-Z]/g,
    ($, ofs) => (ofs ? "-" : "") + $.toLowerCase(),
  );
}

Advanced Usage

Platform-Specific Mappings

Combine with platform modifiers:
<View className="
  ios:@map-shadow/elevation:shadow-md
  android:@map-elevation/shadow:shadow-md
" />

Responsive Mappings

<View className="
  @map-fontSize/sm:text-base
  md:@map-fontSize/lg:text-xl
" />

With Custom Utilities

Define custom utilities that work with @map:
tailwind.config.js
import nativewind from 'nativewind';

export default {
  plugins: [
    nativewind,
    function({ addUtilities }) {
      addUtilities({
        '.custom-elevation': {
          shadowColor: '#000',
          shadowOffset: { width: 0, height: 2 },
          shadowOpacity: 0.25,
          shadowRadius: 3.84,
          elevation: 5,
        },
      });
    },
  ],
};

Technical Details

@media all Wrapper

The @media all wrapper is a workaround for Tailwind CSS internals. Without it, the @nativeMapping block wouldn’t properly contain the styles.
From the source code:
/**
 * Adding @media all is a hack for Tailwind CSS which has undocumented behavior
 * If we do this `@nativeMapping { ...values } @slot;` it doesn't work
 * 
 * Adding @slot duplicates the styles and tries to add them into the
 * @nativeMapping block
 * 
 * By adding the `@media all`, Tailwind will add brackets and insert
 * the styles correctly
 * 
 * This leads to weird looking CSS, but it works in browser and React Native
 */

Variant Patterns

The plugin handles three distinct patterns:
  1. Value + Modifier: @map-[value]/[modifier]:class
    • Maps specific value to target property
    • Example: @map-shadowColor/elevation:shadow-lg
  2. Modifier Only: @map/[modifier]:class
    • Moves last style value to modifier
    • Example: @map/customProp:text-red-500
  3. Value Only: @map-[value]:class
    • Maps to native property by value name
    • Example: @map-textColor:text-blue-500

Use Cases

Shadow to Elevation Mapping

Convert iOS shadow styles to Android elevation:
<View className="
  @map-shadowColor/elevation:shadow-lg
  @map-shadowOpacity/elevation:shadow-lg
" />

Custom Property Mappings

Map Tailwind utilities to custom native properties:
<Text className="@map-fontFamily/typeface:font-sans" />

Style Transformations

Transform web-style properties to native equivalents:
<View className="
  @map-backgroundColor/bgColor:bg-white
  @map-borderColor/strokeColor:border-gray-200
" />

Limitations

The @map variant is an advanced feature for specific use cases. For most styling needs, use standard Tailwind utilities which are already optimized for React Native.
  • Only works with properties that exist in React Native’s style system
  • May produce verbose CSS output
  • Requires understanding of both web and native style property names