Embla Carousel React
A lightweight, dependency-free React hook for building fluid, touch-precise carousels and sliders.
Repository Health
Technical Analysis
Embla Carousel React is the official React binding for Embla Carousel, a framework-agnostic carousel engine built for smooth motion and precise swipe/drag handling. It exposes a single hook, useEmblaCarousel, that wires a plain DOM ref up to Embla’s vanilla-JS engine and hands back an imperative API for navigation, snap points, and events, while leaving all markup and styling entirely to the developer.
Because the engine itself has zero dependencies and does the heavy lifting outside React’s render cycle, the React wrapper stays tiny and avoids re-render thrashing during drag and scroll. It supports SSR out of the box, ships full TypeScript types, and is extensible through the same plugin system used by every other Embla framework binding (autoplay, auto-scroll, class names, fade, wheel gestures, and more).
What You Get
- A single useEmblaCarousel hook returning a root ref, a client-side carousel API, and an SSR-safe server API for the first render
- Automatic re-initialization when options or plugins change between renders, diffed via areOptionsEqual/arePluginsEqual to avoid unnecessary engine restarts
- Full TypeScript types for options, plugins, and the returned EmblaCarouselType API
- Compatibility with every official Embla plugin (Autoplay, AutoScroll, AutoHeight, ClassNames, Fade, WheelGestures, Accessibility) via the same plugins array
- Zero imposed markup or styling — you build the slide DOM and CSS yourself, matching the library’s ‘unopinionated engine’ philosophy
- SSR/SSG support through a dedicated server-rendered fallback API so carousels don’t flash unstyled content in frameworks like Next.js or Astro
Common Use Cases
- Image and product galleries or hero sliders on marketing and e-commerce pages
- Testimonial, logo, or card carousels that need touch/swipe precision on mobile
- Multi-slide ‘peek’ layouts (e.g. showing 1.2 or 2.5 slides) using scroll-snap-driven alignment options
- Tabbed or stepper-like interfaces built on top of Embla’s goTo/scrollTo navigation API
- Carousels composed with shadcn/ui’s Carousel component, which is itself built directly on embla-carousel-react
Under The Hood
Architecture The hook (useEmblaCarousel, 81 lines) wraps the EmblaCarousel() factory from the sibling embla-carousel core package (a 298-line EmblaCarousel.ts orchestrating ~39 internal modules: Engine, DragHandler, ScrollBody, Translate, ResizeHandler, SlidesInView, etc.) using useRef/useState/useEffect. On first render it synchronously builds an SSR-safe ‘server’ API via EmblaCarousel(null, options, plugins); once the returned ref callback attaches to a real DOM node, a useEffect creates the live client engine and destroys it on cleanup. Options and plugins are held in refs and diffed each render with areOptionsEqual/arePluginsEqual (from embla-carousel-reactive-utils) so reInit() only fires when they actually change — all drag/scroll/animation work happens outside React’s render cycle, so it never triggers React re-renders.
Tech Stack TypeScript throughout (roughly 73% of the monorepo’s bytes), managed as a Yarn workspaces monorepo with 19 packages — one binding per framework (React, Vue, Svelte, Solid) plus official plugins (Autoplay, AutoScroll, AutoHeight, ClassNames, Fade, SSR, Accessibility) and a shared reactive-utils package. Builds run through Rollup, emitting UMD, CJS, and ESM bundles with generated .d.ts files. The React package has no runtime dependencies beyond embla-carousel and embla-carousel-reactive-utils, and declares react only as a peerDependency (^16.8 through 19.x). A separate Next.js docs site is checked into the same repo.
Code Quality The React wrapper ships no dedicated test suite of its own (its package.json test script is a no-op placeholder), but the core embla-carousel package carries 37 test files exercising engine internals (Engine, ScrollBody, DragHandler, Alignment, and more), and embla-carousel-reactive-utils has its own tests for the equality checks the hook relies on directly. ESLint and Prettier are enforced repo-wide through a shared workspace script, and the hook’s own source stays small (81 lines) with narrowly scoped, well-named type exports (UseEmblaCarouselType, EmblaRootNodeRefType).
API Design The public surface is deliberately minimal: one default export, useEmblaCarousel(options?, plugins?), returning a 3-tuple [ref, api | undefined, serverApi]. That client API being undefined until mount is the main ergonomic wrinkle — consumers must guard for it on first render, which is the most common source of friction in issues and examples. Otherwise the returned EmblaCarouselType mirrors the vanilla engine’s method names one-to-one (scrollNext, scrollPrev, scrollTo, selectedScrollSnap, on/off), so existing Embla knowledge transfers directly, and the extensive docs site (api/guides/examples/plugins sections) keeps the overall learning curve low.
Used by 63 apps in this directory
Payload CMS
Blogging · CMS · Developer Tools
The open-source, Next.js-native headless CMS that lives inside your /app folder and gives you a full TypeScript backend instantly.
rowboat
AI Assistants · AI Development
Build, test, and deploy multi-agent AI workflows with a visual editor, RAG data sources, MCP tool integration, and a production-ready REST API.
Rybbit
Analytics
Open-source, privacy-friendly web and product analytics with cookieless tracking, session replays, funnels, and real-time dashboards — a self-hostable alternative to Google Analytics.
sigle
Blogging
A decentralized, open-source writing platform that permanently stores your stories on the Stacks blockchain and Arweave — where Web3 content creators own their words forever.
Sink
Analytics · Bookmarks Archiving
Serverless link shortener with real-time analytics, powered by Cloudflare
Skyvern
AI Agents · Automation
Skyvern (YC S2023) automates browser-based workflows by pairing LLMs with computer vision, letting agents click, fill, and extract data on sites they've never seen, without brittle XPath selectors that break on every layout change.
Sourcebot
AI Code Assistants · Developer Tools · Search
A self-hosted, AI-powered code search engine that indexes every repo across GitHub, GitLab, Bitbucket, Gitea, Gerrit, and Azure DevOps, so both engineers and coding agents can search, browse, and ask questions about your codebase from one place.
Sourcebot
AI Code Assistants · Developer Tools · Search
A self-hosted, AI-powered code search engine that indexes every repo across GitHub, GitLab, Bitbucket, Gitea, Gerrit, and Azure DevOps, so both engineers and coding agents can search, browse, and ask questions about your codebase from one place.
Hexclave
Authentication · Developer Tools
The open-source user infrastructure platform — authentication, teams, payments, emails, analytics, and more on a single unified user model.