Skip to main content

Overview

Tailwind v4 lets you extend and override utilities directly in global.css using the @utility and @theme directives — no config file required. This guide covers three common scenarios:
  1. Variable-driven utilities — create a utility whose value is injected at runtime via a CSS variable
  2. Brand-new utilities — add a class that has no Tailwind equivalent
  3. Overriding existing utilities — change what a built-in Tailwind class does

Variable-Driven Utilities

Sometimes you need a utility class whose value isn’t known until runtime. A common example is padding that accounts for a navigation header height, which is only available after the layout renders.

Example: p-safe-header

Step 1 — Declare the variable in global.css Use @theme static so the variable is always available in JavaScript even before it is updated, and define the utility with @utility:
global.css
@theme static ensures --header-height is registered with Uniwind even if it is never used directly in a className. This is required for updateCSSVariables to pick it up.
Step 2 — Inject the real value at runtime Read the header height from react-navigation and push it into the CSS variable using Uniwind.updateCSSVariables:
Step 3 — Use the utility

Brand-New Custom Utilities

Use @utility to define a class that doesn’t exist in Tailwind at all. The CSS you write inside it maps directly to React Native style properties.

Example: card-shadow

global.css
Usage:
Custom utility names must be kebab-case. Tailwind scans your source files for them at build time, so the same dynamic class name rules apply — always write the full class name in source.

Overriding Existing Tailwind Utilities

Override via @theme — change values only

The most common approach: keep the utility name but change what value it resolves to. This works for any design token in Tailwind’s scale.
global.css
All utilities built on those tokens (p-4, px-4, py-4, rounded-lg, etc.) update automatically — no need to touch individual class definitions.

Override via @utility — replace the generated CSS

Use @utility when you want to completely change what a class does, not just adjust its value. Example: make border always use --color-primary By default, border only sets border-width and border-style. Override it to also lock in the border color:
global.css
Now border always renders with the primary color instead of default value (black).

Real-World Example: Border Curve Utilities

iOS supports a borderCurve property that controls how border corners are rendered — continuous produces Apple’s signature “squircle” shape, while circular is the standard round corner. border-continuous and border-circular are built into Uniwind since 1.6.0 / 1.0.0-rc.6 (Pro):
On versions before 1.6.0 / 1.0.0-rc.6 (Pro), you need to add these utilities manually in your global.css:
global.css
This is a good example of how you can use @utility to expose any React Native style property as a Tailwind class.

Best Practices

Prefer @theme for value overrides. It keeps the semantic class name and updates all related utilities in one place.
Use @utility for structural changes or new classes. Reserve it for cases where the default CSS itself needs to change, not just its values.
Only use CSS properties that React Native supports. Web-only properties like background-image, display: grid, or position: fixed have no effect on native.

Global CSS

Full reference for @theme, @utility, and global.css structure

updateCSSVariables

Inject CSS variable values at runtime

useCSSVariable

Read CSS variable values in JavaScript