The JavaScript layer provides the public API and orchestrates communication between React components and native navigation implementations.
index.ts exports the Navigation singleton (a NavigationDelegate instance) along with re-exports from Modal, EventsRegistry, Constants, and all interfaces. Applications use Navigation.* for commands and Navigation.events().* for event subscriptions.
src/
├── index.ts # Main entry point, exports Navigation singleton
├── Navigation.ts # NavigationRoot - core orchestrator
├── NavigationDelegate.ts # Public API facade
├── adapters/ # Native bridge layer
├── commands/ # Command processing
├── components/ # React component management
├── events/ # Event system
├── interfaces/ # TypeScript type definitions
└── processors/ # Extensibility hooks
File: NavigationDelegate.ts
Facade providing the public Navigation API. All methods proxy to NavigationRoot.
// Usage
import { Navigation } from 'react-native-navigation';
Navigation.setRoot({ root: { stack: { children: [...] } } });File: Navigation.ts
Coordinates all subsystems. Constructed with dependencies:
NativeCommandsSender- sends commands to nativeNativeEventsReceiver- receives events from nativeAppRegistryService- manages React Native component registry
Initializes and coordinates:
Store- component instance & props storageComponentRegistry- component registrationLayoutTreeParser- converts layouts to internal nodesLayoutTreeCrawler- processes layout treesCommands- command executionEventsRegistry- event subscriptionsOptionsProcessor- option processingLayoutProcessor- layout transformations
Bridge between JavaScript and native/React Native APIs.
| Adapter | Purpose |
|---|---|
NativeCommandsSender |
Wraps TurboModule for command dispatch |
NativeEventsReceiver |
Wraps NativeEventEmitter for events |
NativeRNNTurboModule |
TurboModule spec interface |
NativeRNNTurboEventEmitter |
TurboModule event emitter spec |
UniqueIdProvider |
Generates unique component/command IDs |
ColorService |
Converts colors to native format |
AssetResolver |
Resolves require() image assets (class: AssetService) |
AppRegistryService |
Registers components with React Native |
Constants |
Platform dimension constants |
TouchablePreview |
3D Touch / Haptic preview handling |
File: commands/Commands.ts
Central command dispatcher. Each navigation command:
- Validates input
- Processes layout through pipeline
- Sends to native via adapter
- Returns promise with result
The pipeline executes in this exact order:
Input Layout (from API)
↓
1. OptionsCrawler.crawl() # Extract static options from component classes
↓
2. LayoutProcessor.process() # Apply registered layout processors
↓
3. LayoutTreeParser.parse() # Convert to internal LayoutNode tree
↓
4. LayoutTreeCrawler.crawl() # Process options, save props to Store
↓
5. OptionsProcessor (during crawl) # Resolve colors, assets, custom processors
↓
6. NativeCommandsSender # Send to native module
interface LayoutNode {
id: string; // Unique identifier
type: LayoutType; // Component|Stack|BottomTabs|etc
data: {
name?: string; // Component name
options?: any; // Processed options
passProps?: any; // Component props (cleared before native)
};
children: LayoutNode[];
}enum LayoutType {
Component = 'Component',
Stack = 'Stack',
BottomTabs = 'BottomTabs',
SideMenuRoot = 'SideMenuRoot',
SideMenuCenter = 'SideMenuCenter',
SideMenuLeft = 'SideMenuLeft',
SideMenuRight = 'SideMenuRight',
TopTabs = 'TopTabs',
ExternalComponent = 'ExternalComponent',
SplitView = 'SplitView',
}File: components/ComponentRegistry.ts
Manages React component registration and wrapping.
Navigation.registerComponent('ScreenName', () => MyComponent);File: components/ComponentWrapper.tsx
Higher-order component that:
- Wraps original component with lifecycle management
- Stores instance in
Storefor event dispatch - Injects
componentIdandcomponentNameprops
File: components/Store.ts
Centralized storage for:
componentsByName- registered component providerscomponentsInstancesById- mounted component instancespropsById- static props by component IDpendingPropsById- props awaiting component mountwrappedComponents- cached wrapped componentslazyRegistratorFn- function for lazy component registration
File: events/EventsRegistry.ts
Public API for event subscriptions:
Navigation.events().registerComponentDidAppearListener(({ componentId }) => {});
Navigation.events().registerCommandCompletedListener(({ commandId }) => {});File: events/ComponentEventsObserver.ts
Dispatches events to component instance methods:
componentWillAppear()componentDidAppear()componentDidDisappear()navigationButtonPressed()screenPopped()
File: events/CommandsObserver.ts
Notifies listeners of command lifecycle (start, complete).
| Event | Description |
|---|---|
RNN.AppLaunched |
App initialization complete |
RNN.ComponentWillAppear |
Component about to appear |
RNN.ComponentDidAppear |
Component now visible |
RNN.ComponentDidDisappear |
Component hidden |
RNN.NavigationButtonPressed |
TopBar button tapped |
RNN.BottomTabPressed |
Tab pressed (even if selected) |
RNN.BottomTabSelected |
Tab selection changed |
RNN.BottomTabLongPressed |
Tab long-pressed |
RNN.ModalDismissed |
Modal was dismissed |
RNN.ModalAttemptedToDismiss |
Swipe-to-dismiss attempted |
RNN.ScreenPopped |
Screen removed from stack |
RNN.SearchBarUpdated |
Search text changed |
RNN.SearchBarCancelPressed |
Search cancelled |
RNN.PreviewCompleted |
3D Touch preview completed |
RNN.CommandCompleted |
Navigation command finished |
File: processors/OptionProcessorsStore.ts
Registers custom option processors:
Navigation.addOptionProcessor('topBar.title.text', (value, commandName) => {
return value.toUpperCase(); // Transform all titles
});File: processors/LayoutProcessorsStore.ts
Registers layout transformers:
Navigation.addLayoutProcessor((layout, commandName) => {
// Add default options to all components
return layout;
});File: interfaces/Layout.ts
interface LayoutRoot {
root: Layout;
modals?: any[];
overlays?: any[];
}
type Layout = {
component?: LayoutComponent;
stack?: LayoutStack;
bottomTabs?: LayoutBottomTabs;
sideMenu?: LayoutSideMenu;
splitView?: LayoutSplitView;
topTabs?: LayoutTopTabs;
externalComponent?: ExternalComponent;
}File: interfaces/Options.ts (comprehensive)
Contains all configuration options for:
- Status bar, navigation bars
- Top bar (buttons, title, search)
- Bottom tabs
- Side menus
- Modals, overlays
- Animations
- Layout parameters
File: interfaces/NavigationComponent.ts
Base class for navigation-aware components:
class MyScreen extends NavigationComponent<Props> {
static options: Options = { ... };
componentDidAppear(event) { }
navigationButtonPressed(event) { }
}Production:
lodash- utility functionshoist-non-react-statics- HOC supportreact-lifecycles-compat- lifecycle polyfilltslib- TypeScript helpers
Peer:
react,react-native(required)remx(optional state management)
Uses react-native-builder-bob:
- Source:
src/ - Output:
lib/ - Targets: ESM modules + TypeScript declarations