{"id":18325225,"url":"https://github.com/kanzitelli/rn-navio","last_synced_at":"2025-04-09T21:18:03.952Z","repository":{"id":61807503,"uuid":"544113842","full_name":"kanzitelli/rn-navio","owner":"kanzitelli","description":"🧭 Navigation library for React Native (Expo). Build once, navigate from anywhere to everywhere!","archived":false,"fork":false,"pushed_at":"2024-04-06T20:40:41.000Z","size":202,"stargazers_count":118,"open_issues_count":5,"forks_count":5,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-09T21:17:56.164Z","etag":null,"topics":["expo","navio","react-native","react-native-navigation","react-navigation"],"latest_commit_sha":null,"homepage":"https://snack.expo.dev/@kanzitelli/rn-navio-snack","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kanzitelli.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-01T17:24:32.000Z","updated_at":"2025-03-04T18:40:05.000Z","dependencies_parsed_at":"2022-10-21T14:45:22.581Z","dependency_job_id":"efa04cf8-4f3e-4cce-9edb-0ad96b95968e","html_url":"https://github.com/kanzitelli/rn-navio","commit_stats":{"total_commits":82,"total_committers":2,"mean_commits":41.0,"dds":"0.20731707317073167","last_synced_commit":"3aa5a8b7782872ff5b01df8544d16ba6f20b7905"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kanzitelli%2Frn-navio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kanzitelli%2Frn-navio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kanzitelli%2Frn-navio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kanzitelli%2Frn-navio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kanzitelli","download_url":"https://codeload.github.com/kanzitelli/rn-navio/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248111973,"owners_count":21049578,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["expo","navio","react-native","react-native-navigation","react-navigation"],"created_at":"2024-11-05T18:40:13.947Z","updated_at":"2025-04-09T21:18:03.932Z","avatar_url":"https://github.com/kanzitelli.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🧭 Navio\n\n[![React Native Compatible](https://img.shields.io/badge/React%20Native-Compatible-brightgreen)](https://snack.expo.dev/@kanzitelli/rn-navio-snack)\n[![Expo Compatible](https://img.shields.io/badge/𝝠%20Expo-Compatible-brightgreen)](https://snack.expo.dev/@kanzitelli/rn-navio-snack)\n[![Expo Snack](https://img.shields.io/badge/𝝠%20Expo-Snack-blue)](https://snack.expo.dev/@kanzitelli/rn-navio-snack)\n\nNavio is a navigation library for React Native built on top of [React Navigation](https://github.com/react-navigation/react-navigation). The main goal is to improve DX by building the app layout in one place and using the power of TypeScript to provide autocompletion and other features.\n\nNavio lets you easily create different kinds of apps: bottom tabs-based, simple single-screen, and apps with drawer layouts. It takes care of all boilerplate code configuration for Navigators, Screens, Stacks, Tabs, and Drawers under the hood, so you can focus on developing your app's business logic.\n\n\u003e If `Navio` helped you in a way, support it with ⭐️\n\n☣️ \u003ci\u003eNavio is still a young library and may have breaking changes in the future. Check out if [Navio is production-ready](#is-navio-production-ready)\u003c/i\u003e\n\n## Quickstart\n\n### Install dependencies\n\n```bash\nyarn add rn-navio\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eReact Navigation dependencies\u003c/summary\u003e\n\nAs Navio is built on top of [React Navigation](https://github.com/react-navigation/react-navigation), you will need to have the following libraries installed:\n\n```bash\nyarn add @react-navigation/stack @react-navigation/native @react-navigation/native-stack @react-navigation/bottom-tabs @react-navigation/drawer\n```\n\nFor more information, please check the [installation steps](https://reactnavigation.org/docs/getting-started/#installation).\n\n\u003c/details\u003e\n\n### Create your first Navio layout\n\nThis code will build a simple app with one screen.\n\n```tsx\n// App.tsx\nimport {Text} from 'react-native';\nimport {Navio} from 'rn-navio';\n\nconst Home = () =\u003e {\n  return \u003cText\u003eHome page\u003c/Text\u003e;\n};\n\nconst navio = Navio.build({\n  screens: {Home},\n  stacks: {\n    HomeStack: ['Home'],\n  },\n  root: 'stacks.HomeStack',\n});\n\nexport default () =\u003e \u003cnavio.App /\u003e;\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eTab-based app with 2 tabs\u003c/summary\u003e\n\n```tsx\n// App.tsx\nimport {Text} from 'react-native';\nimport {Navio} from 'rn-navio';\n\nconst Home = () =\u003e {\n  return \u003cText\u003eHome page\u003c/Text\u003e;\n};\nconst Settings = () =\u003e {\n  return \u003cText\u003eSettings page\u003c/Text\u003e;\n};\n\nconst navio = Navio.build({\n  screens: {Home, Settings},\n  stacks: {\n    HomeStack: ['Home'],\n    SettingsStack: ['Settings'],\n  },\n  tabs: {\n    AppTabs: {\n      layout: {\n        HomeTab: {stack: 'HomeStack'},\n        SettingsTab: {stack: 'SettingsStack'},\n      },\n    },\n  },\n  root: 'tabs.AppTabs',\n});\n\nexport default () =\u003e \u003cnavio.App /\u003e;\n```\n\n\u003c/details\u003e\n\nIf you'd like to see more complex and exotic example, please follow [this link](/docs/layout-examples.md).\n\n## Playground\n\n### React Native Starter\n\nYou can bootstrap a new project with Navio from [expo-starter](https://github.com/kanzitelli/expo-starter):\n\n```bash\nnpx cli-rn new app\n```\n\n### Expo Snack\n\nPlay with the library in the [Expo Snack](https://snack.expo.dev/@kanzitelli/rn-navio-snack).\n\n## Navigation API\n\nNavio provides a colleciton of actions to perform navigation within the app. Suppose, you have a `navio` object:\n\n### Common\n\n- `.N`\n\n  Current navigation object from React Navigation. You can perform any of [these actions](https://reactnavigation.org/docs/navigation-actions).\n\n- `.push(name, params?)`\n\n  Adds a route on top of the stack and navigates forward to it.\n\n- `.goBack()`\n\n  Allows to go back to the previous route in history.\n\n- `.setParams(name, params)`\n\n  Allows to update params for a certain route.\n\n- `.setRoot(as, rootName)`\n\n  Sets a new app root. It can be used to switch between `Stacks`, `Tabs`, and `Drawers`.\n\n### Stacks\n\nStacks-related actions.\n\n- `.stacks.push(name)`\n\n  Adds a route on top of the stack and navigates forward to it. It can hide tab bar.\n\n- `.stacks.pop(count?)`\n\n  Takes you back to a previous screen in the stack.\n\n- `.stacks.popToTop()`\n\n  Takes you back to the first screen in the stack, dismissing all the others.\n\n- `.stacks.setRoot(name)`\n\n  Sets a new app root from stacks.\n\n### Tabs\n\nTabs-related actions.\n\n- `.tabs.jumpTo(name)`\n\n  Used to jump to an existing route in the tab navigator.\n\n- `.tabs.updateOptions(name, options)`\n\n  Updates options for a given tab. Used to change badge count.\n\n- `.tabs.setRoot(name)`\n\n  Sets a new app root from tabs.\n\n### Drawers\n\nDrawers-related actions.\n\n- `.drawers.open()`\n\n  Used to open the drawer pane.\n\n- `.drawers.close()`\n\n  Used to close the drawer pane.\n\n- `.drawers.toggle()`\n\n  Used to open the drawer pane if closed, or close if open.\n\n- `.drawers.jumpTo(name)`\n\n  Used to jump to an existing route in the drawer navigator.\n\n- `.drawers.updateOptions(name, options)`\n\n  Updates options for a given drawer menu content. Used to change its title.\n\n- `.drawers.setRoot(name)`\n\n  Sets a new app root from drawers.\n\n### Modals\n\nModals-related actions.\n\n- `.modals.show(name, params)`\n\n  Used to show an existing modal and pass params.\n\n- `.modals.getParams(name)`\n\n  Returns params passed for modal on .show() method.\n\n### Hooks\n\nUseful hooks.\n\n- `.useN()`\n\n  Duplicate of `useNavigation()` hook from React Navigation. Used for convenience inside screens to get access to navigation object. [Docs](https://reactnavigation.org/docs/use-navigation/).\n\n- `.useR()`\n\n  Duplicate of `useRoute()` hook from React Navigation. Used to convenience inside screens to get access to route object. [Docs](https://reactnavigation.org/docs/use-route)\n\n- `.useParams()`\n\n  Used for quick access to navigation route params. Used to convenience inside screens when passing params.\n\n## Layout structure\n\nNavio requires `screens` and at least one `stacks` to build an app layout. `tabs`, `drawers`, `modals`, `root`, `hooks` and `defaultOptions` are optional and used for more advanced app layouts.\n\n### Screens\n\nThese are main bricks of your app with Navio. You can reuse them for any stack you want to build.\n\nA screen can be defined by passing a plain React component. If you'd like to pass some options which describe the screen, then you can pass an object as well.\n\n\u003cdetails\u003e\n\u003csummary\u003eExample\u003c/summary\u003e\n\n```tsx\nimport {Screen1, Screen3} from '@app/screens';\n\nconst navio = Navio.build({\n  screens: {\n    One: Screen1,\n    Two: () =\u003e {\n      return \u003c\u003e\u003c/\u003e;\n    }\n    Three: {\n      component: Screen3,\n      options: (props) =\u003e ({\n        title: 'ThreeOne'\n      })\n    }\n  },\n});\n```\n\n\u003c/details\u003e\n\n### Stacks\n\nStacks are built using `Screens` that have been defined before. IDEs should help with autocompletion for better DX.\n\nA stack can be defined by passing an array of `Screens`. If you'd like to pass some options down to stack navigator, then you can pass an object.\n\n\u003cdetails\u003e\n\u003csummary\u003eExample\u003c/summary\u003e\n\n```tsx\nconst navio = Navio.build({\n  // screens are taken from previous step\n  stacks: {\n    MainStack: ['One', 'Two'],\n    ExampleStack: {\n      screens: ['Three'],\n      navigatorProps: {\n        screenListeners: {\n          focus: () =\u003e {},\n        },\n      },\n    },\n  },\n});\n```\n\n\u003c/details\u003e\n\n### Tabs\n\nTabs are built using `Screens`, `Stacks`, and `Drawers` that have been defined before.\n\nTabs can be defined by passing an object with `content` and, optionally, props for navigator.\n\nContent can take as a value one of `Stacks`, `Drawers`, array of `Screens`, or an object that describes stack and options for bottom tab (describing title, icon, etc.).\n\n\u003cdetails\u003e\n\u003csummary\u003eExample\u003c/summary\u003e\n\n```tsx\nconst navio = Navio.build({\n  // screens and stacks are taken from previous step\n  tabs: {\n    AppTabs: {\n      layout: {\n        MainTab: {\n          stack: ['One', 'Two'],\n          // or drawer: 'SomeDrawer',\n          options: () =\u003e ({\n            title: 'Main',\n          }),\n        },\n        ExampleTab: {\n          stack: 'ExampleStack',\n          // or drawer: 'SomeDrawer',\n          options: () =\u003e ({\n            title: 'Example',\n          }),\n        },\n      },\n      options: { ... }, // optional\n      navigatorProps: { ... }, // optional\n    },\n  },\n});\n```\n\n\u003c/details\u003e\n\n### Drawers\n\nDrawers are built using `Screens`, `Stacks`, and `Tabs` that have been defined before.\n\nDrawers can be defined by passing an object with `content` and, optionally, props for navigator.\n\nContent can take as a value one of `Stacks`, `Tabs`, array of `Screens`, or an object that describes stack and options for bottom tab (describing title, icon, etc.).\n\n\u003cdetails\u003e\n\u003csummary\u003eExample\u003c/summary\u003e\n\n```tsx\nconst navio = Navio.build({\n  // screens and stacks are taken from previous step\n  drawers: {\n    MainDrawer: {\n      layout: {\n        Main: 'MainStack',\n        Example: 'ExampleStack',\n        Playground: ['One', 'Two', 'Three'],\n      },\n      options: { ... }, // optional\n      navigatorProps: { ... }, // optional\n    },\n  },\n});\n```\n\n\u003c/details\u003e\n\n### Modals\n\nModals are built using `Screens` and `Stacks` that have been defined before. You can show/present them at any point of time while using the app.\n\nA modal can be defined by passing an array of `Screens` or a name of `Stacks`.\n\n\u003cdetails\u003e\n\u003csummary\u003eExample\u003c/summary\u003e\n\n```tsx\nconst navio = Navio.build({\n  // screens and stacks are taken from previous step\n  modals: {\n    ExampleModal: {\n      stack: 'ExampleStack',\n      options: { ... }, // optional\n    },\n  },\n});\n```\n\n\u003c/details\u003e\n\n### Root\n\nThis is a root name of the app. It can be one of `Stacks`, `Tabs` or `Drawers`.\n\nYou can change the root of the app later by `navio.setRoot('drawers', 'AppDrawer')` or by changing `initialRouteName` of `\u003cnavio.App /\u003e` component.\n\n\u003cdetails\u003e\n\u003csummary\u003eExample\u003c/summary\u003e\n\n```tsx\nconst navio = Navio.build({\n  // stacks, tabs and drawers are taken from previous examples\n  root: 'tabs.AppTabs', // or 'stacks.MainStack', or 'drawers.AppDrawer'\n});\n```\n\n\u003c/details\u003e\n\n### Hooks\n\nList of hooks that will be run on each generated `Stacks`, `Tabs` or `Drawers` navigators. Useful for dark mode or language change.\n\n\u003cdetails\u003e\n\u003csummary\u003eExample\u003c/summary\u003e\n\n```tsx\nconst navio = Navio.build({\n  hooks: [useTranslation],\n});\n```\n\n\u003c/details\u003e\n\n### Default options\n\nDefault options that will be applied per each `Stacks`'s, `Tabs`'s, `Drawer`'s, or `Modal`'s screens and containers generated within the app.\n\n`Note` All containers and `Tabs`'s and `Drawer`'s screens options have `headerShown: false` by default (in order to hide unnecessary navigation headers). You can always change them which might be useful if you want to have a native `\u003c Back` button when hiding tabs (pushing new `Stack`).\n\n\u003cdetails\u003e\n\u003csummary\u003eExample\u003c/summary\u003e\n\n```tsx\nconst navio = Navio.build({\n  defaultOptions: {\n    stacks: {\n      screen: {\n        headerShadowVisible: false,\n        headerTintColor: Colors.primary,\n      },\n      container: {\n        headerShown: true,\n      },\n    },\n    tabs: {\n      screen: tabDefaultOptions,\n    },\n    drawer: {\n      screen: drawerDefaultOptions,\n    },\n  },\n});\n```\n\n\u003c/details\u003e\n\n### App\n\nNavio generates root component for the app after the layout is defined. It can be used to directly pass it to `registerRootComponent()` or to wrap with extra providers or add more logic before the app's start up.\n\n```tsx\nconst navio = Navio.build({...});\n\nexport default () =\u003e \u003cnavio.App /\u003e\n```\n\nYou can change the root of the app by `navio.setRoot('drawers', 'AppDrawer')` or by changing `initialRouteName` of `\u003cnavio.App /\u003e` component.\n\n## FAQs\n\n### Passing params to a modal\n\nThis is most frequently asked question ([here](https://github.com/kanzitelli/rn-navio/issues/19), [here](https://github.com/kanzitelli/rn-navio/issues/20) and [here](https://github.com/kanzitelli/rn-navio/issues/28)). Below you can find two solutions:\n\n#### Old approach using React Navigation object\n\n```tsx\n// Use .navigate method of React Navigation object and pass params\nnavio.N.navigate('MyModal', {screen: 'ScreenName', params: {userId: 'someid'}});\n\n// Access params on a screen\nconst Screen = () =\u003e {\n  const {userId} = navio.useParams();\n};\n```\n\n#### New approach with Navio `v0.1.+`\n\n```tsx\n// Use .modals.show method of Navio and pass params\nnavio.modals.show('MyModal', {userId: 'someid'});\n\n// Access params on a screen\nconst Screen = () =\u003e {\n  const {userId} = navio.modals.getParams('MyModal');\n};\n```\n\n### What is the difference between Expo Router, Navio, and React Navigation?\n\n[Expo Router](https://docs.expo.dev/router/introduction/) is a routing library designed for Universal React Native applications using Expo. It operates on a file-based routing system, making it an excellent choice for developers looking to create applications for both native (iOS and Android) and web platforms using a single codebase.\n\nNavio, on the other hand, adopts a static configuration approach, similar to the layout building method seen in [React Native Navigation](https://github.com/wix/react-native-navigation). Navio primarily targets native platforms (iOS and Android), with less emphasis on web compatibility optimisation. In Navio, the application layout is configured within a single file.\n\nBoth libraries are built on top of the [React Navigation](https://github.com/react-navigation/react-navigation) and can be used in conjunction with it. This means all the hooks, actions, deep linking capabilities, and other features from [React Navigation](https://github.com/react-navigation/react-navigation) are expected to work seamlessly with both. Notably, [React Navigation](https://github.com/react-navigation/react-navigation) introduces [Static Configuration in v7](https://reactnavigation.org/docs/7.x/static-configuration) (which has yet to be released).\n\n## Is Navio production-ready?\n\nNavio has been essential for the [BUDDY Marketplace (iOS app)](https://buddify.app/get/buddy-ios), helping us launch it in just 2-3 months. Its use in the app, which is gaining users daily and needs new features fast, allows us to focus more on creating valuable business logic instead of dealing with basic setup tasks.\n\nHowever, Navio is still a young library and lacks some features, like [seamless Deep Linking integration](https://github.com/kanzitelli/expo-starter/issues/29), which are important for its full effectiveness in production apps. Since it's part of a live app, I plan to update it regularly, adding new functionalities. You can see what's coming by checking the [Future Plans section](#future-plans).\n\nIf you're using Navio in your app, I'd love to hear from you, and if there are additional features you're looking for.\n\n## Future plans\n\nNavio began as an experimental (and a bit weird) project aimed at minimizing repetitive code in app layout using [React Navigation](https://github.com/react-navigation/react-navigation). I like the concept of static configuration, where the entire app layout setup is condensed into a single file. After implementing it within the expo-starter and receiving positive feedback, I decided to integrate it into the [active mobile app](https://buddify.app/get/buddy-ios). There are additional features I'd like to integrate into Navio. One of the most exciting goals is to merge [React Navigation](https://github.com/react-navigation/react-navigation) and [React Native Navigation](https://github.com/wix/react-native-navigation) functionalities into a unified API, streamlining the development process even further.\n\n### Enhancements\n\nThere are still some things I would like to add to the library:\n\n- [x] `.updateOptions()` for specific tab and drawer.\n- [x] Tabs can be placed inside Drawer and vice versa.\n- [x] Pass props to Modals.\n- [ ] Make deeplinking easier by providing `linking` prop to screens. [Issue](https://github.com/kanzitelli/expo-starter/issues/29).\n- [ ] Make Navio universal by adding [RNN](https://github.com/wix/react-native-navigation) and [rnn-screens](https://github.com/kanzitelli/rnn-screens).\n- [ ] Extend Navio funtionality and app layout.\n- [ ] Easy integration of Navio with React Navigation (eg. navio.Stack())\n- [ ] TypeScript issues @ `index.tsx` file.\n\nFeel free to open an issue for any suggestions.\n\n## License\n\nThis project is [MIT licensed](/LICENSE.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkanzitelli%2Frn-navio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkanzitelli%2Frn-navio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkanzitelli%2Frn-navio/lists"}