@bedrock-core/navigation
v0.9.3
Published
@bedrock-core/ui navigation system
Maintainers
Readme
@bedrock-core/navigation

Stack-based navigation for @bedrock-core/ui, inspired by
React Navigation and adapted to the runtime's one-render-per-player model. Screens are components,
transitions are actions, and route params are typed by a route map you declare once.
⚠️ MVP scope: stack navigation only. No tabs, nested navigators, deep linking, state persistence, transition animations, or keep-alive for inactive routes.
Install
yarn add @bedrock-core/navigationIt also ships inside the umbrella package as @bedrock-core/ui/navigation.
What it gives you
NavigationContainer— the provider that holds a player's navigation state; the root you pass torender()createStackNavigator(config)— returns{ Navigator, routeNames, initialRouteName }from a{ screens, initialRouteName? }config; a screen entry is a component or{ screen, initialParams }useNavigation()—navigate,push,goBack,canGoBack,reset,setParams,getStateuseRoute()— the active{ key, name, params }stackReducerwith itsStackActionunion andScreenDefaultsmap, for hosts that seed or drive the stack themselves (@bedrock-core/configbuilds an initial state from a fired command this way)
Usage
/** @jsxImportSource @bedrock-core/ui */
import { NavigationContainer, createStackNavigator, type ScreenProps } from '@bedrock-core/navigation';
import { Button, Text, render, type JSX } from '@bedrock-core/ui';
import type { Player } from '@minecraft/server';
type AppRoutes = { Home: undefined; Profile: { userId: number } };
function HomeScreen({ navigation }: ScreenProps<AppRoutes, 'Home'>): JSX.Element {
return (
<Button onPress={(): void => navigation.navigate('Profile', { userId: 42 })}>
<Text>{'Go to Profile'}</Text>
</Button>
);
}
function ProfileScreen({ navigation, route }: ScreenProps<AppRoutes, 'Profile'>): JSX.Element {
return (
<>
<Text>{`Profile: ${route.params.userId}`}</Text>
<Button onPress={(): void => navigation.goBack()}>
<Text>{'Back'}</Text>
</Button>
</>
);
}
const Stack = createStackNavigator<AppRoutes>({
initialRouteName: 'Home',
screens: { Home: HomeScreen, Profile: { screen: ProfileScreen, initialParams: { userId: 0 } } },
});
export function openApp(player: Player): void {
render(
<NavigationContainer>
<Stack.Navigator />
</NavigationContainer>,
player,
);
}One render() per player. Navigating does not call render() again — button callbacks feed
the runtime's existing present cycle, which re-presents the same screen with the new route. Screen
components must never call render() themselves.
Documentation
- navigation — the model, quick start, and how it works
createStackNavigator·useNavigation·useRoute
License
MIT
