Skip to main content

Overview

NativeWind uses Tailwind CSS v4’s plugin system to extend functionality. The framework includes a built-in NativeWind plugin that adds React Native-specific features, and you can create your own plugins to add custom utilities, variants, and behaviors.

NativeWind Plugin

The NativeWind plugin is the core of the framework, providing React Native-specific functionality.

Installation

Register the NativeWind plugin in your theme file:
theme.css
@plugin "nativewind";

@theme {
  /* Your theme configuration */
}
For local development or when using a specific path:
theme.css
@plugin "./node_modules/nativewind/dist/module/plugin.js";

What the Plugin Provides

The NativeWind plugin adds:
  1. @map Variant - Maps CSS properties to React Native component props
  2. Platform Detection - Enables iOS, Android, and native-specific styling
  3. React Native Utilities - Custom utilities for elevation, ripple effects, etc.

The @map Variant

The @map variant is a powerful feature that lets you map CSS values to any React Native component prop.

Basic Usage

Map values to component props:
import { View, Text } from "react-native";

// Map color to the 'tint' prop
<View className="@map/tint:color-blue-500" />

// Map to nested props
<View className="@map/android_ripple.color:color-red-500" />
import { View, Image } from "react-native";

function TintedIcon() {
  return (
    <Image
      source={require("./icon.png")}
      className="w-6 h-6 @map/tint:color-blue-500"
    />
  );
}

Advanced @map Patterns

Mapping to Nested Props

{/* Map to android_ripple.color */}
<Pressable className="@map/android_ripple.color:color-blue-500">
  <Text>Press me</Text>
</Pressable>

{/* Map to style.test.nested */}
<View className="@map/&.test.nested:color-black" />

Using @map with Modifiers

{/* Map fontSize to a custom prop */}
<Text className="@map-[customSize]/fontSize:text-base" />

{/* Map to nested object */}
<View className="@map-[config.theme]/fontSize:text-lg" />

Plugin Implementation

Here’s how the @map variant is implemented in the NativeWind plugin (from /home/daytona/workspace/source/src/plugin.tsx:10-51):
import plugin, { type PluginCreator } from "tailwindcss/plugin";

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

const nativewind: PluginCreator = plugin.withOptions(
  () =>
    ({ matchVariant }) => {
      matchVariant(
        "@map",
        (value = "", { modifier }) => {
          value = kebabCase(value.replace(/&/, "\\&"));

          if (modifier) {
            modifier = modifier.replace(/&/, "\\&");
          }

          if (modifier && value) {
            // @map-[value]/<modifier>:text-red-500
            return `@nativeMapping { ${modifier}:${value} }; @media all`;
          } else if (modifier && !value) {
            // @map/<modifier>:text-red-500
            return `@nativeMapping ${modifier}; @media all`;
          } else if (!modifier && value) {
            return `@nativeMapping ${value}; @media all`;
          } else {
            return "";
          }
        },
        { values: { DEFAULT: undefined } },
      );
    },
);

export default nativewind;
This plugin creates a matchVariant that generates special @nativeMapping CSS at-rules, which the NativeWind runtime uses to map values to component props.

Creating Custom Utilities

Extend NativeWind with custom utility classes using the @utility directive.

React Native-Specific Utilities

Create utilities for React Native props:
theme.css
/* Tint color utility */
@utility tint-* {
  -rn-tint: --value(--color-*);
  @prop -rn-tint tint;
}

/* Android ripple utilities */
@utility ripple-* {
  -rn-ripple-style: --value("borderless");
  -rn-ripple-color: --value(--color-*);
}

@utility ripple-* {
  -rn-ripple-radius: --value(integer);
}

@utility ripple-foreground {
  -rn-ripple-foreground: "foreground";
}

/* Elevation utility (Android shadows) */
@utility elevation-* {
  -rn-elevation: --value(--elevation-*);
}

/* Corner shape utility (iOS) */
@utility corner-* {
  corner-shape: --value("rounded", "squircle");
}
Usage:
import { Image } from "react-native";

<Image
  source={require("./icon.png")}
  className="w-6 h-6 tint-blue-500"
/>

The @prop Directive

The @prop directive maps CSS properties to component props:
@utility tint-* {
  -rn-tint: --value(--color-*);
  @prop -rn-tint tint;  /* Maps -rn-tint to the 'tint' prop */
}
This tells NativeWind to extract the -rn-tint CSS property and apply it to the component’s tint prop.

Custom Variants

Create custom conditional variants using @custom-variant:
theme.css
/* Platform variants */
@custom-variant ios (@media ios);
@custom-variant android (@media android);
@custom-variant native (@media native);
@custom-variant tv (@media (display-mode: tv));

/* Web variant (uses child combinator support as detection) */
@custom-variant web (@supports selector(div > div));

/* Custom device variants */
@custom-variant tablet (@media (min-width: 768px));
@custom-variant desktop (@media (min-width: 1024px));
Usage:
<View className="
  ios:bg-blue-500
  android:bg-green-500
  tablet:p-8
  desktop:p-12
">
  <Text className="native:text-lg web:text-xl">
    Platform-specific styling
  </Text>
</View>

Third-Party Plugins

NativeWind supports Tailwind CSS plugins from the ecosystem.

Safe Area Plugin

Handle device safe areas (notches, home indicators):
theme.css
@plugin "nativewind";
@import "tailwindcss-safe-area";

@theme {
  /* Your configuration */
}
Usage:
import { View, Text } from "react-native";

export default function App() {
  return (
    <View className="flex-1 pt-safe pb-safe">
      <View className="px-4">
        <Text>Content with safe area padding</Text>
      </View>
    </View>
  );
}
Available utilities:
  • pt-safe, pr-safe, pb-safe, pl-safe - Padding for safe areas
  • mt-safe, mr-safe, mb-safe, ml-safe - Margin for safe areas
  • top-safe, right-safe, bottom-safe, left-safe - Position values

Creating Tailwind CSS v4 Plugins

Create a custom plugin file:
my-plugin.js
import plugin from 'tailwindcss/plugin';

export default plugin(function({ matchUtilities, theme }) {
  // Add custom utilities
  matchUtilities(
    {
      'text-shadow': (value) => ({
        textShadowColor: value,
        textShadowOffset: { width: 0, height: 1 },
        textShadowRadius: 2,
      }),
    },
    { values: theme('colors') }
  );
});
Register it:
theme.css
@plugin "./my-plugin.js";
Not all Tailwind plugins are compatible with React Native. Plugins that rely on web-specific CSS features may not work.

Advanced Plugin Patterns

Combining Multiple Custom Properties

theme.css
@utility card {
  background-color: white;
  border-radius: 12px;
  padding: 16px;
  -rn-elevation: 4;
  @prop -rn-elevation elevation;
}

Responsive Custom Utilities

theme.css
@utility container {
  width: 100%;
  padding-left: 16px;
  padding-right: 16px;
  margin-left: auto;
  margin-right: auto;
  
  @media (min-width: 640px) {
    max-width: 640px;
  }
  
  @media (min-width: 768px) {
    max-width: 768px;
    padding-left: 24px;
    padding-right: 24px;
  }
  
  @media (min-width: 1024px) {
    max-width: 1024px;
  }
}

Variant-Aware Utilities

theme.css
@utility btn {
  padding: 12px 24px;
  border-radius: 8px;
  font-weight: 600;
  text-align: center;
  
  &:active {
    opacity: 0.8;
    transform: scale(0.98);
  }
}

@utility btn-primary {
  background-color: var(--color-primary);
  color: white;
}

@utility btn-secondary {
  background-color: var(--color-secondary);
  color: white;
}

Plugin Best Practices

Use Semantic Names

Name utilities based on their purpose, not their appearance (e.g., elevation-card vs elevation-6)

Document Your Utilities

Add comments explaining what custom utilities do and when to use them

Test Cross-Platform

Always test custom utilities on iOS, Android, and web if you support all platforms

Follow Conventions

Match Tailwind’s naming patterns for consistency (e.g., use -* for variants)

Debugging Plugins

Inspect generated CSS to debug plugin output:
npx tailwindcss --output=debug.css --minify=false
Check the generated CSS for your custom utilities and variants.

Complete Plugin Example

Here’s a comprehensive example combining multiple plugin features:
theme.css
@plugin "nativewind";
@import "tailwindcss-safe-area";

@theme {
  /* Brand colors */
  --color-brand: #3b82f6;
  --color-accent: #ec4899;
  
  /* Elevation system */
  --elevation-card: 4;
  --elevation-modal: 8;
  --elevation-drawer: 16;
  
  /* Border radius system */
  --radius-button: 8px;
  --radius-card: 12px;
  --radius-modal: 16px;
}

/* Platform-specific fonts */
:root {
  @media ios {
    --font-sans: System;
  }
  @media android {
    --font-sans: SystemAndroid;
  }
}

/* Custom utilities */
@utility elevation-* {
  -rn-elevation: --value(--elevation-*);
}

@utility tint-* {
  -rn-tint: --value(--color-*);
  @prop -rn-tint tint;
}

@utility ripple-* {
  -rn-ripple-color: --value(--color-*);
}

@utility card {
  background-color: white;
  border-radius: var(--radius-card);
  padding: 16px;
  -rn-elevation: var(--elevation-card);
}

/* Custom variants */
@custom-variant ios (@media ios);
@custom-variant android (@media android);
@custom-variant tablet (@media (min-width: 768px));
@custom-variant desktop (@media (min-width: 1024px));
Usage:
import { View, Text, Image, Pressable } from "react-native";

export default function App() {
  return (
    <View className="flex-1 pt-safe pb-safe bg-gray-50">
      <View className="card m-4 tablet:m-8">
        <View className="flex-row items-center mb-4">
          <Image
            source={require("./icon.png")}
            className="w-8 h-8 tint-brand"
          />
          <Text className="text-xl font-bold ml-2">Custom Plugin Demo</Text>
        </View>
        
        <Pressable className="
          bg-brand p-3 rounded-lg ripple-white
          ios:elevation-card android:elevation-modal
        ">
          <Text className="text-white text-center font-semibold">
            Platform-Aware Button
          </Text>
        </Pressable>
      </View>
    </View>
  );
}

Resources

Tailwind Plugin API

Official Tailwind CSS plugin documentation

NativeWind Source

Explore the NativeWind plugin source code