How it compares
This table compares documented first-class behavior.
| Feature | React Native Bottom Sheet | @gorhom/bottom-sheet | Expo UI BottomSheet | React Native Screens formSheetVia Expo Router or React Navigation | True Sheet |
|---|---|---|---|---|---|
| Architecture | |||||
| Native gestures and snapping | First-class | No first-class supportReanimated worklets | First-class | First-class | First-class |
| No Reanimated or Gesture Handler | First-class | No first-class support | First-class | First-class | First-class |
| Presentation | |||||
| Inline sheets | First-class | First-class | No first-class support | No first-class support | No first-class support |
| Modal sheets | First-class | First-class | First-class | First-class | First-class |
| Stacked modal sheets | First-class | First-class | Supported with caveatsNested in the parent on iOS | First-class | First-class |
| Detached (floating card) sheets | First-classInsets per detent | First-class | Supported with caveatsiOS 26+ system style only | Supported with caveatsiOS 26+ system style only | Supported with caveatsWeb only |
| Custom sheet surface | First-class | First-class | Supported with caveatsColor only | Supported with caveatsColor, radius, elevation | First-class |
| Sizing and detents | |||||
| Content-based sizing | First-class | First-class | First-class | First-class | First-class |
| Custom detents (heights and percentages) | First-class | First-class | Supported with caveatsHalf or full on Android | Supported with caveatsFractions only, up to 3 on Android | Supported with caveatsNo fixed heights, max 3 |
| Programmatic-only detents | First-class | Supported with caveats snapToPosition() | No first-class support | No first-class support | No first-class support |
| Interaction | |||||
| Regular React Native scrollables | First-class | No first-class supportNeeds library scroll wrappers | Supported with caveatsWrapped in RNHostView | Supported with caveatsLayout constraints | First-classVia scrollableRef |
| Position tracking | First-class | First-class | No first-class support | Supported with caveatsDetent index only | First-class |
| Keyboard handling | First-classApp-defined via controlled state and callbacks | First-classBuilt-in props and input | Supported with caveatsPlatform behavior only | Supported with caveatsPlatform/screen behavior only | First-classNative automatic handling |
| Platforms | |||||
| Web | First-class | Supported with caveatsMobile web per docs | First-class | No first-class supportRenders as full page | First-class |
React Native already has strong bottom-sheet options, but they make different tradeoffs. React Native Bottom Sheet gives you composable React Native primitives backed by native sheet mechanics: You compose the surface in React, while the sheet host, gestures, snapping, and scroll coordination run in native code on iOS and Android. On the web, the same behavior runs in JavaScript on React Native Web.
@gorhom/bottom-sheet is the
closest match in day-to-day functionality: configurable detents, dynamic sizing,
scroll coordination, inline sheets, and modal presentation. The main difference
is the implementation model. React Native Bottom Sheet moves the sheet host,
gestures, snapping, and scroll coordination into native code on iOS and Android,
so heavy React rendering and busy JS work are less likely to affect drag and
snap performance. It also does not require Reanimated or React Native Gesture
Handler. Because scroll coordination is native, regular React Native scrollables
work inside the sheet without bottom-sheet-specific list components or wrapper
factories.
Expo UI sheets, React Native
Screens form sheets (what
Expo Router and
React Navigation
use for presentation: 'formSheet'), and native modal-sheet libraries such as
True Sheet lean into platform presentation APIs.
That is a good fit when you want a system-style presented sheet, but it also
means the platform and presentation system decide more of the behavior. React
Native Bottom Sheet is built as a lower-level sheet primitive instead: The same
native implementation powers both persistent inline sheets and modal sheets, you
provide the complete sheet surface in React, and detents can include app-level
behavior such as programmatic-only snap points.
That difference also matters for layering. A platform-presented sheet can disable dimming and allow background interaction, but it is still drawn as a presented native sheet over the React Native view hierarchy. React Native Bottom Sheet gives you three placement modes instead:
BottomSheetis inline. It renders in your screen’s React Native hierarchy, so it can be layered alongside nearby content and constrained by the layout around it.ModalBottomSheetusesBottomSheetProvider’s React Native portal by default. Use this when you want modal behavior while keeping layering control in your React tree, so global UI such as toasts, menus, floating controls, or debug overlays can be arranged above or below the sheet by where you place them relative to the provider.ModalBottomSheetwithwindowOverlaybypasses the provider portal and presents in a window overlay. Use this when the sheet must appear above other native overlays, such as a React Navigation native-stack screen presented withpresentation: 'modal'.