Swipi
Swipi is a headless carousel for React. One hook gives you the engine — drag, momentum, snapping, looping, autoplay — and hands back a ref and a small object of state. The markup, the CSS and the accessibility stay yours, so nothing of ours ends up in your DOM and there is no stylesheet to import.
It weighs 5.1 KB gzipped — 1.85× less than
embla-carousel-react with its autoplay plugin, measured through the
same build in
SIZE.md.
Upgrading from Swipi 2? The
<Swipi>component and its ~30 props are gone in 3.0 — MIGRATION.md maps every one of them to a hook option or a line of CSS.
Installation
npm
$ npm install swipi
yarn
$ yarn add swipi
View more examples and create a custom slider
Basic Usage
Wiring is a single ref on the viewport. The track is its only child and the slides are the children of the track.
The markup
import { useSwipiCarousel } from 'swipi'
export const Carousel = ({ items }) => {
const [carouselRef, carousel] = useSwipiCarousel({ loop: true })
return (
<>
<div className="overflow-hidden touch-pan-y" ref={carouselRef}>
<div className="flex -ml-3 select-none">
{items.map((item) => (
<div
className="min-w-0 shrink-0 grow-0 basis-1/2 pl-3"
key={item.id}
>
{item.title}
</div>
))}
</div>
</div>
<button
type="button"
onClick={carousel.scrollPrev}
disabled={!carousel.canScrollPrev}
>
‹
</button>
<button
type="button"
onClick={carousel.scrollNext}
disabled={!carousel.canScrollNext}
>
›
</button>
</>
)
}
The classes
Those three class lists are a contract, not decoration — the geometry depends on
them. Two of them are yours to tune: basis-1/2 sets how many slides are
visible, and the pl-3 on the slide with the matching -ml-3 on the track sets
the space between them. Everything else on the page is styling you own.
Not using Tailwind? Our documentation provides examples using both Tailwind and plain CSS.
Documentation
For advanced usage, available options, responsive layout specifics, state management, and accessibility guidelines, please refer to our full documentation at https://swipi.midstem.net/docs/.