One ships @vxrn/native, a package of native primitives for capabilities outside React Navigation. These are experimental and the API may change.
npm install @vxrn/native@vxrn/native links automatically during the native build.
Type-safe platform colors for iOS and Android. Works with PlatformColor under the hood.
import { Color } from '@vxrn/native'
// iOS system colors<View style={{ backgroundColor: Color.ios.systemBlue }} /><Text style={{ color: Color.ios.label }} />
// Android Material Design 3<View style={{ backgroundColor: Color.android.dynamic.primary }} /><View style={{ backgroundColor: Color.android.material.surface }} />All UIKit semantic colors: systemBlue, systemRed, systemGreen, label, secondaryLabel, systemBackground, separator, systemFill, systemGray through systemGray6, and more.
Color.android.black, Color.android.white — system colors via PlatformColorColor.android.material.primary — static Material Design 3 baseline colorsColor.android.dynamic.primary — dynamic colors that adapt to the user’s wallpaper (Android 12+)Native iOS 18+ zoom transitions. The destination screen expands from a source element with a fluid animation.
import { ZoomTransitionSource, ZoomTransitionEnabler } from '@vxrn/native'
// source screen — wrap the tappable elementfunction ListScreen() { const router = useRouter() return ( <ZoomTransitionSource identifier="item-1"> <Pressable onPress={() => router.push('/detail?id=item-1')}> <Text>Mountain View</Text> </Pressable> </ZoomTransitionSource> )}
// destination screen — place the enabler anywherefunction DetailScreen() { const { id } = useParams() return ( <View> <Stack.Screen options={{ headerShown: false }} /> <ZoomTransitionEnabler zoomTransitionSourceIdentifier={id} /> <Text>Detail for {id}</Text> </View> )}headerShown: false on the detail screen to avoid the header overlapping during the zoom animationidentifier must match between ZoomTransitionSource and ZoomTransitionEnablerZoomTransitionAlignmentRectDetector on the destination to align the zoom to a specific elementNative iOS UIToolbar rendered at the bottom of the screen. Supports SF Symbols, badges, and Liquid Glass on iOS 26.
Use React Navigation’s unstable_headerLeftItems and unstable_headerRightItems screen options for header actions. Use ToolbarHost directly for a bottom UIToolbar; One does not add a second toolbar abstraction.
import { ToolbarHost, ToolbarItem, Color } from '@vxrn/native'
function MyScreen() { return ( <View style={{ flex: 1 }}> <Text>Content</Text>
<ToolbarHost> <ToolbarItem identifier="add" title="Add" systemImageName="plus" tintColor={Color.ios.systemBlue} onSelected={() => console.log('add tapped')} /> <ToolbarItem identifier="spacer" type="fluidSpacer" /> <ToolbarItem identifier="share" title="Share" systemImageName="square.and.arrow.up" barButtonItemStyle="prominent" onSelected={() => console.log('share tapped')} /> <ToolbarItem identifier="settings" systemImageName="gearshape" badgeConfiguration={{ value: '3' }} onSelected={() => console.log('settings tapped')} /> </ToolbarHost> </View> )}| Prop | Type | Description |
|---|---|---|
identifier | string | Unique ID (required) |
title | string | Button title |
systemImageName | string | SF Symbol name |
type | 'normal' | 'fixedSpacer' | 'fluidSpacer' | 'searchBar' | Item type |
barButtonItemStyle | 'plain' | 'prominent' | Button style |
badgeConfiguration | { value?: string } | Badge (iOS 26+) |
disabled | boolean | Disable the button |
hidden | boolean | Hide the button |
onSelected | () => void | Tap handler |
Native iOS UIMenu and UIAction for context menus in toolbars.
import { MenuAction } from '@vxrn/native'
<MenuAction identifier="edit" title="Edit" icon="pencil" onSelected={() => console.log('edit')}/>
<MenuAction identifier="delete" title="Delete" icon="trash" destructive onSelected={() => console.log('delete')}/>Native UISplitViewController for iPad multi-column layouts.
react-native-screens gamma mode. Add this to the top of your Podfile:ENV['RNS_GAMMA_ENABLED'] ||= '1'pod install. The SplitView.Column markers must be direct children of
SplitView; One maps them to the native screen columns and supplies the routed
detail through slot.import { SplitView } from '@vxrn/native'
function Layout() { return ( <SplitView slot={Detail}> <SplitView.Column> <SidebarContent /> </SplitView.Column> </SplitView> )}On iPhone, SplitView collapses to a single column automatically.
| Feature | iOS | Android | Web |
|---|---|---|---|
| Color API | system colors via PlatformColor | Material 3 dynamic/static | returns null |
| Zoom Transitions | iOS 18+ | unsupported | unsupported |
| Toolbar | UIToolbar + SF Symbols | unsupported | unsupported |
| Menu Actions | UIMenu / UIAction | unsupported | unsupported |
| SplitView | iPad (gamma required) | routed slot fallback | routed slot fallback |
Unsupported toolbar and zoom components return null, so they are safe to keep in
cross-platform component trees. SplitView renders its routed slot without native
columns on Android and web.
Edit this page on GitHub.