React carousel components

Swipeable rails, card decks and infinite marquees, each with keyboard stepping and snap already handled. Install one and the source is yours to change.

Built with the stack you already ship

React
Next.js
TypeScript
Tailwind CSS
Framer Motion
Vite
Astro
React
Next.js
TypeScript
Tailwind CSS
Framer Motion
Vite
Astro

Carousels and sliders

From a standard accessible carousel to a cylindrical photo rail with inertia. Each ships with pointer, keyboard and touch input already wired.

Continuous and scroll driven motion

Not everything that moves sideways needs arrows. These loop on their own or advance with the scroll position instead of a click.

Carousels have a bad reputation and most of it is earned. The classic hero carousel that auto rotates through five marketing messages performs badly because people learn to ignore anything that moves on its own, and because only the first slide is ever really seen. That is not an argument against the pattern, it is an argument against using it to hide content that should have been on the page. A carousel works when the items are genuinely equivalent and the visitor is browsing rather than being sold to.

Product images, testimonials, logos and gallery photos all fit that description. A row of feature explanations does not, because those are not equivalent and hiding four of five behind an interaction means most people read one. The test is simple: if you would be unhappy for someone to see only the first item, do not put it in a carousel.

Once you have decided the pattern fits, the interaction model is the next choice. A standard carousel with arrows and dots is the most predictable and the easiest to make accessible, which is why the base Carousel primitive here is built that way. A swipe deck like Stacked Swipe Deck is better on touch and worse with a mouse. A drag rail like Orbital Image Carousel feels the best of the three and asks the most of the user, because nothing on screen says drag me until they try.

Autoplay deserves more thought than it usually gets. If it moves without being asked, it has to pause on hover, pause on focus, and stop permanently once the user interacts, otherwise it will yank a slide away mid read. It also has to respect reduced motion, which for a carousel means not advancing on its own at all. An infinite marquee is the one case where continuous motion is fine, because it is decorative and nobody is trying to read a specific logo.

The accessibility work is the part worth not rebuilding. A carousel needs arrow key stepping, a live region announcing the current slide, focus that never lands on an off screen item, and controls that are real buttons rather than styled divs. Every carousel here handles those, and the off screen focus problem in particular is the one that most hand rolled versions miss, because it only shows up when you tab through the page rather than clicking.

Frequently asked questions

Run npx wensity@latest add carousel to copy the base carousel into your codebase, or use the slug of any other carousel on this page. The CLI installs what the component needs and matches your Tailwind theme. Every one of them is a single file you own afterwards, so changing the snap behaviour or the arrow styling is a normal code edit.
Not by themselves. The risk is that content inside a carousel is often loaded lazily or hidden in a way crawlers do not follow, so it never gets indexed. The carousels here keep every slide in the server rendered HTML and move them with CSS transforms rather than mounting and unmounting, which means the text is in the document whether or not the slide is currently visible.
Both, on every one. Pointer events cover mouse and touch through the same code path, so there is no separate mobile mode. Arrow keys step between slides, Tab never lands on an off screen item, and the current position is announced through a live region. Those last two are the ones custom carousels usually miss.
Only if it is decorative. An autoplaying carousel has to pause on hover, pause on keyboard focus, and stop for good once someone interacts, or it will move a slide away while it is being read. It should also not advance at all when the user has asked for reduced motion. A logo marquee is a reasonable exception because nobody is trying to read a specific item in it.
A carousel has discrete slides the user steps through and a current position that matters. A marquee scrolls continuously, has no concept of a current item, and usually loops forever. Use a carousel when someone might want to go back to slide two, and a marquee when the content is a texture rather than a list.

Where to go next