Skip to main content
Paste’s theming system allows you to easily switch between different visual styles and create consistent themed experiences across your application. The theme provider manages design token values and makes them available to all components.

Theme Provider

The Theme.Provider component wraps your application and provides theme context to all Paste components.

Basic Setup

import { Theme } from '@twilio-paste/core/theme';

function App() {
  return (
    <Theme.Provider theme="default">
      {/* Your app components */}
    </Theme.Provider>
  );
}
Always wrap your application at the root level with Theme.Provider to ensure all Paste components have access to theme values.

Available Themes

Paste includes several built-in themes:

Default Theme

The standard Paste theme with light mode colors.
import { Theme } from '@twilio-paste/core/theme';

function App() {
  return (
    <Theme.Provider theme="default">
      <YourApp />
    </Theme.Provider>
  );
}

Dark Theme

A dark mode theme optimized for low-light environments.
import { Theme } from '@twilio-paste/core/theme';

function App() {
  return (
    <Theme.Provider theme="dark">
      <YourApp />
    </Theme.Provider>
  );
}

Twilio Theme

Twilio-branded theme with Twilio’s color palette.
import { Theme } from '@twilio-paste/core/theme';

function App() {
  return (
    <Theme.Provider theme="twilio">
      <YourApp />
    </Theme.Provider>
  );
}

Twilio Dark Theme

Dark variant of the Twilio-branded theme.
import { Theme } from '@twilio-paste/core/theme';

function App() {
  return (
    <Theme.Provider theme="twilio-dark">
      <YourApp />
    </Theme.Provider>
  );
}

SendGrid Theme

SendGrid-branded theme.
import { Theme } from '@twilio-paste/core/theme';

function App() {
  return (
    <Theme.Provider theme="sendgrid">
      <YourApp />
    </Theme.Provider>
  );
}

Evergreen Theme

Evergreen theme variant.
import { Theme } from '@twilio-paste/core/theme';

function App() {
  return (
    <Theme.Provider theme="evergreen">
      <YourApp />
    </Theme.Provider>
  );
}

Theme Constants

Available theme options are exported as constants:
import { ThemeVariants } from '@twilio-paste/core/theme';

// Available values:
// ThemeVariants.DEFAULT - "default"
// ThemeVariants.DARK - "dark"
// ThemeVariants.TWILIO - "twilio"
// ThemeVariants.TWILIO_DARK - "twilio-dark"
// ThemeVariants.SENDGRID - "sendgrid"
// ThemeVariants.EVERGREEN - "evergreen"

function App() {
  return (
    <Theme.Provider theme={ThemeVariants.DARK}>
      <YourApp />
    </Theme.Provider>
  );
}

Switching Themes Dynamically

You can switch themes at runtime by changing the theme prop:
import React from 'react';
import { Theme } from '@twilio-paste/core/theme';
import { Button } from '@twilio-paste/core/button';
import { Box } from '@twilio-paste/core/box';

function App() {
  const [currentTheme, setCurrentTheme] = React.useState('default');

  const toggleTheme = () => {
    setCurrentTheme(currentTheme === 'default' ? 'dark' : 'default');
  };

  return (
    <Theme.Provider theme={currentTheme}>
      <Box padding="space60">
        <Button onClick={toggleTheme}>
          Switch to {currentTheme === 'default' ? 'Dark' : 'Light'} Theme
        </Button>
      </Box>
    </Theme.Provider>
  );
}

Theme Provider Props

The Theme Provider accepts several configuration options:

theme

The theme variant to use.
<Theme.Provider theme="dark">
  <YourApp />
</Theme.Provider>

customBreakpoints

Custom responsive breakpoints for your application.
<Theme.Provider 
  theme="default" 
  customBreakpoints={['640px', '768px', '1024px', '1280px']}
>
  <YourApp />
</Theme.Provider>

disableAnimations

Disable all animations in Paste components.
<Theme.Provider theme="default" disableAnimations>
  <YourApp />
</Theme.Provider>
This respects user preferences for reduced motion automatically.

cacheProviderProps

Custom Emotion cache configuration.
<Theme.Provider 
  theme="default" 
  cacheProviderProps={{ key: 'custom-cache' }}
>
  <YourApp />
</Theme.Provider>

Accessing Theme Values

useTheme Hook

Access the current theme object in any component:
import { useTheme } from '@twilio-paste/core/theme';

function MyComponent() {
  const theme = useTheme();
  
  return (
    <div style={{
      backgroundColor: theme.backgroundColors.colorBackground,
      padding: theme.space.space60,
      borderRadius: theme.radii.borderRadius30,
    }}>
      Custom themed component
    </div>
  );
}

Theme Consumer

Access theme using React Context Consumer:
import { Theme } from '@twilio-paste/core/theme';

function MyComponent() {
  return (
    <Theme.Consumer>
      {({ theme }) => (
        <div style={{
          color: theme.textColors.colorText,
          backgroundColor: theme.backgroundColors.colorBackground,
        }}>
          Themed content
        </div>
      )}
    </Theme.Consumer>
  );
}

withTheme Higher-Order Component

Wrap components to inject the theme as a prop:
import React from 'react';
import { withTheme } from '@twilio-paste/core/theme';

function MyComponent({ theme }) {
  return (
    <div style={{ color: theme.textColors.colorText }}>
      Themed with HOC
    </div>
  );
}

export default withTheme(MyComponent);

Theme Object Structure

The theme object contains all design tokens organized by category:
{
  // Colors
  backgroundColors: {
    colorBackground: '#f4f4f6',
    colorBackgroundPrimary: '#0263e0',
    // ...
  },
  textColors: {
    colorText: '#121c2d',
    colorTextWeak: '#606b85',
    // ...
  },
  borderColors: {
    colorBorder: '#cacdd8',
    // ...
  },
  
  // Spacing
  space: {
    space0: '0',
    space10: '0.25rem',  // 4px
    space20: '0.5rem',   // 8px
    space60: '1.5rem',   // 24px
    // ...
  },
  
  // Typography
  fontSizes: {
    fontSize10: '0.75rem',
    fontSize30: '0.875rem',
    // ...
  },
  fontWeights: {
    fontWeightNormal: 400,
    fontWeightBold: 700,
    // ...
  },
  fonts: {
    fontFamilyText: '"Inter", sans-serif',
    fontFamilyCode: '"Courier Prime", monospace',
  },
  
  // Border & Effects
  radii: {
    borderRadius10: '2px',
    borderRadius30: '4px',
    // ...
  },
  shadows: {
    shadow: '0 2px 4px rgba(0, 0, 0, 0.08)',
    // ...
  },
  
  // Responsive
  breakpoints: ['640px', '768px', '1024px', '1280px'],
}

CSS Variables Theme

Paste supports using CSS variables for theming:
import { Theme } from '@twilio-paste/core/theme';

function App() {
  return (
    <Theme.Provider useCSSVariables>
      <YourApp />
    </Theme.Provider>
  );
}
This generates CSS custom properties that can be overridden:
:root {
  --paste-color-background: #ffffff;
  --paste-color-text: #121c2d;
  /* ... */
}

Multiple Theme Providers

You can nest Theme Providers to use different themes in different parts of your app:
import { Theme } from '@twilio-paste/core/theme';
import { Box } from '@twilio-paste/core/box';

function App() {
  return (
    <Theme.Provider theme="default">
      <Box padding="space60">
        <h1>Light Theme Section</h1>
        
        <Theme.Provider theme="dark">
          <Box padding="space60" backgroundColor="colorBackground">
            <h2>Dark Theme Section</h2>
          </Box>
        </Theme.Provider>
      </Box>
    </Theme.Provider>
  );
}

Theme Contrast Checking

Paste provides utilities to check color contrast compliance:
import { useThemeContrastCheck } from '@twilio-paste/core/theme';

function ContrastChecker() {
  const {
    textContrastRating,
    uiControlContrastRating,
    numberOfTextFailures,
    numberOfUIControlFailures,
    totalFailures,
  } = useThemeContrastCheck();

  return (
    <div>
      <p>Text Contrast: {textContrastRating}</p>
      <p>UI Control Contrast: {uiControlContrastRating}</p>
      <p>Total Failures: {totalFailures}</p>
    </div>
  );
}
Use this hook inside a Theme.Provider or CustomizationProvider for it to work correctly.

Best Practices

Do’s

  • Wrap at root level: Place Theme.Provider as high as possible in your component tree
  • Use theme hooks: Access theme values through useTheme when needed
  • Respect user preferences: The theme provider automatically respects prefers-reduced-motion
  • Test themes: Ensure your UI works well in all themes you support

Don’ts

  • Don’t hardcode theme values: Always use tokens or theme object
  • Don’t create multiple providers unnecessarily: One provider at the root is usually enough
  • Don’t mix theming approaches: Choose either Theme.Provider or CustomizationProvider

Next Steps

Build docs developers (and LLMs) love