Skip to main content

Overview

The VariableContextProvider component allows you to inject CSS variables into your component tree. This is useful for creating dynamic themes, managing design tokens, and providing runtime styling values to your NativeWind components.

Import

import { VariableContextProvider } from 'nativewind';

Basic Usage

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

const StyledView = styled(View);
const StyledText = styled(Text);

export default function App() {
  const variables = {
    '--primary-color': '#3b82f6',
    '--secondary-color': '#8b5cf6',
    '--text-color': '#1f2937',
  };

  return (
    <VariableContextProvider variables={variables}>
      <StyledView className="flex-1 items-center justify-center">
        <StyledText className="text-[--primary-color] text-2xl font-bold">
          Themed Text
        </StyledText>
      </StyledView>
    </VariableContextProvider>
  );
}

Props

variables
Record<string, string | number>
required
An object containing CSS variable names (with -- prefix) and their values. Values can be strings (colors, units) or numbers.
{
  '--primary-color': '#3b82f6',
  '--spacing': 16,
  '--border-radius': '8px',
  '--font-size': '14px',
}
children
React.ReactNode
required
The component tree that will have access to the provided CSS variables.

Advanced Usage

Design Tokens System

import { VariableContextProvider } from 'nativewind';

// Design tokens
const designTokens = {
  // Colors
  '--color-primary': '#3b82f6',
  '--color-secondary': '#8b5cf6',
  '--color-success': '#10b981',
  '--color-error': '#ef4444',
  '--color-warning': '#f59e0b',
  
  // Spacing
  '--spacing-xs': '4px',
  '--spacing-sm': '8px',
  '--spacing-md': '16px',
  '--spacing-lg': '24px',
  '--spacing-xl': '32px',
  
  // Typography
  '--font-size-sm': '12px',
  '--font-size-base': '14px',
  '--font-size-lg': '16px',
  '--font-size-xl': '20px',
  '--font-size-2xl': '24px',
  
  // Borders
  '--border-radius-sm': '4px',
  '--border-radius-md': '8px',
  '--border-radius-lg': '12px',
  '--border-radius-full': '9999px',
};

export default function App() {
  return (
    <VariableContextProvider variables={designTokens}>
      {/* Your app */}
    </VariableContextProvider>
  );
}

Component-Level Variables

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

const StyledView = styled(View);
const StyledText = styled(Text);

function Card({ children, variant = 'default' }) {
  const variantVariables = {
    default: {
      '--card-bg': '#ffffff',
      '--card-border': '#e5e7eb',
      '--card-text': '#1f2937',
    },
    success: {
      '--card-bg': '#d1fae5',
      '--card-border': '#10b981',
      '--card-text': '#065f46',
    },
    error: {
      '--card-bg': '#fee2e2',
      '--card-border': '#ef4444',
      '--card-text': '#991b1b',
    },
  }[variant];

  return (
    <VariableContextProvider variables={variantVariables}>
      <StyledView className="bg-[--card-bg] border-2 border-[--card-border] p-4 rounded-lg">
        <StyledText className="text-[--card-text]">{children}</StyledText>
      </StyledView>
    </VariableContextProvider>
  );
}

User Preferences

import { useState, useEffect } from 'react';
import { VariableContextProvider, styled } from 'nativewind';
import { View, Text } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';

const StyledView = styled(View);
const StyledText = styled(Text);

function App() {
  const [userPreferences, setUserPreferences] = useState({
    '--font-scale': '1',
    '--contrast': 'normal',
  });

  useEffect(() => {
    // Load user preferences
    AsyncStorage.getItem('userPreferences').then((prefs) => {
      if (prefs) setUserPreferences(JSON.parse(prefs));
    });
  }, []);

  const variables = {
    '--primary-color': '#3b82f6',
    '--base-font-size': '14px',
    ...userPreferences,
  };

  return (
    <VariableContextProvider variables={variables}>
      <StyledView className="flex-1">
        <StyledText className="text-[calc(var(--base-font-size)*var(--font-scale))]">
          Accessible Text
        </StyledText>
      </StyledView>
    </VariableContextProvider>
  );
}

Responsive Variables

import { useState, useEffect } from 'react';
import { Dimensions } from 'react-native';
import { VariableContextProvider, styled } from 'nativewind';
import { View, Text } from 'react-native';

const StyledView = styled(View);
const StyledText = styled(Text);

function App() {
  const [dimensions, setDimensions] = useState(Dimensions.get('window'));

  useEffect(() => {
    const subscription = Dimensions.addEventListener('change', ({ window }) => {
      setDimensions(window);
    });
    return () => subscription?.remove();
  }, []);

  const variables = {
    '--screen-width': `${dimensions.width}px`,
    '--screen-height': `${dimensions.height}px`,
    '--is-tablet': dimensions.width >= 768 ? '1' : '0',
    '--container-width': dimensions.width >= 768 ? '720px' : '100%',
  };

  return (
    <VariableContextProvider variables={variables}>
      <StyledView className="flex-1 items-center">
        <StyledView className="w-[--container-width] p-4">
          <StyledText className="text-lg">
            Responsive Container
          </StyledText>
        </StyledView>
      </StyledView>
    </VariableContextProvider>
  );
}

Variable Naming Conventions

CSS Variable Format: All CSS variables must start with -- (double dash). This is the standard CSS custom property syntax.
// Good
{ '--primary-color': '#3b82f6' }

// Bad
{ 'primary-color': '#3b82f6' }
{ 'primaryColor': '#3b82f6' }
const variables = {
  // Semantic naming (what it means)
  '--color-primary': '#3b82f6',
  '--color-danger': '#ef4444',
  '--spacing-content': '16px',
  
  // Component-specific
  '--button-bg': '#3b82f6',
  '--card-shadow': 'rgba(0, 0, 0, 0.1)',
  
  // State-based
  '--active-opacity': '0.8',
  '--disabled-color': '#9ca3af',
  
  // Scale-based
  '--font-size-1': '12px',
  '--font-size-2': '14px',
  '--font-size-3': '16px',
};

Using Variables in Styles

Variables can be referenced in className using CSS variable syntax:
import { styled } from 'nativewind';
import { View, Text } from 'react-native';

const StyledView = styled(View);
const StyledText = styled(Text);

function Example() {
  return (
    <>
      {/* Direct variable reference */}
      <StyledView className="bg-[--primary-color]" />
      
      {/* With fallback */}
      <StyledView className="bg-[--primary-color,#3b82f6]" />
      
      {/* In arbitrary values */}
      <StyledView className="shadow-[0_4px_6px_--shadow-color]" />
      
      {/* In spacing */}
      <StyledView className="p-[--spacing-md]" />
      
      {/* In text */}
      <StyledText className="text-[--font-size-lg] text-[--text-color]" />
    </>
  );
}

Performance Considerations

Avoid Frequent Updates: Updating variables triggers re-renders in child components. For frequently changing values (like animations), consider using other approaches:
// Avoid this for animations
const [animValue, setAnimValue] = useState(0);
const variables = { '--anim-value': `${animValue}px` };

// Use Animated API or CSS animations instead
import { Animated } from 'react-native';

Best Practices

  1. Define variables at the root: Place global variables at the app root level
  2. Use semantic names: Name variables by purpose, not appearance
  3. Group related variables: Organize variables by category (colors, spacing, etc.)
  4. Provide fallbacks: Include fallback values when using variables in styles
  5. Type your variables: Use TypeScript for type safety
type DesignTokens = {
  '--primary-color': string;
  '--secondary-color': string;
  '--spacing-unit': string;
};

const tokens: DesignTokens = {
  '--primary-color': '#3b82f6',
  '--secondary-color': '#8b5cf6',
  '--spacing-unit': '8px',
};
  • styled - Create styled components that can use CSS variables
  • useUnstableNativeVariable - Hook to access CSS variables in components
  • vars - Alternative API for working with CSS variables