Embla vs Swiper: pick by what you’re building
Both are excellent, actively maintained carousel engines, and the choice between them is genuinely close. It comes down to one axis: Swiper ships every feature built in; Embla ships a small headless engine you build on. This page is written by the maintainer of a library that competes with neither — which is also the third answer at the bottom, for the builds that turn out not to be carousels at all.
| Embla | Swiper | |
|---|---|---|
| What it is | Headless carousel engine | Full slider/carousel framework |
| Bundle (core, min+gzip) | ≈8 kB | ≈40 kB (grows with modules) |
| Styling & markup | Yours entirely — it ships none | Its own DOM structure and CSS, themed |
| Effects (fade, cube, coverflow…) | Community plugins, or DIY | Built in, mature |
| Autoplay, pagination, thumbs | Official plugins | Built-in modules |
| React integration | First-class hook (useEmblaCarousel) | Wrapper components over a vanilla core |
| Ecosystem note | The engine under the shadcn/ui carousel | The most-used slider on the web |
| Best for | Custom-designed carousels, design systems | Image-first sliders, feature-heavy galleries |
Bundle sizes are approximate cores — check bundlephobia for current numbers; Swiper’s grows with the modules you import.
Choose Embla when design control is the point
Embla gives you snap physics, drag handling and a slide model, and nothing else — no markup, no CSS, no arrows. That is its strength: in a design system, everything visible is yours, and the engine never fights your styles. It is what shadcn/ui builds its carousel on, which tells you the sweet spot: teams that want a carousel to look like their product, not like a carousel library.
The cost is that every feature beyond sliding is an add-on or hand-built: autoplay and class-names are official plugins; pagination dots, thumbnails and effects are yours to write.
Choose Swiper when you want the features shipped
Swiper is the batteries-included answer: fade, cube and coverflow effects, virtual slides, zoom, parallax, thumbs galleries, a11y module, pagination in several styles — configured, not built. If your product needs three of those this quarter, Swiper earns its size many times over.
The cost is the inverse of Embla's: you inherit Swiper's DOM, its CSS to theme, and a vanilla-JS core wrapped for React — heavier both in kilobytes and in surface area.
The question to ask before either
Both libraries assume you are presenting slides — one thing, or one page of things, at a time, with snapping and a sense of position. A large share of real "carousels" are nothing like that: category rows, logo strips, tab bars, chip filters — rows of clickable items your user scans and picks from. Those want native scrolling (momentum, scrollbar, wheel, accessibility for free) plus knowing which items are on screen — and neither Embla nor Swiper models per-item visibility, because slides aren't items.
For that shape there is a third option: react-horizontal-scrolling-menu (≈5.7 kB) rides native scroll and ships useIsVisible, scrollToItem and edge-aware arrows. See it as a Netflix-style row, a tab strip or a chip bar, or the full comparison table against both.