Articles · GuidesUpdated October 2026

Tabs, stack and drawer are not three styles. They are three claims about what your app is.

Choosing a navigation pattern means deciding whether your app is a pile of screens you come back out of, a set of sections people switch between, or one screen with a menu hidden behind it. A stack says the second screen depends on the first. Tabs say these areas are equals. A drawer says the list is long and nobody needs it often. Get the claim right and the rest of the design argues with you less. Get it wrong and no amount of animation fixes it. If you inherited the project rather than typed it, the claim has already been made, and the useful first move is finding out which one.

What follows is the shapes an Expo project actually hands you, what Apple's and Google's own guidance expects of each, the one real asymmetry between the two platforms, and which parts you can change later without a rewrite. Every figure and field name below comes from Apple's, Google's and Expo's own current documentation, read on 17 October 2026. Most people meet this decision long before publishing to the App Store, and then live with it long after.

See the four shapes

The short version

Pick the shape from the content, then check what each side expects.

Lists with detail behind them want a stack. Three or four areas of equal standing want tabs, each with its own stack inside, which is the arrangement Expo names first in its own guide to real-life patterns. A long flat list of secondary destinations is the only honest case for a drawer. A thing the person does once and leaves wants a modal. Almost every real app is a stack inside tabs with a modal or two, and the interesting decisions are about which screens count as top-level.

The platforms then disagree about one thing that matters. Android gives every app a system Back, as a button or a gesture, and Google's quality guidelines make supporting it a test you can fail. iOS has no system Back, so the only way out of a pushed screen is the one your stack draws. The same layout file produces an app with two exits on one platform and one on the other, and that is worth knowing before you hide anything behind a gesture.

What navigation patterns does an Expo project actually give you?

Four, and Expo files them under that heading. Its documentation has a section called Navigation patterns, and the pages in it are Stack, JavaScript tabs, Native tabs, Drawer, Modals and nesting navigators, alongside pages on authentication and protected routes. The shapes themselves are the four. A stack pushes screens on top of one another. Tabs put a bar across the bottom and switch between sections. A drawer slides a menu in from the side, and Expo describes it as a menu people swipe open from the edge of the screen, usually with a button in the header as well. A modal sits over whatever was already there.

Tabs are the one with options, and this surprises people reading someone else's project. Expo documents three different tab navigators. JavaScript tabs, built on React Navigation's bottom tabs. Native tabs, which use the platform's own system tab bar. And custom tabs, headless components from the router's own user interface package for layouts the system bar cannot do. Three different ways to write the same bar at the bottom of the screen, with different APIs and different behaviour. The native tabs guide, last changed on 30 September 2026, is explicit that the native entry point is available in SDK 58 and later, and that SDK 54 through 57 use an unstable one instead. So the version of Expo the project is pinned to decides which of the three you are even allowed to write.

None of this lives in a config file. The shape is declared in _layout files inside the app directory, and a layout decides what holds the routes sitting beside it. Export Stack from a layout and its siblings become a stack. Export tabs and they become tabs. Nest one inside the other by putting a second layout in a subdirectory, which is how a stack ends up inside each tab. The root layout, directly inside the app directory, renders before every other route and is where font loading and theme providers go. If you want to know what shape a project you inherited has, you read its layout files, and there are usually only two or three of them.

One quiet detail in Expo's core concepts page, last changed on 28 July 2026, tells you how seriously the platform differences are taken. The default project template ships two tab implementations. Native tabs on Android and iOS, custom tabs on the web, chosen automatically through platform-specific file extensions, because native platforms have a system tab bar that already does things like scroll to top when you tap the current tab, while the web wants a bar styled like a website's. The framework does not pretend one tab bar fits every screen it runs on, and neither should you.

Start from the app

Which shape your app is asking for

Pick the sentence that describes what you have. The pattern follows from the content, not from the library.

Stack

A stack

One screen pushes the next and the person comes back the way they came. This is the only shape where going back has an obvious meaning, which is why it sits underneath almost every other shape as well.

A starting point, not a ruling. The only wrong answer is the one you picked because it was the first example in a tutorial.

What do Apple and Google expect navigation to do?

Apple writes about the furniture, Google writes about the behaviour, and the two documents barely overlap. Apple's guidance for tab bars opens by saying a tab bar lets people navigate between top-level sections of an app, then spends most of its advice on restraint. Use a tab bar to support navigation, not to provide actions, and reach for a toolbar if the control acts on the current view. Keep the tab bar visible as people move around the app, because hiding it makes them forget which area they are in, with one exception: a modal view may cover it, since a modal is temporary and self-contained. Do not disable or hide tab bar buttons even when their content is unavailable, because an interface that comes and goes feels unstable. Include labels, and use single words where you can.

The number everyone repeats is not on that page. There is no maximum of five tabs for iPhone in Apple's current tab bars guidance, read on 17 October 2026, and the page carries its own update notice dated 8 June 2026. What it says instead is to use the appropriate number of tabs required, weighing the cost of another tab against how often people need that section, and to avoid overflow tabs, because when horizontal space runs out the trailing tab becomes a More tab in iOS and iPadOS and everything behind it gets harder to notice. The only five on the page is advice for iPadOS tab bars that people customise themselves, where Apple suggests a default list of five or fewer so the bar stays consistent between compact and regular widths. The working rule is better than the number: as many tabs as fit without producing a More tab.

Apple, Human Interface Guidelines, Tab bars, read 17 October 2026

Google's side is a checklist with identifiers, which makes it easier to act on. The Core app quality guidelines, last updated on 21 September 2026, contain a Navigation block with three entries. Back_Button_Nav: the app supports standard back button navigation and does not make use of any custom onscreen back button prompts. Back_Gesture_Nav: the app supports gesture navigation for going back and for going to the home screen. State_Preservation: the app preserves state when it leaves the foreground and prevents accidental data loss from back navigation, and when it is resumed from the app switcher it returns the person to the exact state they left. These are tests with names, not taste.

Put the two documents side by side and the asymmetry is the whole story. Android already has a Back that works everywhere, so your job is to not break it and to not replace it with something you drew yourself. iOS has no system Back, so the control your stack draws is the only exit, and Apple's toolbar guidance, updated on 16 December 2025, asks you to use the standard Back and Close buttons because people already know what they do. One React Native layout file produces both outcomes. This is also why the choice is not a framework argument. The same split lands on anyone weighing Flutter against React Native, because it comes from the operating systems rather than from the toolkit.

Google, Core app quality guidelines, last updated 21 September 2026, read 17 October 2026

Why does a drawer feel wrong on an iPhone?

Because Apple does not describe one. The navigation section of Apple's component guidelines lists path controls, search fields, sidebars, tab bars and token fields. There is no drawer page and no hamburger menu page, and the words drawer, hamburger and side menu do not appear on the Tab bars, Sidebars or Toolbars pages either. That is an absence rather than a prohibition, and it is worth saying plainly: Apple nowhere forbids a drawer, and plenty of shipped iOS apps have one. But a pattern the platform owner has never documented is a pattern none of its examples will help you with.

Apple, Human Interface Guidelines, the navigation components, read 17 October 2026

What Apple documents instead is a sidebar, and the differences are instructive. A sidebar sits on the leading side of a view and lets people navigate between areas of the app or top-level collections like folders and playlists. It wants a lot of horizontal and vertical space, and Apple says that when space is limited a more compact control such as a tab bar may be the better experience. You may let people hide it, using the interaction they already know on that platform, but the guidance is to avoid hiding the sidebar by default so that it stays discoverable. And in general, show no more than two levels of hierarchy in it. A drawer is a sidebar that is hidden by default, which is the one thing Apple asks you not to do with it.

Android is the other way round. Drawers have been a normal Android pattern for years, Google's quality guidelines raise no objection to one, and the only navigation requirements they do print are about the system Back and about not losing state. So a drawer is a defensible Android answer and a thinner iOS one. In a React Native project that ships to both stores from the same layout file, that is a real cost rather than a philosophical one, and the fix is usually not to argue the point. It is to put the primary areas in tabs and the long secondary list in a settings screen pushed from a stack, which reads correctly on both platforms.

Google, Core app quality guidelines, the Navigation requirements, read 17 October 2026

If you decide you want one anyway, Expo makes it cheap to try and tells you the version it depends on. Its drawer guide, last changed on 3 June 2026, says the drawer navigator is bundled in the router itself in SDK 56 and later and uses a drawer layout library underneath, while SDK 54 and 55 install the React Navigation drawer separately. On Android and iOS it needs the animation and worklets packages to drive the motion. On the web, the animation is plain CSS. That difference is the sort of thing that decides whether a shape change is a layout edit or a new native build.

What do you change in a project you did not type?

Start by reading, not moving. Open every _layout file in the app directory and write down what each one exports. That is your map, and it is usually two or three files. Then look for the first index file inside the app directory, because Expo Router does not let you name an initial route in code: it looks for the first index matching the root URL and starts there. If the project starts inside a group of tabs, that is because the tab screens sit in a directory whose name is in parentheses, which groups them without adding anything to the URL. None of that is a convention somebody on your team invented. It is how the router works.

Then the cheap changes. Moving a group of screens under a tabs layout is a file move plus a layout edit, and relabelling or reordering tabs is a few lines. The expensive ones are easy to spot once you know what to look for. Adding native tabs or a drawer can pull in native dependencies, and that is the line between a change you can push as one of your over the air updates and one that needs a new binary in both stores. And because every screen's URL is its file path, moving a file renames its deep link. Anything that pointed at the old path, including links in emails you already sent, stops resolving.

Two things in the documentation are worth knowing before you plan anything for next quarter. Expo's nesting guide, last changed on 29 September 2026, carries a note at the top saying the navigation user interface elements, naming the link, tabs and stack components, may move out of the router library in future. And on iOS, headers have changed under everyone. Expo's stack guide states that from iOS 26 navigation headers adopt the system's new glass appearance by default and that it cannot be turned off per screen. The escape hatch is a single property list key, and Apple's own reference for that key says the system ignores it when you build for iOS 27 or later. So the compatibility mode is a window, not a decision, and a project parked on it has homework.

There is also one behaviour of the stack-inside-tabs shape that nobody expects until they see it, and Expo documents it. A link to a URL belonging to another tab switches tabs, and back then pops the stack inside the tab you landed in. Open a post in the Feed tab from the Settings tab and going back returns you to the top of Feed, not to Settings. With native tabs it is firmer than that, because the tab navigator loads every tab as soon as it mounts, so the destination tab is already sitting at its first screen before you link into it. Expo's own fix is a shape change: keep the detail route out of the tabs and push it from an outer stack instead. That page was last changed on 16 September 2026.

The last thing to check is not in any guideline. Open the app on a real phone, go three screens deep in one tab, switch tabs, come back, then press the Android back button until you leave. If any of those steps loses your place, the shape is not the problem. State is. That is the behaviour Google actually tests for, and it fails more often than the layout does.

The four shapes, and what each side says about them

The shapeWhere it lives in the projectOn iOSOn Android
StackA _layout file exporting StackYou draw the standard Back button, and it is the only way outYour back control is a convenience on top of the system one
TabsA _layout file exporting tabs, three flavours to choose fromDocumented as the way to move between top-level areasFine, and it has to survive the system Back
DrawerA _layout file exporting Drawer, bundled since SDK 56No drawer in the guidelines, a sidebar is the nearest thingA long-standing Android pattern
ModalAn ordinary route with presentation set to modalThe one sanctioned reason to cover a tab barFine, and Back has to close it
A back gesture the system ownsYour stack adds its own, through an option marked iOS onlyNoYes

Where this lands if a builder generated your app

Something already answered the question, and the answer is sitting in a file you can read. Newly is an AI app builder. You describe an app in plain English and it writes a real React Native and Expo project that you own, so the navigation shape is in the layout files like anyone else's, open to the same edits and the same arguments. It runs from $25 a month, with no free plan. That ownership is the only reason this page is useful to you: a tool that handed you a locked binary would make the whole decision somebody else's, and you would have nothing to read.

What a generator is good at here is the boring half. Laying out four tabs with a stack inside each, wiring the modal route, keeping the file paths tidy so the URLs stay sane. What it cannot do is decide which of your screens are top-level, because that is a claim about your product and not about your code. If you are weighing this against writing it yourself, the honest framing is in building React Native apps without coding: the shape is the part you still own either way.

Then the parts that touch the stores. Newly uploads iOS builds to TestFlight, publishes to Google Play internal testing and builds a standalone Android APK, and it keeps two-way GitHub sync so the layout files are yours in a repository rather than inside a tool. It does not submit to the App Store for you, because Apple requires the content owner to submit. Which means the person reviewing whether the tab bar makes sense to a stranger is you, and the best time to do that is before the first build goes out rather than after a reviewer mentions it.

Questions people ask about choosing a navigation pattern

Four shapes cover nearly everything. A stack, where screens push on top of each other and you come back the way you came. Tabs, where a bar at the bottom switches between sections of equal standing. A drawer, a menu that slides in from the side. And a modal, a screen presented over whatever was already there. Expo's own documentation has a section called Navigation patterns, and its pages are Stack, JavaScript tabs, Native tabs, Drawer, Modals and nesting navigators. Everything else is one of those four nested inside another.

Name the top-level areas, then let the shape follow

Write down the three or four things a person opens your app to do. That list is your tab bar. Everything else is a screen pushed from one of them, and the argument is over before you open a layout file.

Start building