Shadcn/ui provides native Right-to-Left (RTL) support through a combination of CLI-driven code transformations and automated registry builds. This system allows developers to maintain a single source of truth for component logic while automatically transforming physical CSS classes to logical equivalents during installation or registry generation.
The RTL support system operates within the CLI's transformation pipeline and the registry build pipeline. In the v4 architecture, RTL variants are pre-compiled for specific styles (like base-nova and radix-nova) to support the documentation app's live previews, while the CLI continues to handle on-the-fly transformations for users.
The following diagram illustrates how an RTL preference travels from the user configuration to the final code on disk during the component addition process.
RTL Transformation Flow
Sources: packages/shadcn/src/utils/get-config.ts7-15 apps/v4/scripts/build-registry.mts12-17 packages/shadcn/src/utils/transformers/transform-cleanup.test.ts7-15
In the v4 monorepo, the registry build script build-registry.mts automates the generation of RTL-specific component variants. This is used primarily to populate styles/<style>/ui-rtl/* for the documentation site apps/v4/scripts/build-registry.mts56
The build pipeline targets specific style combinations for RTL generation, notably base-nova and radix-nova apps/v4/scripts/build-registry.mts33-34 These are exported as installable registry JSON and local style files apps/v4/registry/README.md33-35
| Output Path | Purpose |
|---|---|
apps/v4/styles/<style>/ui-rtl/* | Compiled components used by the docs app for RTL previews apps/v4/registry/README.md33-34 |
apps/v4/public/r/styles/<style>-rtl.json | Registry entries for RTL-enabled installations apps/v4/scripts/build-registry.mts158 |
The CLI and registry build use transformDirection and transformRtl to map physical directions (Left/Right) to logical ones (Start/End).
| Physical Class | Logical Equivalent | Description |
|---|---|---|
ml-* | ms-* | Margin Left -> Margin Start |
mr-* | me-* | Margin Right -> Margin End |
pl-* | ps-* | Padding Left -> Padding Start |
pr-* | pe-* | Padding Right -> Padding End |
text-left | text-start | Horizontal Alignment |
text-right | text-end | Horizontal Alignment |
rounded-l-* | rounded-s-* | Corner Radius |
left-* | start-* | Absolute Positioning |
Sources: apps/v4/scripts/build-registry.mts12-17 apps/v4/registry/README.md88-91 packages/shadcn/src/utils/transformers/transform-cleanup.test.ts18-25
The transformation logic is implemented across several utilities that interact with the ts-morph Project to manipulate source code.
RTL Transformation Entity Map
Sources: apps/v4/scripts/build-registry.mts12-18 packages/shadcn/src/utils/transformers/transform-cleanup.test.ts18-68
The system uses special CSS markers (classes) in the source code to signal where transformations should occur. These markers are removed by the transformCleanup transformer before the final code is written to the user's project.
cn-rtl-flip: Signals that the associated classes should be flipped for RTL packages/shadcn/src/utils/transformers/transform-cleanup.test.ts18cn-logical-sides: Signals that side-based classes (like border-l) should be converted to logical properties (border-s) packages/shadcn/src/utils/transformers/transform-cleanup.test.ts58The transformCleanup function ensures that internal markers do not leak into production code. It handles:
cn() helper packages/shadcn/src/utils/transformers/transform-cleanup.test.ts35-50class-variance-authority base classes and variant definitions packages/shadcn/src/utils/transformers/transform-cleanup.test.ts70-105className attribute is removed entirely packages/shadcn/src/utils/transformers/transform-cleanup.test.ts129-146Components designed for RTL support typically accept a dir prop and utilize the logical variants generated by the pipeline.
The DatePickerRtl example demonstrates how to integrate RTL support with external libraries like react-day-picker and date-fns using the logical components from the ui-rtl directory.
Sources: apps/v4/examples/base/date-picker-rtl.tsx16-22 apps/v4/examples/base/date-picker-rtl.tsx68-97 apps/v4/examples/radix/date-picker-rtl.tsx16-22
Refresh this wiki
This wiki was recently refreshed. Please wait 2 days to refresh again.