- Published on
How to Use NativeWind for RTL Arabic Layouts in Expo (2025 Guide)
- Authors
- Name
- Ahmed Farid
- @
TIP
Save this page as a reference when localising your React Native apps for Arabic, Farsi or Hebrew audiences.
NativeWind brings Tailwind-inspired utility classes to React Native and Expo. By default, Tailwind assumes a left-to-right (LTR) layout. This guide shows you how to adapt NativeWind for right-to-left Arabic layouts, deploying on Expo for both Android and iOS. We will cover configuration, dynamic direction switching, typography, icon flipping and automated testing.
Table of Contents
- Table of Contents
- 1. Prerequisites & Terminology
- 2. Create an Expo Project
- 3. Install NativeWind & Dependencies
- 4. Configure Tailwind for RTL Support
- 5. Load Arabic Fonts with Expo Google Fonts
- 6. Detect Locale & Direction
- 7. Creating RTL-Aware Components
- 8. Auto-Flipping Icons & Images
- 9. Dynamic Direction Switching at Runtime
- 10. Testing RTL Layouts
- 11. Performance Considerations
- 12. Accessibility & UX Tips
- 13. Further Reading & Resources
- 14. Conclusion
1. Prerequisites & Terminology
- Expo SDK 50+ (with the new Metro bundler plugin system).
- Node.js 18+, Yarn or pnpm.
- Basic familiarity with Tailwind CSS and React Native.
Term | Meaning |
---|---|
RTL | Right-to-left languages (Arabic, Hebrew, Persian…) |
I18n | Internationalisation (number of letters between I and n = 18) |
NativeWind | Tailwind-like styling library for React Native |
Yoga | Layout engine used by React Native |
2. Create an Expo Project
npx create-expo-app ArabicRTLDemo
cd ArabicRTLDemo
expo start
NOTE
Expo SDK 50+ includes automatic Hermes on iOS and Android which handles RTL text rendering efficiently.
3. Install NativeWind & Dependencies
yarn add nativewind
# Optional but recommended
yarn add react-native-safe-area-context expo-localization i18next react-i18next
Generate the TypeScript helper:
npx nativewind init
This creates tailwind.config.js
and app.css
.
4. Configure Tailwind for RTL Support
Tailwind v3.3 introduced logical properties with the official tailwindcss-rtl
plugin. NativeWind supports the same plugin ecosystem.
yarn add tailwindcss-rtl
Update tailwind.config.js
:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./App.{js,jsx,ts,tsx}', './src/**/*.{js,jsx,ts,tsx}'],
plugins: [require('tailwindcss-rtl')],
theme: {
extend: {
fontFamily: {
arabic: ['Tajawal_400Regular', 'System'],
},
},
},
}
The plugin rewrites directional utilities (ml-4
, left-4
, etc.) into logical equivalents (ms-4
, inset-s-4
).
5. Load Arabic Fonts with Expo Google Fonts
yarn add @expo-google-fonts/tajawal expo-font
// src/hooks/useFonts.ts
import { useFonts, Tajawal_400Regular } from '@expo-google-fonts/tajawal'
export default function useAppFonts() {
const [loaded] = useFonts({ Tajawal_400Regular })
return loaded
}
6. Detect Locale & Direction
import * as Localization from 'expo-localization'
import { I18nManager } from 'react-native'
export const isRTL = Localization.isRTL // true if device language is RTL
I18nManager.allowRTL(true)
I18nManager.forceRTL(isRTL)
Restart the Expo app after forcing RTL.
7. Creating RTL-Aware Components
NativeWind lets you compose classes:
import { View, Text } from 'react-native'
import { styled } from 'nativewind'
const Box = styled(View)
const Title = styled(Text)
export default function Welcome() {
return (
<Box className="flex-1 items-center justify-center bg-zinc-100 dark:bg-zinc-900">
<Title className="font-arabic text-right text-3xl">مرحباً بك في Expo!</Title>
</Box>
)
}
Key points:
- Use
text-right
for Arabic headings. - Use logical spacing utilities:
pl-4
➜ps-4
(padding-start). - Icons that imply direction (chevrons, arrows) must flip (see §8).
8. Auto-Flipping Icons & Images
- Vector Icons: Most
react-native-vector-icons
sets include*-reverse
variants. - SVGs: Wrap with
style={{ transform: [{ scaleX: I18nManager.isRTL ? -1 : 1 }] }}
. - Images: Use
resizeMode={'scale'}
andtransform
flip as above.
9. Dynamic Direction Switching at Runtime
Sometimes users switch language in-app.
I18nManager.forceRTL(true)
Updates.reloadAsync() // from expo-updates
After forcing RTL, you must trigger a full reload (or unmount App container). Expo’s OTA updates make this seamless.
10. Testing RTL Layouts
- Jest Snapshot with
I18nManager.forceRTL(true)
. - E2E: Detox supports
device.setOrientation('rtl')
. - Storybook: Add a global RTL toggle decorator.
Automated tests catch regressions when contributors forget logical utilities.
11. Performance Considerations
- Avoid
flex-row
when possible; logicalflex-row-reverse
costs extra Yoga calculations. - Memoise heavy components with
React.memo
. - On Android, enable
android:supportsRtl="true"
inAndroidManifest.xml
(Expo preconfigures this).
12. Accessibility & UX Tips
✅ Keep back navigation on the left edge in RTL. ✅ Mirror progress indicators (e.g. stepper flows). ✅ Use Arabic abbreviations for dates (e.g. "سبتمبر" for September).
❌ Don’t concatenate Arabic & Latin scripts in one Text
node—bidirectional algorithm may reorder characters. ❌ Avoid hard-coding numeric literals; wrap with toLocaleString('ar-EG')
.
13. Further Reading & Resources
- NativeWind docs.
- Tailwind CSS RTL plugin.
- React Native I18nManager.
- Expo Localization.
14. Conclusion
You can now deliver pixel-perfect RTL Arabic experiences in Expo using NativeWind utilities. Combine logical spacing, proper font loading and dynamic direction detection to support global audiences without duplicating UI code.
🌍 Happy coding / ترميز سعيد! 🚀