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.
Works with
---
name: rnn-codebase
description: 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.
license: MIT
---
# React Native Navigation Codebase
## Architecture Overview
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:
1. `Navigation.push()` → `Commands.ts` → processing pipeline → `NativeCommandsSender.ts`
2. TurboModule: `RNNTurboModule` (iOS) / `NavigationTurboModule.kt` (Android)
3. iOS: `RNNCommandsHandler` → `RNNViewControllerFactory` → UIKit controllers
4. Android: `Navigator` → `LayoutFactory` → View-based controllers (no Fragments)
Read [ARCHITECTURE.md](../../ARCHITECTURE.md) for the full overview.
## Key Cross-Layer Mappings
### Layout Types → Native Controllers
| 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` |
### Options → Presenters
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` |
### Events (same names both platforms)
| 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 |
## Where to Find Things
### By task: "I need to fix/change X"
| 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` |
### By directory
- **`src/`** — JS public API, commands, processing pipeline. See [src/ARCHITECTURE.md](../../src/ARCHITECTURE.md)
- **`ios/`** — All Obj-C/C++ native code. See [ios/ARCHITECTURE.md](../../ios/ARCHITECTURE.md)
- **`ios/TurboModules/`** — New architecture entry points (`RNNTurboModule`, `RNNTurboManager`, `RNNTurboCommandsHandler`)
- **`android/src/main/java/com/reactnativenavigation/`** — All Java/Kotlin native code. See [android/ARCHITECTURE.md](../../android/ARCHITECTURE.md)
- **`playground/`** — Demo app for development and E2E tests
- **`playground/src/screens/`** — Test screens exercising every feature
- **`playground/e2e/`** — Detox E2E tests
## Options Resolution Order
Options are applied in ascending priority:
1. Default options (from `Navigation.setDefaultOptions()`) — lowest priority
2. Static options (from component class or `Navigation.registerComponent`)
3. Options passed in the layout call (e.g. `push`, `setRoot`)
4. `mergeOptions()` — runtime override, highest priority
## JS Processing Pipeline (exact order)
```
API layout → OptionsCrawler.crawl() → LayoutProcessor.process()
→ LayoutTreeParser.parse() → LayoutTreeCrawler.crawl()
→ OptionsProcessor (colors, assets, custom) → NativeCommandsSender
```
## iOS Patterns
- All controllers conform to `RNNLayoutProtocol`
- `RNNBasePresenter` subclasses apply options — `applyOptionsOnInit:`, `applyOptions:`, `mergeOptions:resolvedOptions:`
- Commands run on main thread (`RCTExecuteOnMainQueue`)
- React views: `RNNReactView` wraps `RCTSurfaceHostingView` (new arch)
- Overlays use separate `UIWindow` instances (`RNNOverlayWindow`)
- `RNNReactComponentRegistry` caches React component instances
## Android Patterns
- View-based, NOT Fragment-based
- All commands dispatched via `UiThread.post()`
- `ViewController<T extends ViewGroup>` is the base — `createView()` is abstract
- `ParentController` extends `ChildController` extends `ViewController`
- Bottom tabs use `AHBottomNavigation` library
- Three root layouts in `NavigationActivity`: rootLayout, modalsLayout, overlaysLayout
- Tab attachment modes: `Together`, `OnSwitchToTab`, `AfterInitialTab`
## Development Workflow
### Playground app
- `yarn start` — Metro bundler
- `yarn xcode` — Open iOS project
- `yarn studio` — Open Android project
- `yarn pod-install` — Install iOS pods
### Testing
- `yarn test-js` — Jest unit tests
- `yarn 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 tests
### Building
- `yarn prepare` — Builds `src/` → `lib/` (ESM + types)
- Codegen config: `rnnavigation` in `package.json`
## Common Gotchas
- iOS uses UIKit subclasses (UINavigationController, UITabBarController); Android uses custom View hierarchy
- `splitView` is iOS-only
- Side menu: iOS uses MMDrawerController (3rd party); Android uses DrawerLayout (native)
- Options that exist in JS types may not be implemented on both platforms — check the presenter
- `passProps` are stored in JS `Store`, not sent to native (cleared before bridge crossing)
- The `lib/` folder is generated — never edit it, edit `src/` instead
- Deep links are processed only after the first `setRoot()` 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 crashesMore Mobile skills
animation-vocabulary
emilkowalski/skills
Reverse-lookup glossary that turns a vague description of a web animation or motion effect into its exact term ("the bouncy thing when a popover opens" → Pop in; "the iOS rubber-band scroll" → Rubber-banding). Use when the user asks "what's it called when…", or describes a motion effect without knowing its name and wants the right word to prompt an AI or designer with. For naming an effect, not designing or building one.
xcode-project-setup
firebase/agent-skills
Safely modifies Xcode projects (.pbxproj) to add Swift Packages and link files. Use this skill whenever an iOS project needs dependencies installed (e.g. Firebase, Alamofire).
cross-border-ecommerce
nexscope-ai/ecommerce-skills
Cross-border e-commerce expansion advisor. Scores target markets on 8 weighted dimensions (market size, ecommerce penetration, competition, regulatory complexity, logistics infrastructure, payment ecosystem, cultural distance, IP protection), compares 5 fulfillment models with cost and transit data, provides country-by-country tax/duty compliance guides (EU VAT/IOSS, UK VAT, US sales tax, CA GST, AU GST, JP consumption tax), maps local payment preferences by market, and builds a phased expansion roadmap. No API key required.

