React Native Navigation (RNN) is a native navigation library for React Native that provides 100% native platform navigation on both iOS and Android through a unified JavaScript API.
- Package:
react-native-navigation(v8.7.0) - Platforms: iOS 11+, Android 7.0+ (API 24)
- React Native: 0.77+ (developed against 0.83; see package.json for current version)
- License: MIT (maintained by Wix)
react-native-navigation/
├── src/ # TypeScript source code (JS API layer)
├── lib/ # Compiled output (generated by bob build - do not edit)
├── android/ # Android native implementation (Java/Kotlin)
├── ios/ # iOS native implementation (Obj-C/C++)
├── playground/ # Demo app and E2E test target
├── autolink/ # Post-install linking scripts
├── scripts/ # Build, test, and release scripts
├── website/ # Docusaurus documentation site
├── integration/ # Integration tests (Redux, Remx)
├── Mock/ # Mock implementations for testing
└── .buildkite/ # CI/CD pipeline configuration
┌──────────────────────────────────────────────────────────────────┐
│ JavaScript API Layer │
│ Navigation.setRoot() / push() / pop() / showModal() / etc. │
└─────────────────────────────┬────────────────────────────────────┘
│
┌─────────────────────────────▼────────────────────────────────────┐
│ Processing Pipeline │
│ OptionsCrawler → LayoutProcessor → LayoutTreeParser → OptionsProcessor │
└─────────────────────────────┬────────────────────────────────────┘
│
┌─────────────────────────────▼────────────────────────────────────┐
│ TurboModule Bridge │
│ NativeCommandsSender ←→ RNNTurboModule (iOS) / NavigationTurboModule (Android) │
└──────────┬─────────────────────────────────────┬─────────────────┘
│ │
┌──────────▼──────────┐ ┌─────────▼──────────┐
│ iOS Native Layer │ │ Android Native Layer│
│ UINavigationController │ ViewControllers │
│ UITabBarController │ │ CoordinatorLayout │
│ UIViewController │ │ BottomNavigation │
└─────────────────────┘ └────────────────────┘
All navigation structures are composed from these layout primitives:
| Layout Type | Description | iOS Implementation | Android Implementation |
|---|---|---|---|
component |
React component screen | RNNComponentViewController | ComponentViewController |
stack |
Push/pop navigation | UINavigationController (RNNStackController) | StackController |
bottomTabs |
Tab bar navigation | UITabBarController (RNNBottomTabsController) | BottomTabsController |
topTabs |
Horizontal scrollable tabs | RNNTopTabsViewController | TopTabsController |
sideMenu |
Drawer navigation (with center, left, right) | MMDrawerController (RNNSideMenuViewController) | SideMenuController |
splitView |
Master-detail (iPad only) | UISplitViewController (RNNSplitViewController) | — |
externalComponent |
Native (non-React) screen | RNNExternalViewController | ExternalComponentViewController |
Core commands available through the Navigation API:
- Root:
setRoot()- Replace entire navigation hierarchy - Stack:
push(),pop(),popTo(),popToRoot(),setStackRoot() - Modal:
showModal(),dismissModal(),dismissAllModals() - Overlay:
showOverlay(),dismissOverlay(),dismissAllOverlays() - Options:
setDefaultOptions(),mergeOptions(),updateProps()
Styling and behavior is controlled via a hierarchical options object:
{
statusBar: {...}, // Status bar appearance
topBar: {...}, // Navigation bar styling
bottomTabs: {...}, // Tab bar configuration
bottomTab: {...}, // Individual tab styling
sideMenu: {...}, // Drawer configuration
layout: {...}, // Screen layout options
animations: {...}, // Transition animations
modal: {...}, // Modal presentation style
overlay: {...} // Overlay behavior
}Options merge in order: Default Options → Parent Options → Component Options
1. JS: Navigation.push(componentId, layout)
2. Commands.ts validates and begins processing
3. OptionsCrawler extracts static options from component classes
4. LayoutProcessor applies registered layout processors
5. LayoutTreeParser converts to internal LayoutNode tree
6. LayoutTreeCrawler processes tree, saves props to Store
7. OptionsProcessor resolves colors, images, fonts
8. NativeCommandsSender sends to TurboModule
9. Native layer creates/updates view hierarchy
10. EventEmitter sends completion event to JS
Note: The JS layer exports a single Navigation object (from NavigationDelegate). The TurboModule names differ per platform: RNNTurboModule on iOS, NavigationTurboModule on Android.
1. Native lifecycle event (viewDidAppear, etc.)
2. RNNEventEmitter (iOS) / EventEmitter (Android)
3. NativeEventsReceiver receives via NativeEventEmitter
4. EventsRegistry dispatches to registered listeners
5. ComponentEventsObserver calls component instance methods
- Facade Pattern:
NavigationDelegateprovides clean public API - Bridge Pattern: Adapters isolate JS from native implementation details
- Presenter Pattern: Separates view styling from controller logic
- Observer Pattern: Event system for lifecycle and command notifications
- Factory Pattern:
LayoutFactorycreates controllers from layout nodes - Plugin Pattern: Processors allow extending layout/options handling
React components receive navigation lifecycle events:
class MyScreen extends NavigationComponent {
componentWillAppear(event) {} // About to become visible
componentDidAppear(event) {} // Now visible
componentDidDisappear(event) {} // No longer visible
navigationButtonPressed(event) {} // TopBar button tapped
screenPopped(event) {} // Screen removed from stack
searchBarUpdated(event) {} // Search text changed
searchBarCancelPressed(event) {} // Search cancelled
previewCompleted(event) {} // 3D Touch preview completed
}- Unit Tests: Jest + ts-mockito for TypeScript source
- Integration Tests: Redux/Remx integration verification
- E2E Tests: Detox framework with playground app
- Snapshot Tests: iOS visual regression testing
- Native Unit Tests: XCTest (iOS) and JUnit (Android)