React Native True Sheet

[!NOTE]
š Version 3.0 is here! Completely rebuilt for Fabric with new features like automatic ScrollView detection, native headers/footers, sheet stacking, and more. Read the announcement
The true native bottom sheet experience for your React Native Apps. š©



Features
- ā” Powered by Fabric - Built on React Native's new architecture for maximum performance
- š Fully Native - Implemented in the native realm, zero JS hacks
- āæ Accessible - Native accessibility and screen reader support out of the box
- š Flexible API - Use imperative methods or lifecycle events
- šŖ Liquid Glass - iOS 26+ Liquid Glass support out of the box, featured in Expo Blog
- š Reanimated - First-class support for react-native-reanimated
- š§ React Navigation - Built-in sheet navigator for seamless navigation integration
- š Web Support - Full web support out of the box
Installation
[!IMPORTANT]
Version 3.0+ requires React Native's New Architecture (Fabric)
For the old architecture, use version 2.x. See the Migration Guide for upgrading.
Prerequisites
- React Native >= 0.76 (Expo SDK 52+)
- New Architecture enabled (default in RN 0.76+)
- Xcode 26.2 (strongly recommended for better library functionality)
Expo
npx expo install @lodev09/react-native-true-sheet
Bare React Native
yarn add @lodev09/react-native-true-sheet
cd ios && pod install
EAS Build (iOS)
When using EAS Build to build your iOS app, you must configure your eas.json to use a build image that includes Xcode 26.2. Use "image": "latest" or choose from the available build images:
{
"build": {
"production": {
"ios": {
"image": "latest"
}
},
"development": {
"ios": {
"image": "latest"
}
}
}
}
Documentation
Usage
import { TrueSheet } from "@lodev09/react-native-true-sheet"
export const App = () => {
const sheet = useRef<TrueSheet>(null)
const present = async () => {
await sheet.current?.present()
console.log('horray! sheet has been presented š©')
}
const dismiss = async () => {
await sheet.current?.dismiss()
console.log('Bye bye š')
}
return (
<View>
<Button onPress={present} title="Present" />
<TrueSheet
ref={sheet}
detents={['auto', 1]}
>
<Button onPress={dismiss} title="Dismiss" />
</TrueSheet>
</View>
)
}
Testing
TrueSheet exports mocks for easy testing:
jest.mock('@lodev09/react-native-true-sheet', () =>
require('@lodev09/react-native-true-sheet/mock')
);
jest.mock('@lodev09/react-native-true-sheet/navigation', () =>
require('@lodev09/react-native-true-sheet/navigation/mock')
);
jest.mock('@lodev09/react-native-true-sheet/reanimated', () =>
require('@lodev09/react-native-true-sheet/reanimated/mock')
);
All methods (present, dismiss, resize) are mocked as Jest functions, allowing you to test your components without native dependencies.
Full Testing Guide
Contributing
See the contributing guide to learn how to contribute to the repository and the development workflow.
License
MIT
Made with ā¤ļø by @lodev09