# How to Implement RTL Support in Material-UI Using the Stylis Plugin

> Easily add RTL support to Material-UI. Configure your theme and Emotion cache with the stylis plugin for seamless right-to-left implementation.

- Repository: [MUI/material-ui](https://github.com/mui/material-ui)
- Tags: how-to-guide
- Published: 2026-02-26

---

**To implement RTL support in Material-UI, configure your theme with `direction: 'rtl'` and create an Emotion cache that includes the `stylis-plugin-rtl` plugin, then wrap your application with both `CacheProvider` and `ThemeProvider`.**

Material-UI (MUI) uses Emotion as its styling engine, processing CSS through the Stylis preprocessor at runtime. To implement RTL support in Material-UI using the Stylis plugin, you must configure both the theme direction and the Emotion cache to automatically mirror physical CSS properties for right-to-left languages.

## How RTL Works in Material-UI

MUI provides two complementary mechanisms that work together to enable RTL support:

| Mechanism | Purpose | Source Location |
|-----------|---------|-----------------|
| `theme.direction` | Sets the logical direction (`'ltr'` or `'rtl'`) on the theme. Components using logical CSS properties reference this value. | [`packages/mui-material/src/theme/defaultTheme.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/theme/defaultTheme.ts) |
| **stylis-plugin-rtl** | A Stylis plugin injected into Emotion's cache that rewrites CSS rules to flip physical properties (`margin-left`, `right`, etc.) when the direction is RTL. | [`packages/mui-styles/src/cache.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-styles/src/cache.ts) |

The plugin operates at the cache level, meaning all generated styles—including custom `styled` components—are transformed without requiring component-level changes.

## Step-by-Step Implementation

### Install Required Dependencies

Install Material-UI, Emotion, and the RTL plugin:

```bash
npm install @mui/material @emotion/react @emotion/cache stylis-plugin-rtl

```

### Create an RTL-Enabled Emotion Cache

Create a cache instance that includes the Stylis RTL plugin. This configuration mirrors the approach used internally in [`packages/mui-styles/src/cache.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-styles/src/cache.ts):

```typescript
import createCache from '@emotion/cache';
import rtlPlugin from 'stylis-plugin-rtl';

export const rtlCache = createCache({
  key: 'mui-rtl',
  stylisPlugins: [rtlPlugin],
});

```

The `key` property ensures this cache does not clash with default Emotion caches, while `stylisPlugins` array injects the RTL transformation logic.

### Configure the MUI Theme for RTL

Set the `direction` property when creating your theme. This value is defined in [`packages/mui-material/src/theme/defaultTheme.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/theme/defaultTheme.ts) and processed by [`packages/mui-material/src/theme/createTheme.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/theme/createTheme.ts):

```typescript
import { createTheme } from '@mui/material/styles';

const theme = createTheme({
  direction: 'rtl',
  // Additional customizations (palette, typography, etc.)
});

```

### Wrap Your Application with Providers

Combine the cache and theme providers at your application root. This pattern ensures all child components receive the RTL-transformed styles:

```tsx
import * as React from 'react';
import { CacheProvider } from '@emotion/react';
import { ThemeProvider } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import { rtlCache } from './rtlCache';
import { theme } from './theme';
import App from './App';

export default function Root() {
  return (
    <CacheProvider value={rtlCache}>
      <ThemeProvider theme={theme}>
        <CssBaseline />
        <App />
      </ThemeProvider>
    </CacheProvider>
  );
}

```

`CssBaseline` automatically respects the theme direction, setting the HTML `dir` attribute and adjusting global styles accordingly.

### Verify RTL with Custom Styled Components

Custom components created with the `styled` API automatically inherit RTL support because they use the same Emotion cache. As implemented in [`packages/mui-material/src/styles/experimentalStyled.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/styles/experimentalStyled.ts), physical properties are mirrored without additional code:

```tsx
import { styled } from '@mui/material/styles';
import Button from '@mui/material/Button';

const FancyButton = styled(Button)(({ theme }) => ({
  // In RTL mode, margin-left becomes margin-right automatically
  marginLeft: theme.spacing(2),
  padding: '8px 16px',
}));

export default function Demo() {
  return <FancyButton>مرحبا بالعالم</FancyButton>;
}

```

## Key Source Files and Architecture

Understanding the underlying implementation helps debug edge cases:

- **[`packages/mui-material/src/theme/defaultTheme.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/theme/defaultTheme.ts)**: Defines the default `direction: 'ltr'` value and theme structure.
- **[`packages/mui-material/src/theme/createTheme.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/theme/createTheme.ts)**: Merges user configuration (including RTL direction) with the default theme.
- **[`packages/mui-styles/src/cache.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-styles/src/cache.ts)**: Provides utilities for creating Emotion caches; the RTL implementation follows this pattern by injecting `stylisPlugins`.
- **[`packages/mui-material/src/ThemeProvider/ThemeProvider.tsx`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/ThemeProvider/ThemeProvider.tsx)**: Injects the theme (and thus `direction`) into the React context tree.
- **[`packages/mui-material/src/CssBaseline/CssBaseline.tsx`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/CssBaseline/CssBaseline.tsx)**: Applies global RTL styles based on the theme direction.
- **[`packages/mui-material/src/styles/experimentalStyled.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/styles/experimentalStyled.ts)**: The `styled` API that consumes the RTL-enabled Emotion cache.

## Summary

- **Use `stylis-plugin-rtl`** to automatically mirror physical CSS properties at the Emotion cache level.
- **Set `direction: 'rtl'`** in your MUI theme to enable logical property support and global direction context.
- **Wrap your app** with both `CacheProvider` (supplying the RTL cache) and `ThemeProvider` (supplying the RTL theme).
- **No component changes required**: Custom `styled` components and MUI components automatically receive RTL styles because the transformation happens during CSS generation in [`packages/mui-material/src/styles/experimentalStyled.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/styles/experimentalStyled.ts).

## Frequently Asked Questions

### What is the difference between `theme.direction` and `stylis-plugin-rtl`?

`theme.direction` sets the logical direction property in the MUI theme, which components use to adjust behavior and logical CSS properties. `stylis-plugin-rtl` is a CSS preprocessor plugin that physically mirrors directional properties (like `margin-left` becoming `margin-right`) at the Emotion cache level. You need both working together for complete RTL support.

### Do I need to modify individual components to support RTL?

No. Because the RTL transformation occurs at the Emotion cache level (as implemented in [`packages/mui-styles/src/cache.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-styles/src/cache.ts)), both MUI components and custom `styled` components automatically receive mirrored styles. The architecture isolates RTL concerns to theme and cache configuration.

### Can I use RTL with Styled Components instead of Emotion?

While MUI primarily uses Emotion as its default styling engine, the same `stylis-plugin-rtl` approach works with Styled Components because both libraries use Stylis as their CSS preprocessor. You would configure the Stylis plugin in your Styled Components setup rather than using Emotion's `createCache`.

### How do I handle mixed LTR and RTL content in the same application?

For applications requiring both directions, create separate Emotion caches (one with `stylis-plugin-rtl` and one without) and switch between them using `CacheProvider` at the appropriate component tree level. Alternatively, nest `ThemeProvider` instances with different `direction` values, though you must ensure the cache matches the theme direction for that subtree.