This project aims to expose native navigation container components to Lynx. It is not designed to be used as a standalone library but rather as a dependency of a full-featured navigation library. The implementation is based on react-native-screens.
The repository is structured similarly as react-native-screens: a library at the root with an example app, integrated via Lynx autolinking:
src/- the library sources for JS side oflynx-screenspackageandroid/+ios/- the native element implementations, exposed through@LynxElementannotationsLynxExample/- the example app; it installslynx-screenslocally ("file:../") and hosts the demoStackContainernavigator built on top of the primitives
Install dependencies - both the library root and the example app, which links lynx-screens from the repo root:
npm install
cd LynxExample
npm install
npm run dev # start the Rspeedy dev servercd LynxExample/android
./gradlew :app:assembleDebug # or open LynxExample/android in Android StudioThe bundled Material FormSheet backend is used by default. A host that supplies its own backend can exclude the bundled implementation at compile time:
lynxScreens.formSheetBackend=externalThe host must then register its factory before creating a FormSheet:
LynxScreens.setFormSheetControllerFactory(HostFormSheetControllerFactory)cd LynxExample/ios
bundle install # once; provides CocoaPods with the cocoapods-lynx-library plugin
bundle exec pod install
open LynxScreens.xcworkspaceRun the LynxScreens app scheme from XCode.
The library tracks the Stack v5 work on react-native-screens main and is synced up to c0305806 (2026-08-18). Every Stack v5 commit in that range was backported one at a time, in RNS chronological order — each backport commit links its source commit (Related commit from RNScreens: ...) in the commit message.
The native implementation intentionally stays as close to react-native-screens as possible. Divergences exist only where the Lynx platform forces them (props/state/layout plumbing, event emission, view commands) and are marked in code with Adaptation: / Divergence from RNS: comments and an Adaptations for Lynx section in the backport commit message.
Already ported to Lynx and working:
| Feature | Android | iOS |
|---|---|---|
| Base Stack v5 navigation model | ✅ | ✅ |
push, pop, preload, batch, native pop |
✅ | ✅ |
| Nested stacks | ✅ | ✅ |
Screen lifecycle events (onWillAppear / onDidAppear / onWillDisappear / onDidDisappear, onDismiss) |
✅ | ✅ |
Per-route options updated at runtime (setRouteOptions) |
✅ | ✅ |
preventNativeDismiss (+ onNativeDismissPrevented) |
✅ | ❌ |
| Predictive back gesture support (internal) | ✅ | N/A |
| Transition API / screen transitions (internal) | ✅ | ❌ |
ScrollViewMarker (registers a wrapped scroll view with the enclosing screen for header integrations) |
✅ | ✅ |
| FormSheet v5 | ✅ | ✅ |
Header — Android
- Base
headerConfigsetup (title,small/medium/largetypes, hidden, transparent) with custom subviews (background / leading / center / trailing, collapse modes) - Back button support with customization props (tint colors, custom icon,
backButtonHidden) - Integration with Android
scrollFlags+liftOnScroll(M3 Expressive app bar theme, Material 1.14) - Toolbar menu with nested submenus and groups (checkbox / radio single-selection,
menuTitleheaders) - Menu item props: icons (image sources and drawable resources) with tint colors,
title/titleCondensed/tooltipText,accessibilityLabel,disabled,showAsAction - View commands:
updateToolbarMenuElements(single and batched atomic updates)
Header — iOS
- Base
headerConfigsetup (title / subtitle, large title / subtitle, hidden) with header items and spacers (leading / trailing / title / subtitle / largeSubtitle placements, custom views,onPress,hitSlop) - Item icons: SF Symbols, xcassets, async image / template sources
- Menus and menu items (actions, toggles, radio single-selection hierarchies) with
onPress/onSelectionChange - Menu props:
keepsMenuPresented,displayInline,displayAsPalette, menu icons -
titleMenu(menu attached to the navigation bar title, iOS 16+) - View commands:
setMenuItemOptions/setMenuOptions(incl. toggle state with selection events)
Parts of react-native-screens in the synced range that were deliberately left out:
- Native Tabs, SplitView, SafeArea, ScrollToTopGuard — components lynx-screens doesn't port; see also the open topics below.
- ScrollViewMarker scroll edge effects — only the scroll view registration core of the SVM epic is ported; the iOS scroll edge effect subsystem is not.
The implementation for the following features hasn't been initiated in react-native-screens yet, but we have plans to add the support in the nearest feature.
- Screen transition animations - the most important remaining gap before Stack v5 can be considered as feature-complete for
react-native-screens. -
preventNativeDismisssupport on iOS.
- How screens should integrate with
SafeAreaViewis still unresolved in RNS. Additionally the research on the Lynx approach on this topics hasn't been investigated (who owns the insets etc.) yet. Related known gap: on iOS, v5 screen content is not inset below the navigation bar (RNS relies on UIKit's automatic scroll view insets, which Lynx's scroll view opts out of) - the examples approximate the inset with a static padding. - Stack v5 is only a part of what
react-native-screensships. Whether Lynx is interested in other navigators: Native Tabs, SplitView - this hasn't been confirmed yet. Those components are good candidates for a Lynx port too.
lynx-screens library is licensed under The MIT License.