Shadcn Carousel: Embla Powered Sliders for React
The shadcn carousel turns a row of slides into a swipeable, motion-smooth gallery, built for product imagery, testimonials, and featured content. This react carousel component wraps the Embla engine with Tailwind CSS styling and a composable TypeScript API that fits naturally into Next.js apps.
On this page you can copy carousel examples across the whole range: a three column layout, dot indicators, autoplay with loop, a vertical axis, custom arrows and custom dots, side thumbnails for gallery navigation, a slide counter, styled custom slides, and a progress bar tied to scroll position.
What is the Shadcn Carousel component?
A carousel presents a horizontal or vertical strip of content where only part is visible at once, with drag, swipe, and button navigation. The shadcn carousel exposes Content, Item, Previous, and Next parts you compose freely, which is why the variants on this page can look so different while sharing one core.
Slide sizing is pure CSS, so showing one slide, three columns, or a peek of the next item is a matter of basis classes rather than configuration flags.
Why choose this carousel?
- Real touch physics: Dragging and swiping feel native on mobile because the underlying engine handles momentum and snapping, not CSS hacks.
- Composable API: Arrows, dots, counters, and thumbnails are ordinary React children, so the custom arrows and custom dots examples require no plugin system.
- Autoplay and loop: The autoplay plus loop variant shows continuous rotation with proper pause behavior, ready for hero sections.
- Vertical support: Switching the axis gives you vertical sliders for tickers and stacked media without new markup.
- Lightweight: The engine is small and dependency-free, which keeps your Next.js bundle lean compared to legacy slider libraries.
Production tips
- Show partial next slides: Letting the next slide peek in from the edge signals swipeability far better than dots alone.
- Pause autoplay on hover: Auto-advancing content that users cannot stop is an accessibility failure. Pause on hover and focus, and keep intervals generous.
- Set slide dimensions early: Give slides explicit aspect ratios or heights so the carousel does not cause layout shift while images load.
- Provide non-swipe controls: Always keep visible previous and next buttons. Not every user will discover dragging, especially on desktop.
- Lazy load offscreen media: Slides beyond the viewport should load their images lazily to protect Core Web Vitals on image-heavy pages.
Works well with other components
Slides are usually more than images. A card makes a solid slide container for testimonials and product tiles, a badge can flag sale or new items, and the progress bar variant pairs conceptually with the standalone progress component. For click-through detail views, slides can open a dialog with a larger gallery.
Carousels like these power the media sections in our dashboard blocks and store-front templates, where the side thumbnails variant works especially well for product pages.
Under the hood
Every example is powered by Embla Carousel, a small headless slider engine with precise physics and a plugin system that provides the autoplay behavior used here. The shadcn layer adds context, accessible buttons, and Tailwind CSS styling on top.
Because Embla is headless and the wrapper is plain markup, the carousel works in any React project, whether the rest of your UI is built on Radix UI or Base UI primitives.