Skip to main content
This API is marked as unstable and may change in future versions. Use with caution in production code.

Overview

The useUnstableNativeVariable hook provides access to CSS custom properties (CSS variables) in React Native. It allows you to read, set, and react to changes in CSS variables defined in your components or globally in your application.

Import

import { useUnstableNativeVariable } from 'nativewind';

Type Signature

function useUnstableNativeVariable(
  variableName: string,
  defaultValue?: string | number
): [value: string | number | undefined, setValue: (newValue: string | number) => void]

Parameters

variableName
string
required
The name of the CSS variable to access. Should be provided with or without the -- prefix (both --theme-color and theme-color work).
defaultValue
string | number
Optional default value to use if the variable is not defined. Can be a string (like '#ffffff') or a number (like 16).

Return Value

Returns a tuple similar to React’s useState:
value
string | number | undefined
The current value of the CSS variable. Returns undefined if the variable is not set and no default is provided.
setValue
(newValue: string | number) => void
Function to update the CSS variable value. The new value will be propagated to all components that reference this variable.

Usage

import { View, Text } from 'react-native';
import { useUnstableNativeVariable } from 'nativewind';

export default function ThemedCard() {
  const [primaryColor] = useUnstableNativeVariable('--primary-color', '#3B82F6');

  return (
    <View className="p-4 rounded-lg" style={{ backgroundColor: primaryColor }}>
      <Text className="text-white text-lg">Themed Content</Text>
    </View>
  );
}

Advanced Patterns

Using with Tailwind Classes

Combine CSS variables with Tailwind’s var() function:
import { View, Text } from 'react-native';
import { useUnstableNativeVariable } from 'nativewind';

export default function ThemedComponent() {
  const [brandColor, setBrandColor] = useUnstableNativeVariable(
    '--brand-color',
    '#3B82F6'
  );

  return (
    <View
      className="p-4 rounded-lg"
      style={{ '--brand-color': brandColor }}
    >
      <Text className="text-[var(--brand-color)] text-xl font-bold">
        Brand Colored Text
      </Text>
      <View className="bg-[var(--brand-color)] h-1 w-full mt-2" />
    </View>
  );
}

Animated Transitions

Use CSS variables with animations for smooth transitions:
import { useEffect } from 'react';
import { View, Pressable } from 'react-native';
import { useUnstableNativeVariable } from 'nativewind';

export default function AnimatedTheme() {
  const [hue, setHue] = useUnstableNativeVariable('--theme-hue', 200);

  useEffect(() => {
    const interval = setInterval(() => {
      setHue((prev) => ((Number(prev) + 1) % 360));
    }, 50);

    return () => clearInterval(interval);
  }, []);

  return (
    <View
      className="flex-1 items-center justify-center transition-colors duration-300"
      style={{
        backgroundColor: `hsl(${hue}, 70%, 50%)`,
      }}
    />
  );
}

Sharing Variables Across Components

import { View, Text } from 'react-native';
import { useUnstableNativeVariable } from 'nativewind';

function Header() {
  const [headerHeight] = useUnstableNativeVariable('--header-height', 64);

  return (
    <View 
      className="bg-blue-500 items-center justify-center"
      style={{ height: headerHeight }}
    >
      <Text className="text-white text-lg font-bold">Header</Text>
    </View>
  );
}

function Content() {
  const [headerHeight] = useUnstableNativeVariable('--header-height', 64);

  return (
    <View
      className="flex-1 bg-gray-100"
      style={{ marginTop: headerHeight }}
    >
      <Text className="p-4">Content starts below header</Text>
    </View>
  );
}

export default function App() {
  const [headerHeight, setHeaderHeight] = useUnstableNativeVariable(
    '--header-height',
    64
  );

  return (
    <View className="flex-1">
      <Header />
      <Content />
    </View>
  );
}

Best Practices

Recommended use cases:
  • Managing global theme values (colors, spacing, fonts)
  • Creating dynamic, user-customizable themes
  • Sharing design tokens across components
  • Building design systems with consistent variables
Important considerations:
  • This API is marked as unstable and may change
  • Avoid excessive updates as they can impact performance
  • Consider using React Context for complex theme management
  • CSS variable names are case-sensitive

Naming Conventions

Follow consistent naming patterns for CSS variables:
// Good: Semantic, hierarchical naming
'--color-primary'
'--color-primary-dark'
'--spacing-base'
'--spacing-large'
'--font-size-heading'

// Avoid: Generic or unclear names
'--color1'
'--size'
'--x'

Performance Tips

  1. Memoize variable updates when they depend on calculations:
const updateTheme = useCallback((newColor) => {
  setThemeColor(newColor);
}, [setThemeColor]);
  1. Batch updates when changing multiple variables:
const applyTheme = (theme) => {
  // Updates are batched in React
  setPrimaryColor(theme.primary);
  setSecondaryColor(theme.secondary);
  setAccentColor(theme.accent);
};
  1. Use default values to avoid undefined checks:
// With default
const [color] = useUnstableNativeVariable('--color', '#000000');

// Without default - requires checks
const [color] = useUnstableNativeVariable('--color');
const safeColor = color ?? '#000000';

Migration Considerations

Since this API is unstable, plan for potential changes:
  • Encapsulate usage in custom hooks or utilities
  • Document all CSS variable usage in your codebase
  • Monitor NativeWind release notes for API changes
  • Consider alternative approaches for critical features

Abstraction Layer

Create a stable abstraction over the unstable API:
// hooks/useThemeVariable.ts
import { useUnstableNativeVariable } from 'nativewind';

export function useThemeVariable(name: string, defaultValue?: any) {
  return useUnstableNativeVariable(name, defaultValue);
}

// If the API changes, update only this file