This is documentation for the next SDK version. For up-to-date documentation, see the latest version (SDK 55).

BottomSheet

A bottom sheet compatible with @gorhom/bottom-sheet.

Android
iOS
Web
Included in Expo Go

For the complete documentation index, see llms.txt. Use this file to discover all available pages.

A BottomSheet component with an API compatible with @gorhom/bottom-sheet. It wraps the platform-specific @expo/ui primitives: Jetpack Compose ModalBottomSheet on Android and SwiftUI BottomSheet on iOS. On web, it uses a vaul drawer.

If you need lower-level control over platform-specific styling, modifiers, or layout behavior, use the native primitives directly.

Installation

Terminal
npx expo install @expo/ui

If you are installing this in an existing React Native app, make sure to install expo in your project.

Migrating from @gorhom/bottom-sheet

  • Update imports from:

    import BottomSheet, { BottomSheetView } from '@gorhom/bottom-sheet';

    To use @expo/ui/community/bottom-sheet:

    import BottomSheet, { BottomSheetView } from '@expo/ui/community/bottom-sheet';
  • GestureHandlerRootView from react-native-gesture-handler is not required by this implementation. You can leave it in place if other parts of your app need it.

  • Component and hook exports such as BottomSheetBackdrop, BottomSheetHandle, BottomSheetFooter, BottomSheetDraggableView, BottomSheetVirtualizedList, BottomSheetFlashList, useBottomSheetModal, useBottomSheetSpringConfigs, and useBottomSheetTimingConfigs are not supported. Some related prop types are exported for API compatibility.

Basic usage

BottomSheetExample.tsx
import { useRef } from 'react'; import { Button, Text, View } from 'react-native'; import BottomSheet, { BottomSheetView } from '@expo/ui/community/bottom-sheet'; export default function BottomSheetExample() { const sheetRef = useRef<BottomSheet>(null); return ( <View style={{ flex: 1 }}> <Button title="Open" onPress={() => sheetRef.current?.snapToIndex(0)} /> <BottomSheet ref={sheetRef} snapPoints={['25%', '50%', '90%']} index={-1} onChange={index => { console.log('onChange', index); }} onClose={() => { console.log('closed'); }} enablePanDownToClose> <BottomSheetView style={{ flex: 1, padding: 24, alignItems: 'center' }}> <Text>Sheet content</Text> </BottomSheetView> </BottomSheet> </View> ); }

BottomSheetModal

Use BottomSheetModal when migrating from @gorhom/bottom-sheet modal APIs. It starts closed and opens with present().

BottomSheetModalExample.tsx
import { useRef } from 'react'; import { Button, Text, View } from 'react-native'; import { BottomSheetModal, BottomSheetView } from '@expo/ui/community/bottom-sheet'; export default function BottomSheetModalExample() { const modalRef = useRef<BottomSheetModal>(null); return ( <View style={{ flex: 1 }}> <Button title="Present" onPress={() => modalRef.current?.present()} /> <BottomSheetModal ref={modalRef} snapPoints={['50%', '90%']} enablePanDownToClose> <BottomSheetView style={{ padding: 24 }}> <Text>Modal content</Text> <Button title="Dismiss" onPress={() => modalRef.current?.dismiss()} /> </BottomSheetView> </BottomSheetModal> </View> ); }

Dynamic sizing

When snapPoints is not provided, the sheet sizes to fit its content by default. Use BottomSheetView for the sheet content wrapper.

DynamicBottomSheetExample.tsx
import { useRef } from 'react'; import { Button, Text, View } from 'react-native'; import BottomSheet, { BottomSheetView } from '@expo/ui/community/bottom-sheet'; export default function DynamicBottomSheetExample() { const sheetRef = useRef<BottomSheet>(null); return ( <View style={{ flex: 1 }}> <Button title="Open" onPress={() => sheetRef.current?.present()} /> <BottomSheet ref={sheetRef} index={-1} enablePanDownToClose> <BottomSheetView style={{ padding: 24 }}> <Text>This sheet sizes itself to its content.</Text> </BottomSheetView> </BottomSheet> </View> ); }

Platform behavior

@gorhom/bottom-sheet renders inline at the bottom of its parent view. This component uses native modal presentation on Android and iOS, and a drawer overlay on web.

This difference is intentional. @gorhom/bottom-sheet owns the gesture and animation layer through react-native-gesture-handler and react-native-reanimated, while @expo/ui/community/bottom-sheet delegates those behaviors to Jetpack Compose, SwiftUI, and the web drawer primitive. As a result, this component is best suited for modal bottom sheet flows, including callsites that use the BottomSheet API rather than BottomSheetModal.

FeatureAndroidiOSWeb
PresentationJetpack Compose modal bottom sheetSwiftUI sheetvaul drawer
Snap pointsMaps to partial and expanded statesSupports provided snap pointsSupports provided snap points
No snapPointsFits contentFits contentFits content
Pan down to closeAlso enables back button and scrim tap dismissAlso enables backdrop tap dismissEnables drawer dismiss
Persistent inline peekNot supportedNot supportedNot supported

Supported exports

ExportSupportedNotes
BottomSheetYesModal on Android and iOS, drawer on web
BottomSheetModalYesStarts closed and opens with present()
BottomSheetModalProviderYesRenders children directly for compatibility
BottomSheetViewYesWraps sheet content
BottomSheetScrollViewYesRe-export of React Native ScrollView
BottomSheetFlatListYesRe-export of React Native FlatList
BottomSheetSectionListYesRe-export of React Native SectionList
BottomSheetTextInputYesRe-export of React Native TextInput
useBottomSheetYesReturns the sheet ref methods from context
BottomSheetBackdropNoThe native sheet or web drawer handles the backdrop
BottomSheetHandleNoThe native sheet or web drawer handles the drag indicator
BottomSheetFooterNoNo equivalent in this implementation

Compatibility notes

  • snapPoints, index, onChange, onClose, onDismiss, enablePanDownToClose, and enableDynamicSizing are supported.
  • handleComponent={null} hides the native or web drag indicator. Custom handle components are not rendered on native platforms.
  • backgroundStyle applies fully on web. On Android, backgroundColor is used for the native container color. On iOS, the system sheet background is used.
  • Animation, over-drag, content panning, handle panning, keyboard behavior, custom backdrop, custom background, custom footer, animated value, and detached props are accepted for API compatibility but do not change behavior.

API

import BottomSheet from '@expo/ui/community/bottom-sheet';

No API data file found, sorry!