react-brain
Browse decisions
React & language foundations 3App architecture 10UI 13Platform & native 9Build, test, observe, secure 6AI in React apps 3stack composerdecision recordscensusstaleness bencharchitecturechangelogmethodologyroadmap

entriesui · verified 2026-08-18 · react-native

Bottom sheets & modal sheets (React Native)

reviewedconfidence: mediumthis tier holds 67% on the public scorecard (6/19 graded · 0 overturned) →

related decisions: polish · nav

re-verified 2× — 2026-08-18 · 2026-07-16 · changelog

recommendation

Default to a NATIVE sheet — react-native-true-sheet today — unless you need custom gesture choreography, where @gorhom/bottom-sheet remains the flexible JS incumbent. The axis is simple: gorhom DRAWS a sheet in JS, the native libraries PRESENT the OS one, so detents, dismissal physics, screen-reader semantics and iOS 26 Liquid Glass come from the platform instead of being re-implemented. Every native option is pre-1.0 or fast-moving — pin versions.

  • custom gesture-heavy sheet UIs (drag handoff to inner scroll, dynamic snap logic) → @gorhom/bottom-sheet
  • platform-authentic native sheet, stable today → react-native-true-sheet (3.11.x; New Architecture required — it is Fabric-only)
  • the sheet must hold a form or a text input → prefer a native sheet: keyboard avoidance inside a JS-drawn sheet is your problem to solve, while true-sheet ships keyboard handling and native a11y strings
  • iPad / Android tablet layouts → true-sheet side sheets; a phone-shaped bottom sheet stretched across a tablet is the giveaway of a JS-drawn one
  • betting on the Software Mansion native line → @swmansion/react-native-bottom-sheet — 0.x, pin versions and expect breaking changes
  • the sheet is really a SCREEN (deep-linkable, own route) → react-native-screens FormSheet via native-stack (experimental — pin; see RB-E-NAV)

Options & tradeoffs

the field considered — and why each one isn’t the default here

optiontradeoffevidence
@gorhom/bottom-sheetthe JS incumbent (5.2.14, published 2026-05-09) — built on Reanimated + Gesture Handler, dynamic sizing, scrollable content handoff, ~9.1k stars and by far the largest deployed base; JS-driven look (it DRAWS a sheet, it does not present the OS one), most flexible for custom gesture-heavy sheets. Maintenance is the thing to watch: no release and no repo push since 2026-05-09 with 74 open issues, while both native entrants ship weekly
@swmansion/react-native-bottom-sheetSoftware Mansion's native sheet components (inline AND modal, snap points; software-mansion-labs) — platform-authentic behavior; 0.16.2 latest with 0.17.0-next.1 on the `next` tag (verified 2026-08-18), still 0.x — pin, expect churn
react-native-true-sheet (@lodev09)native sheets on iOS, Android and web (3.11.11, 2026-08-12; a 4.0.0-beta.3 line is open) — the platform-authentic option that pre-dates SWM's entrant, and the most complete one today: Fabric-only, native accessibility, built-in keyboard handling, side sheets on iPad/Android tablets, iOS 26+ Liquid Glass, first-class Reanimated, and a built-in SHEET NAVIGATOR for React Navigation. Releasing every few days152k/wk · ships in 1/14
react-native-screens FormSheetthe sheet as a NAVIGATION DESTINATION — native-stack presents a route as a form sheet (detents); still experimental on the 4.x line (4.27.0, 2026-08-07; 5.0.0-alpha.2 on `next`) — see RB-E-NAV. Right shape when the sheet is conceptually a screen, but true-sheet's sheet navigator now covers that case too without waiting on the screens rewrite

evidence: npm weekly downloads (signals snapshot) · “ships in n/D” = adoption across the production-app census, honest denominators

npm weekly downloads (from the corpus's last signals run): @gorhom/bottom-sheet 2.4M · @swmansion/react-native-bottom-sheet 27k · @lodev09/react-native-true-sheet 152k

Verified notes

NEW entry (2026-07-16), found by the TWiR #284–290 BACK-AUDIT: bottom sheets had NO corpus home while three independent signals accumulated in seven issues — Software Mansion shipped a NEW native bottom-sheet library (#284; 0.16 by #289), react-native-true-sheet 3.11 (#287), and react-native-screens' experimental FormSheet (#290) — and the incumbent everyone deploys (@gorhom/bottom-sheet) was never covered. Same failure shape as the AUTH gap: a domain with no entry is invisible to triage until a sweep or recurrence surfaces it. Versions verified vs npm 2026-07-16: gorhom 5.2.14 (2026-05), @swmansion 0.16.2 (2026-07-14), true-sheet 3.11.9 (2026-07-15). The selection axis mirrors RB-E-POLISH's toasts: JS-flexible incumbent vs platform-authentic native entrants; the SWM line is the one to WATCH for 1.0 (tripwire below). GRADUATED drafted → reviewed 2026-08-18 (upkeep-routine step 4). What changed in the month since the entry was drafted, all re-verified against npm + the repos: true-sheet went from "the simpler alternative" to the most COMPLETE native option (3.11.11, releasing every few days, with a React Navigation sheet navigator, side sheets, built-in keyboard handling, native accessibility strings and iOS 26 Liquid Glass support), while gorhom has not published or pushed since 2026-05-09 and carries 74 open issues. That inverts the default: the JS incumbent is now the specialist choice for custom gesture work, not the safe first pick. Adoption still lags the argument — the 34-app census (2026-08-18) finds sheets in 7 of 14 RN apps, gorhom in 7 and true-sheet in 1 — which is exactly what a recent inversion looks like, and why this is medium confidence rather than high.

Canonical reading

Editorial annotations on why each piece matters — the articles themselves are the originals; read them there.

Building a drawer componentEmil Kowalski (Vaul author)

The design rationale under good sheets/drawers, from the author of web's canonical drawer (Vaul): velocity-based dismissal over distance thresholds, snap-point logic, scroll-vs-drag handoff, and background scaling — the interaction details that decide whether a sheet feels native. Web-authored, but it is the why-good-sheets-feel-good reference, exactly as this corpus uses his toast piece in RB-E-POLISH.

Sources

Depth (in-domain rules) is owned by the react-native-best-practices skill — this entry is selection breadth.

The full explanation

The reviewed long-form essay behind this entry — the why, not a how-to. Also on GitHub.

About bottom sheets & modal sheets (React Native)

Diataxis: Explanation. This page builds understanding of why the sheet decision is a decision at all, and why the recommendation now leans native. It is not an install guide or an API reference. Rendering-performance depth belongs to react-native-best-practices; keyboard behavior to RB-E-KEYBOARD; routing to RB-E-NAV; platform-feel in general to RB-E-NATIVE-UI. Read this for the why.

The one distinction that organises everything: drawing a sheet vs presenting one

There are two fundamentally different things a React Native library can do when you ask for a bottom sheet, and almost every difference between the options falls out of which one it does.

It can draw a sheet: a View positioned by animated values, with pan gestures wired to translate it, snap points implemented as numbers you supply, and a backdrop you also draw. That is @gorhom/bottom-sheet, built on Reanimated and Gesture Handler. Everything about the sheet is yours — which is exactly the appeal, and exactly the cost.

Or it can present one: hand the content to the platform and let the OS put it on screen — UISheetPresentationController on iOS, the Material bottom-sheet machinery on Android. That is react-native-true-sheet and @swmansion/react-native-bottom-sheet. You get the platform's detents, the platform's rubber-banding and dismissal physics, the platform's screen-reader semantics, and — on iOS 26 — the platform's Liquid Glass material, because none of it was re-implemented in the first place.

Everything below is a consequence of that split.

Why "just draw it" stops being free

A drawn sheet has to re-answer, in your code, questions the OS already answers:

  • Dismissal physics. Real sheets dismiss on velocity, not on distance crossed — a fast flick from near the top should dismiss, a slow drag past halfway should not. The reading in the index entry (Emil Kowalski, author of Vaul) is the canonical rationale for this and the related choices, and it is worth reading precisely because these are your decisions once you draw.
  • Scroll-vs-drag handoff. When the sheet contains a list, the gesture has to belong to the sheet until the list is at its top, and to the list after. Getting this subtly wrong is the most common way a sheet feels "off" without anyone being able to say why.
  • Accessibility semantics. A presented sheet arrives with a grabber label, detent state announcements and a dialog/pane role. A drawn one is a View until you say otherwise.
  • The keyboard. A sheet holding a TextInput has to move with the keyboard, on two platforms that animate the keyboard on different clocks (see RB-E-KEYBOARD). Native sheets inherit the platform's behavior; drawn sheets inherit your bug backlog.
  • Tablets. iPad and Android tablets expect a side sheet, not a phone-shaped sheet stretched across a tablet display. A phone-shaped sheet on a tablet is usually the visible signature of a drawn one.

None of that makes drawing wrong. It makes drawing a choice you should make deliberately, for sheets whose gesture behavior is genuinely custom.

Why the default inverted this month

When this entry was drafted (2026-07-16), @gorhom/bottom-sheet was the safe default and the native entrants were the interesting newcomers. A month of watching moved the line:

  • The native option grew up. react-native-true-sheet reached 3.11.11 (2026-08-12) while publishing every few days, and it is no longer the simpler option — it is the more complete one: Fabric-only by design, native accessibility strings, built-in keyboard handling, side sheets for iPad and Android tablets, iOS 26+ Liquid Glass, first-class Reanimated interop, and a sheet navigator for React Navigation. A 4.0.0-beta.3 line is already open.
  • The incumbent went quiet. @gorhom/bottom-sheet sits at 5.2.14, published 2026-05-09, with no repository push since that date and 74 open issues. It is not abandoned, and ~9.1k stars of deployed base do not evaporate — but "safe default" is a claim about maintenance as much as about features, and that claim is weaker than it was.

So the index entry now says: present by default, draw when you need custom choreography.

The third shape: a sheet that is really a screen

Some sheets are not components at all. If the sheet is deep-linkable, appears in the back stack, and owns its own data loading, it is a route that happens to be presented as a sheet.

Two paths exist. react-native-screens can present a native-stack route as a FormSheet with detents — still experimental on the 4.x line (4.27.0, 2026-08-07; a 5.0.0-alpha.2 line is open), so pin it. Or use react-native-true-sheet's sheet navigator, which reaches the same shape without waiting on the screens rewrite. The decision is not "which library" but "is this a component or a destination" — and answering that first usually settles the library question.

What the field looks like (and why confidence is medium, not high)

The 34-app census (2026-08-18) finds a sheet library in 7 of 14 React Native apps: @gorhom/bottom-sheet in 7 of them, react-native-true-sheet in 1. Adoption still points at the incumbent, which is what a recent inversion looks like — the argument moved before the ecosystem did. Two further reasons to hold this at medium confidence: @swmansion/react-native-bottom-sheet is still 0.x (0.16.2, with 0.17.0-next.1 on the next tag), and the option this entry now leads with has a major version in beta. Both are wired as tripwires in the index entry, so a stable 1.0 or 4.0 forces this page to be re-read rather than quietly aging.

How to read the recommendation

  1. Is this a destination or a component? Destination → sheet navigator or FormSheet route.
  2. Does the sheet need genuinely custom gesture behavior? Yes → @gorhom/bottom-sheet, and budget for the physics and handoff work as real work.
  3. Otherwise, present the OS sheetreact-native-true-sheet today (New Architecture required), @swmansion/react-native-bottom-sheet if you want to bet on the Software Mansion line and can absorb 0.x churn.
  4. Pin whichever you choose. Every native option here is pre-1.0 or shipping weekly.

Related in ui: styling · component-libs · animation · lists · a11y · i18n · charts · editors · svg · maps · calendars · polish