Native Bottom Sheet

A gesture-driven React Native bottom sheet for Expo — snap points, velocity-projected flicks, rubber banding, scroll handoff and a real blur backdrop.

componentModals & SheetsExpo SDK 57Free

Preview

Native Bottom Sheet screenshot 1

Usage

Terminal
$npx expo install react-native-reanimated react-native-worklets react-native-gesture-handler expo-blur react-native-safe-area-context

Built with React Native core only — no third-party UI library required.

Examples

6

The case that exercises the scroll handoff. BottomSheetScrollView wires the list into the sheet's own gesture so both recognise at once — the list scrolls only at the top snap, and pulling down at offset 0 hands control back to the sheet.

tsx
<BottomSheet  ref={sheetRef}  blurTarget={blurTarget}  snapPoints={['38%'', '68%'', '94%'']}  blurIntensity={60}>  <BottomSheetScrollView>    {tracks.map((track) => (      <Row key={track.title} {...track} />    ))}  </BottomSheetScrollView></BottomSheet>

Overview

Native Bottom Sheet is a gesture-driven sheet for Expo and React Native that keeps every frame on the UI thread. Position is a single Reanimated shared value — translateY, the distance from the top of the screen to the sheet's top edge — and the drag, the springs and the backdrop blur all read from it, so nothing round-trips through JavaScript during a gesture. On release the sheet projects where your flick would land (velocity × 0.12s) and settles on whichever snap point is nearest that spot rather than the one you let go at, so a hard flick skips a stop and a slow drag does not. "Closed" competes in the same nearest-neighbour search, which means pan-down-to-close needs no separate threshold. Pulling above the top snap rubber-bands asymptotically, the inner BottomSheetScrollView hands drag control back to the sheet the moment the list sits at offset 0, and the backdrop is a real gaussian blur whose intensity ramps with sheet position — not a fade-in of a pre-blurred bitmap. The snap and close springs are deliberately asymmetric: dismissal settles in roughly 130ms and arrival in roughly 170ms, both just under critically damped so they land crisply with no visible bounce. It ships with an imperative ref API — open, close, snapToIndex, expand, collapse and getIndex — and closes on the Android hardware back button.

What's included

  • Snap points as percentages or pixel heights
  • Velocity projection — a flick skips stops, a drag does not
  • Pan-down-to-close with no separate threshold
  • iOS-style rubber banding past the top snap
  • Scroll-to-drag handoff via BottomSheetScrollView
  • Real gaussian blur backdrop that ramps with position
  • Asymmetric springs — close lands faster than open
  • Everything on the UI thread (Reanimated 4 worklets)
  • Ref API: open, close, snapToIndex, expand, collapse, getIndex
  • Android hardware back button closes the sheet
  • Style overrides for the surface and grab handle
  • MIT licensed — full source on GitHub

Tech Stack

ExpoReact NativeJavaScriptreact-native-reanimatedreact-native-gesture-handlerexpo-blurreact-native-safe-area-context

Get this component

Free

One-time payment · Lifetime access

Free License

Personal and commercial use

Free
  • Use in 1 personal project
  • Lifetime access to updates
  • Email support
  • Remove attribution
  • Commercial use included
Get it on GitHub
Full JavaScript source code
All examples & variants
Lifetime updates
Public repo — clone or fork it