- Components
- Data Display
- Carousel
Shadcn Carousel Components
A carousel with motion and swipe built using Embla Carousel. All carousel examples are compatible with both Radix UI and Base UI stacks. Browse our collection of 13 Shadcn Carousel variants.
3 columns
Dots
Autoplay + Loop
Vertical
Card 1
Description for card 1
Card 2
Description for card 2
Card 3
Description for card 3
Card 4
Description for card 4
“The component library saved us weeks of design work. The defaults look right out of the box and everything fits together.”
John Doe
CEO at Nordwind
“Clean code, thoughtful details and great documentation. Our design team adopted it in a single sprint.”
Jane Smith
Product Designer at Loopline
“Best developer experience I have had with a UI kit. Accessibility comes built in, which sealed the deal for us.”
Bob Johnson
Frontend Developer at Fieldset
Custom arrows
Custom dots
Side thumbnails
Slide counter
Custom slides
Beautiful Landscape
Explore the wonders of nature
Mountain View
Experience breathtaking views
Forest Path
Discover hidden trails
Progress bar
Unlock premium components
Explore Shadcn Blocks
Ready-made page sections built with the same components.
Shadcn Carousel Component
The Shadcn Carousel shows a row of slides that users move through with arrows, swipe gestures, dots or the keyboard. It lets you present several images, products or testimonials in the space of one, which is why it appears on hero sections, product galleries and review blocks across almost every kind of website.
Thumbnail galleries, autoplay sliders with a progress bar, testimonial slides and a vertical feed are all part of this React carousel component collection. Sliding, snapping and touch handling come from Embla Carousel, not from a Radix UI or Base UI primitive, and the styling comes from shadcn/ui, React and Tailwind CSS, so every variant behaves the same in either stack.
What is the Shadcn Carousel Component?
The shadcn/ui carousel is a thin React wrapper around the useEmblaCarousel hook. The root creates the Embla instance and shares it through context, the content part becomes the scrolling viewport, and the previous and next buttons read whether scrolling is possible so they disable themselves at the ends. Anything Embla supports, such as looping, alignment, drag free scrolling or plugins like autoplay, is passed through the opts and plugins props.
A carousel hides most of its content at any given time, so use it when the items are similar and browsing is optional, like photos or reviews. When users need to compare items or read all of them, a responsive grid of Cards is usually better. For switching between a few distinct views, use Tabs, and for a free-scrolling strip without snapping, a Scroll Area is simpler.
Anatomy of the Shadcn Carousel
| Part | Description |
|---|---|
| Carousel | The root region. Takes opts (Embla options), plugins, orientation ("horizontal" or "vertical") and setApi to expose the Embla API to your component. |
| CarouselContent | The overflow hidden viewport and the flex track that holds the slides. Negative margin on the track pairs with the padding on each item to create the gaps. |
| CarouselItem | One slide. It takes the full width by default; change its basis class to show two, three or more slides at once. |
| CarouselPrevious | An outline icon button that scrolls back one slide and disables itself at the start. It rotates automatically in vertical mode. |
| CarouselNext | The matching button that scrolls forward one slide and disables itself at the end. |
| useCarousel | A hook for custom controls placed inside the carousel. It returns the API, scrollPrev, scrollNext, canScrollPrev and canScrollNext. |
| CarouselApi | The exported type of the Embla API you receive from setApi, used for dots, counters and thumbnails. |
13 Shadcn Carousel Variants
Each carousel variant listed here is previewed live at the top of this page, together with its source code and install command.
- Basic: One image per slide with outline arrow buttons on both sides, the starting point for most galleries.
- Multiple slides per view: Responsive basis classes show one slide on mobile, two on medium screens and three on large screens.
- Dots and slide counter: Pagination below the slider, either as dots where the active one stretches into a pill or as a simple 2 / 4 counter.
- Thumbnail navigation: Clickable image thumbnails in a row below the main slide or in a column beside it, with the active thumbnail outlined and the others dimmed.
- Autoplay, loop and progress bar: Slides advance on their own with the Embla autoplay plugin and wrap around endlessly, optionally with a progress bar that fills until the next slide.
- Vertical: Stacks the slides in a column with vertical orientation and start alignment, showing two slides at a time from medium screens up. Useful for feeds and side panels.
- Content slides: Slides built from Cards, testimonials with star ratings and avatars, or images with a gradient caption overlay.
- Custom arrows: Replaces the default arrows with your own buttons centered below the slider. They call scrollPrev and scrollNext on the carousel API and disable themselves at the ends.
How to Install the Shadcn Carousel Component
Set up shadcn/ui in your project if you have not already, then add the Shadcn UI Kit registry to your components.json once:
{
"registries": {
"@shadcnuikit": "https://shadcnuikit.com/r/{name}.json"
}
}Then install a carousel variant by its name:
npx shadcn@latest add @shadcnuikit/carousel1The same command works with pnpm dlx, yarn dlx and bunx --bun. Each variant has a copy button for every package manager, and the code is added to your project as plain React and Tailwind CSS that you can edit freely.
How to Use the Shadcn Carousel Component
Install the component with the shadcn CLI, which also adds embla-carousel-react. Then wrap your slides in CarouselContent and add the navigation buttons. Pass Embla options such as loop through opts.
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@/components/ui/carousel"
const products = ["Chair", "Lamp", "Desk", "Shelf", "Sofa"]
export function ProductCarousel() {
return (
<Carousel
opts={{ align: "start", loop: true }}
className="w-full max-w-2xl"
aria-label="Featured products"
>
<CarouselContent>
{products.map((product) => (
<CarouselItem key={product} className="md:basis-1/2 lg:basis-1/3">
<div className="flex aspect-square items-center justify-center rounded-lg border">
{product}
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
)
}Why Use the Shadcn Carousel Component
- Smooth touch support: Embla handles swipe, drag and momentum natively, so the carousel feels right on phones and trackpads.
- Lightweight and headless: Embla does the physics while the markup and styling stay in your code as Tailwind classes.
- Full API access:
setApigives you the Embla API for dots, counters, thumbnails and events likeselect. - Plugin ready: Add autoplay, auto scroll, auto height or class names with the official Embla plugins.
- Stack independent: It does not depend on Radix UI or Base UI, so it fits any shadcn/ui project.
Common Carousel Use Cases
- Product galleries: Show several product photos with thumbnails on e-commerce detail pages.
- Testimonials: Rotate customer quotes with ratings and avatars on landing pages.
- Hero banners: Autoplaying promotional slides with captions at the top of a homepage.
- Related items: A horizontal row of recommended products, posts or courses.
- Onboarding: Step through feature highlights with dots showing progress.
- Portfolios: Present case study images or screenshots one at a time.
Customizing the Shadcn Carousel
Control how many slides are visible with the basis class on CarouselItem, change the gap by adjusting the negative margin on CarouselContent and the padding on each item, and move or restyle the arrows through their className and variant props. Behavior such as looping, alignment and how many slides move per click lives in Embla's options. Colors follow your theme tokens; generate a palette with the free Theme Generator.
For example, this adds autoplay that stops for good once the user drags or clicks an arrow:
import Autoplay from "embla-carousel-autoplay"
const autoplay = React.useRef(
Autoplay({ delay: 4000, stopOnInteraction: true })
)
<Carousel opts={{ loop: true }} plugins={[autoplay.current]}>
...
</Carousel>Carousel Accessibility and Keyboard Support
The root renders as a region with aria-roledescription="carousel" and each slide as a group with aria-roledescription="slide". Give the carousel an aria-label that describes its content. The arrow buttons include visually hidden "Previous slide" and "Next slide" labels, and custom dots or thumbnails should get an aria-label such as "Go to slide 3".
Autoplay can be a barrier for users who read slowly or use screen readers. If slides move on their own, offer a visible pause button or stop autoplay on interaction, and always provide meaningful alt text for images.
| Key | Action |
|---|---|
| ArrowLeft | Scrolls to the previous slide when focus is inside the carousel, in both horizontal and vertical orientation. |
| ArrowRight | Scrolls to the next slide when focus is inside the carousel, in both horizontal and vertical orientation. |
| Tab | Moves focus to the next control, such as the arrows or dots. |
| ShiftTab | Moves focus to the previous control. |
| Enter | Activates the focused arrow, dot or thumbnail button. |
| Space | Activates the focused arrow, dot or thumbnail button. |
Carousel Best Practices
- Keep the number of slides small; users rarely look past the third or fourth one.
- Put the most important slide first instead of relying on users to swipe to it.
- Always show a position indicator such as dots, thumbnails or a counter so users know how many slides there are.
- Avoid fast autoplay and let users pause it, especially when slides contain text.
- Reserve space for the arrows: they sit outside the slider with negative offsets, so add horizontal padding to the parent or move them inside with
className. - Use a grid of Cards instead when users need to compare items.
Components Related to Carousel
Shadcn Carousel FAQ
Looking for something else? Browse all shadcn/ui components or ready-made UI blocks built with them.















