An Expo Router app that shows
react-native-rtl flipping the whole UI between LTR and RTL at
runtime — no restart, no reload, no remount.
It leans on the modern Expo stack so the flip is visible across every surface:
- Native bottom tabs (
expo-routerNativeTabs→ SwiftUIUITabBarController/ Jetpack Compose) — the tab bar mirrors natively. @expo/uinative SwiftUI controls (Switch, Slider, Stepper, segmented Picker, Gauge, Buttons) on the UI Kit tab —HostreadsI18nManager, so the whole form re-mirrors the instant you flip.- expo-symbols (SF Symbols), expo-haptics, and reanimated entrance animations for the "nice things".
Because the library (and @expo/ui, native tabs) ship native code, this runs as
an Expo development build, not in Expo Go.
Four native bottom tabs; the Home tab is a native stack you can push into.
| Route | What it shows |
|---|---|
app/(tabs)/(home)/index.tsx |
Home — hero, live direction readout, links, features |
app/(tabs)/(home)/article.tsx |
Pushed article — native header + back button + edge swipe-back all mirror; long RTL paragraphs |
app/(tabs)/(home)/form.tsx |
Pushed form — RN TextInputs and switch; inputs/placeholders flip side |
app/(tabs)/components.tsx |
UI Kit — native @expo/ui SwiftUI gallery |
app/(tabs)/profile.tsx |
Profile — avatar, stats, actions |
app/(tabs)/settings.tsx |
Settings — the language switch that triggers the flip |
# in example/
yarn install # or npm install
# generate the native projects (autolinks the native module)
npx expo prebuild --clean
# build & launch a dev build
npx expo run:ios
npx expo run:androidIf dependency versions warn, run
npx expo install --fixto align them with the installed Expo SDK.
- Launch, open the Settings tab.
- Pick العربية (Arabic) in the segmented control.
- The whole app flips to RTL instantly — text right-aligns, rows reverse, the
native tab bar mirrors, the
@expo/uiform on the UI Kit tab mirrors, and on iOS the edge swipe-back moves to the right edge. Your tab and scroll position are preserved. - On the Home tab, open Read the article or Try a form — the native header title and back button sit on the mirrored side and you can swipe back from the right edge.
- Switch back to English to return to LTR.
app/_layout.tsx— aligns native direction with the stored language on cold start (setRTL(isRTL(lang))) before the first paint, and overrides React Navigation'sLocaleDirContextwith a reactive direction. Expo Router defaults that context toI18nManager.getConstants().isRTL— the cached startup constant — so without the override, native-stack push/pop animations and the swipe-back gesture keep the old direction until a restart.src/store/languageStore.ts— callssetRTL(isRTL(lang))on every language change (before changing the strings).app/(tabs)/settings.tsx— the segmented picker that drives it.