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.

Image 1
Image 2
Image 3
Image 4
Image 5

3 columns

Image 1
Image 2
Image 3
Image 4
Image 5

Dots

Image 1
Image 2
Image 3
Image 4

Autoplay + Loop

Image 1
Image 2
Image 3

Vertical

Image 1
Image 2
Image 3

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.”
JD

John Doe

CEO at Nordwind

“Clean code, thoughtful details and great documentation. Our design team adopted it in a single sprint.”
JS

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.”
BJ

Bob Johnson

Frontend Developer at Fieldset

Custom arrows

Image 1
Image 2
Image 3

Custom dots

Image 1
Image 2
Image 3
Image 4

Side thumbnails

Image 1
Image 2
Image 3
Image 4

Slide counter

Image 1
Image 2
Image 3
Image 4
0 / 0

Custom slides

Beautiful Landscape

Beautiful Landscape

Explore the wonders of nature

Mountain View

Mountain View

Experience breathtaking views

Forest Path

Forest Path

Discover hidden trails

Progress bar

Image 1
Image 2
Image 3
Image 4
Unlock premium components
Get full control of shadcn/ui components, blocks and instances, including future additions.

Explore Shadcn Blocks

Ready-made page sections built with the same components.

View all blocks

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

PartDescription
CarouselThe root region. Takes opts (Embla options), plugins, orientation ("horizontal" or "vertical") and setApi to expose the Embla API to your component.
CarouselContentThe 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.
CarouselItemOne slide. It takes the full width by default; change its basis class to show two, three or more slides at once.
CarouselPreviousAn outline icon button that scrolls back one slide and disables itself at the start. It rotates automatically in vertical mode.
CarouselNextThe matching button that scrolls forward one slide and disables itself at the end.
useCarouselA hook for custom controls placed inside the carousel. It returns the API, scrollPrev, scrollNext, canScrollPrev and canScrollNext.
CarouselApiThe 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/carousel1

The 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: setApi gives you the Embla API for dots, counters, thumbnails and events like select.
  • 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.

KeyAction
ArrowLeftScrolls to the previous slide when focus is inside the carousel, in both horizontal and vertical orientation.
ArrowRightScrolls to the next slide when focus is inside the carousel, in both horizontal and vertical orientation.
TabMoves focus to the next control, such as the arrows or dots.
ShiftTabMoves focus to the previous control.
EnterActivates the focused arrow, dot or thumbnail button.
SpaceActivates 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

Install embla-carousel-autoplay, create the plugin with Autoplay({ delay: 4000 }) inside a useRef, and pass it to the plugins prop of Carousel. Add opts={{ loop: true }} so the slides wrap around at the end.

Change the basis class on CarouselItem. basis-1/2 shows two slides and basis-1/3 shows three, and responsive prefixes such as md:basis-1/2 lg:basis-1/3 adapt the count to the screen size.

Pass setApi to Carousel to get the Embla API, read api.scrollSnapList().length for the total and api.selectedScrollSnap() for the current slide, and update state in an api.on('select') listener. Render a button per slide that calls api.scrollTo(index).

No. The shadcn/ui carousel is built on Embla Carousel through the embla-carousel-react package. Because it does not depend on Radix UI or Base UI primitives, it works the same in both kinds of projects.

Set orientation="vertical" on Carousel. It switches Embla to the y axis and moves the arrows above and below the slides. Give CarouselContent a fixed height such as h-[400px], and use a basis class like md:basis-1/2 on CarouselItem to show two slides at a time.

Looking for something else? Browse all shadcn/ui components or ready-made UI blocks built with them.