Description:
Expo Glass Carousel is a React Native carousel component distributed as an Expo source project. Its cards bend through a glass lens during swipes and open into a focused view when tapped.
See in Action
Run the Expo Project
Clone the project to run the carousel with its configured dependencies:
git clone https://github.com/rit3zh/expo-glass-carousel
cd expo-glass-carousel
bun install
bun start -cRender Your Cards
Use the local component in src/components/glass-carousel inside a full-height screen:
import { Text, View } from "react-native";
import { GlassCarousel } from "@/components/glass-carousel";
const events = [
{ id: "jazz", title: "Friday Jazz", date: "November 13" },
{ id: "design", title: "Design Meetup", date: "November 19" },
];
export function EventGallery() {
return (
<GlassCarousel.Root onIndexChange={(index) => console.log(index)}>
{events.map((event) => (
<GlassCarousel.Item key={event.id} label={event.title}>
<View style={{ flex: 1, backgroundColor: "#172033", padding: 24 }}>
<Text style={{ color: "white", fontSize: 28 }}>{event.title}</Text>
<Text style={{ color: "white" }}>{event.date}</Text>
</View>
</GlassCarousel.Item>
))}
</GlassCarousel.Root>
);
}Control Snapshot Timing
The carousel captures card children as Skia images. Use static content inside each captured card. For remote images, set the item’s ready prop to false until loading completes. Change captureKey when updated content needs a new snapshot.
Use an item’s backdrop prop for content behind the card that blurs toward its bottom. The root’s background prop renders behind the entire carousel.
Children of GlassCarousel.Root that are not GlassCarousel.Item render as overlays.
Put interactive headers or navigation buttons there. Read useGlassCarousel() inside the root to access index, focused, itemCount, and reducedMotion, plus next(), previous(), open(), and close().
Navigation and Accessibility
Drag or flick to move through the cards. Tap a side card to center it, tap the center card to focus it, and tap again to close.
VoiceOver and TalkBack actions provide next, previous, focus, and close controls. The carousel respects reduced motion.
Carousel Options
| Root prop | Default | Purpose |
|---|---|---|
defaultIndex | 0 | Initial centered card |
cardHeight | 450 | Card height |
aspect | 3 / 4 | Width-to-height ratio |
gap | 12 | Card spacing |
radius | 10 | Corner radius |
onIndexChange | Unset | Receives the centered index |
onFocusChange | Unset | Receives the focused boolean |
accessibilityLabel | Liquid glass carousel | Carousel label |
background | Unset | Content behind the carousel |
style | Unset | Root container styling |
children | Unset | Card items and overlays |
Customize the Lens and Motion
Edit src/constants/components/glass-carousel.const.ts for lens shape, dispersion, backdrop blur, focus timing, and scroll physics.