wix/react-native-navigation-rnn-codebase
Navigate and work with the react-native-navigation (RNN) codebase. Use when fixing bugs, adding features, tracing command flows, understanding options resolution, or working across JS/iOS/Android layers in this repo.
npx skills add https://github.com/wix/react-native-navigation --skill rnn-codebase
RNN has three layers that mirror each other:
JS/TS (src/) → TurboModule bridge → iOS native (ios/)
→ Android native (android/)
A navigation command (e.g. push) flows:
Navigation.push() → Commands.ts → processing pipeline → NativeCommandsSender.tsRNNTurboModule (iOS) / NavigationTurboModule.kt (Android)RNNCommandsHandler → RNNViewControllerFactory → UIKit controllersNavigator → LayoutFactory → View-based controllers (no Fragments)Read ARCHITECTURE.md for the full overview.
| JS Layout Type | iOS Controller | Android Controller |
|----------------|---------------|-------------------|
| component | RNNComponentViewController | ComponentViewController |
| stack | RNNStackController (UINavigationController) | StackController |
| bottomTabs | RNNBottomTabsController (UITabBarController) | BottomTabsController |
| sideMenu | RNNSideMenuViewController (MMDrawerController) | SideMenuController (DrawerLayout) |
| topTabs | RNNTopTabsViewController | TopTabsController (ViewPager) |
| splitView | RNNSplitViewController | N/A (iOS only) |
| externalComponent | RNNExternalViewController | ExternalComponentViewController |
Each controller type has a Presenter that applies options to views:
| iOS Controller | iOS Presenter | Android Presenter |
|----------------|--------------|-------------------|
| RNNComponentViewController | RNNComponentPresenter | ComponentPresenter |
| RNNStackController | RNNStackPresenter + TopBarPresenter | StackPresenter |
| RNNBottomTabsController | RNNBottomTabsPresenter | BottomTabsPresenter |
| RNNSideMenuViewController | RNNSideMenuPresenter | SideMenuPresenter |
| Event | Trigger |
|-------|---------|
| RNN.ComponentDidAppear | Screen becomes visible |
| RNN.ComponentDidDisappear | Screen hidden |
| RNN.NavigationButtonPressed | TopBar button tap |
| RNN.BottomTabSelected | Tab changed |
| RNN.ModalDismissed | Modal dismissed |
| RNN.ScreenPopped | Screen popped from stack |
| RNN.CommandCompleted | Any command finished |
| Task | JS File(s) | iOS File(s) | Android File(s) |
|------|-----------|------------|----------------|
| Command execution | src/commands/Commands.ts | ios/RNNCommandsHandler.mm | react/NavigationTurboModule.kt |
| Layout creation | src/commands/LayoutTreeParser.ts | ios/RNNViewControllerFactory.mm | options/LayoutFactory.java |
| Options processing | src/commands/OptionsProcessor.ts | ios/RNNNavigationOptions.mm | options/Options.java |
| Options application | — | ios/*Presenter.mm | viewcontrollers/*Presenter.java |
| TopBar | src/interfaces/Options.ts (TopBarOptions) | ios/TopBarPresenter.mm, ios/RNNUIBarButtonItem.mm | views/stack/topbar/ |
| Bottom tabs | src/interfaces/Options.ts (BottomTabsOptions) | ios/RNNBottomTabsPresenter.mm | viewcontrollers/bottomtabs/ |
| Modals | src/commands/Commands.ts | ios/RNNModalManager.mm | viewcontrollers/modal/ModalStack.java |
| Overlays | src/commands/Commands.ts | ios/RNNOverlayManager.mm | viewcontrollers/overlay/OverlayManager.kt |
| Animations | src/interfaces/Options.ts (AnimationOptions) | ios/ScreenAnimationController.mm | viewcontrollers/stack/StackAnimator.kt |
| React view rendering | — | ios/RNNReactView.mm | react/ReactView.java |
| Events to JS | src/adapters/NativeEventsReceiver.ts | ios/RNNEventEmitter.mm | react/events/EventEmitter.java |
| Component registration | src/components/ComponentRegistry.ts | — | — |
| Deep linking (URL → screen) | src/linking/ (LinkingHandler, URLParser, RouteMatcher, DeferredLinkQueue, ModalLayoutBuilder) | ios/RNNAppDelegate.mm (dispatchDeepLinkURL:, cold-start queue, RCTContentDidAppearNotification) | NavigationActivity.onNewIntent → ReactGateway |
src/ — JS public API, commands, processing pipeline. See src/ARCHITECTURE.mdios/ — All Obj-C/C++ native code. See ios/ARCHITECTURE.mdios/TurboModules/ — New architecture entry points (RNNTurboModule, RNNTurboManager, RNNTurboCommandsHandler)android/src/main/java/com/reactnativenavigation/ — All Java/Kotlin native code. See android/ARCHITECTURE.mdplayground/ — Demo app for development and E2E testsplayground/src/screens/ — Test screens exercising every featureplayground/e2e/ — Detox E2E testsOptions are applied in ascending priority:
Navigation.setDefaultOptions()) — lowest priorityNavigation.registerComponent)push, setRoot)mergeOptions() — runtime override, highest priorityAPI layout → OptionsCrawler.crawl() → LayoutProcessor.process()
→ LayoutTreeParser.parse() → LayoutTreeCrawler.crawl()
→ OptionsProcessor (colors, assets, custom) → NativeCommandsSender
RNNLayoutProtocolRNNBasePresenter subclasses apply options — applyOptionsOnInit:, applyOptions:, mergeOptions:resolvedOptions:RCTExecuteOnMainQueue)RNNReactView wraps RCTSurfaceHostingView (new arch)UIWindow instances (RNNOverlayWindow)RNNReactComponentRegistry caches React component instancesUiThread.post()ViewController<T extends ViewGroup> is the base — createView() is abstractParentController extends ChildController extends ViewControllerAHBottomNavigation libraryNavigationActivity: rootLayout, modalsLayout, overlaysLayoutTogether, OnSwitchToTab, AfterInitialTabyarn start — Metro bundleryarn xcode — Open iOS projectyarn studio — Open Android projectyarn pod-install — Install iOS podsyarn test-js — Jest unit testsyarn test-unit-ios — iOS native unit tests (XCTest)yarn test-unit-android — Android native unit tests (JUnit + Robolectric)yarn test-e2e-ios-ci / yarn test-e2e-android-ci — Detox E2E testsyarn prepare — Builds src/ → lib/ (ESM + types)rnnavigation in package.jsonsplitView is iOS-onlypassProps are stored in JS Store, not sent to native (cleared before bridge crossing)lib/ folder is generated — never edit it, edit src/ insteadsetRoot() resolves; pre-bridge URLs on iOS are queued natively in RNNAppDelegate and flushed on RCTContentDidAppearNotification (bridgeless mode — RCTJavaScriptDidLoadNotification does NOT fire)ModalLayoutBuilder strips React-reserved keys (ref, key) from URL query params before they reach passProps, to avoid React 19 ref-validation crashesTake wix/react-native-navigation-rnn-codebase from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.