カルーセルUIライブラリの有力な選択肢 Embla Carousel

ラクスパートナーズのWebエンジニアの安井です。
普段は主にフロントエンドの開発を行なっています。

この記事は[ラクス Advent Calendar 2022](https://qiita.com/advent-calendar/2022/rakus)の9日目です。
Qiita初投稿 & 初Advent Calenderです。よろしくお願いします。

過去に後輩エンジニアからカルーセルUIで用いるライブラリの選定について聞かれたことがあったのですが、自分のこれまで導入を検討したライブラリはネックに感じる部分もあり、なかなかすっきりとした提案ができなかったことがありました。

そんな思いを抱えていたところ「これならおすすめできる！」と感じたライブラリを見つけたのでご紹介したいと思います。

## 忙しい人のために先に結論
[Embla Carousel](https://www.embla-carousel.com/) をおすすめしたい

## カルーセルUIライブラリの選定の観点
どのライブラリを採用するかの決め手はプロジェクトによってさまざまだと思いますが、自分はこれまで主に次のような観点で検討しました。

### 機能・拡張性
「ユースケースに合ったUI/UXを実現できるか」という観点で挙げています。
設計されたデザインや操作性を再現できるかどうかという観点でとらえてます。
またアクセシビリティの要件なども考慮する必要があります。

### 利用しているフレームワークや環境にフィットするかどうか
Vue環境で使用したいのにVueをサポートしていないなどは選定から外れます。
あくまで自然に使える状態が良くて、ハックすれば特定のフレームワークでも使えるというような利用の仕方も極力避けたいです。

### ライセンス
ライセンスについては商用で利用するのか個人で利用するかによっても制約が変わってくると思います。
有償ライセンスが購入可能かどうかによっても選択肢は変わります。
今回は商用利用無料なものを利用したい前提で検討したいと思います。

### バンドルサイズ・他のライブラリへの依存
バンドルサイズはアプリケーションのパフォーマンスに関わるので極力小さくしたいところです。
他のライブラリへの依存も同様の観点です。

### ライブラリ自体が継続的にメンテナンスされそうか
こちらも重要な観点です。
仮にメンテナンスが継続されなくなった場合、機能が改善されなかったりバグがあっても解消されずユースケースの実現が困難になる可能性があります。
TypeScriptやReactのバージョンアップのネックになったりすることもあると思います。

この判断基準は難しいですが、私は利用実績という観点でGitHubのStar数やnpmのダウンロード数、GitHub上のPRやIssuesのレスポンスなどを見ています。
PRやIssuesに対してレスポンスがある状態であれば自分からリクエストやフィードバックを送って改善を行うこともできそうです。
あと開発をしている人や組織がどんな集団なのか、コントリビュートしている人やその人数なども判断する材料になりそうです。
先のことはわからないですが極力リスクの少ない選択肢をとれるかどうかを検討したいところです。

## これまで利用してきたライブラリの所感
次に上記のような基準の中でこれまで利用してきたカルーセルUIライブラリの中で代表的なものに関して感想を述べます。

### Slick
公式ドキュメント
https://kenwheeler.github.io/slick/
GitHub
https://github.com/kenwheeler/slick
npm
https://www.npmjs.com/package/slick-carousel

メジャーなライブラリです。(執筆時点でGitHub Star 27.8k)
ネックな点としてはjQueryに依存している点でした。
バンドルサイズについては下記参照。
https://bundlephobia.com/package/slick-carousel@1.8.1

### Swiper

<img src="https://camo.githubusercontent.com/c502684f2cf3a66a1c01060bbe8feb456d85f85cae70619afb402b398fde589d/68747470733a2f2f7377697065726a732e636f6d2f696d616765732f73686172652d62616e6e65722d332e706e67" alt="" width="298" height="170" />

公式ドキュメント
https://swiperjs.com/
GitHub
https://github.com/nolimits4web/swiper
npm
https://www.npmjs.com/package/swiper

こちらもメジャーなライブラリです。(執筆時点でGitHub Star 33.5k)
ネックに感じる点としては独自のCSSを読み込む必要があります。
あとバンドルサイズも大きめです。
https://bundlephobia.com/package/swiper@8.4.5

比較については下記の記事が丁寧に解説されていると感じました。
本記事では個人的な所感に留めさせていただきます。

参考
https://ics.media/entry/210902/

上記はどちらもMITライセンスなので商用利用無料という観点で有力な選択肢になると思います。
また利用実績が多いという点でも高評価です。ドキュメントがしっかり用意されているのも嬉しいところです。
いずれも導入事例が多いため導入やトラブルシューティングの際の情報が豊富なので、ベターな選択肢になるかなと思いますがやはりネックとして挙げた点が気になるところでした。

そこで今回の記事でご紹介したいのが[Embla Carousel](https://www.embla-carousel.com/)です。

## Embla Carousel

<img src="https://www.embla-carousel.com/static/embla-logo-dark-theme-blur-dd6671f5992e7089fd82e1f04db7370e.svg" alt="" width="200" height="200" />

公式ドキュメント
https://www.embla-carousel.com/
GitHub
https://github.com/davidjerleke/embla-carousel
npm
https://www.npmjs.com/package/embla-carousel

> A lightweight carousel library with fluid motion and great swipe precision

翻訳すると「滑らかな動きと優れたスワイプ精度を備えた軽量カルーセルライブラリ」とのことです。
また高度な拡張性、プラグインシステム、完全な型サポートが強調されています。

ロゴがいかにもReactファーストっぽい感じがしますが、pureなJavaScriptでも利用できる他React, Vue, Svelteなど主要なモダンフレームワークでも利用可能となっています。
デフォルトではIE11をサポートしていませんがpolyfillを導入することでIE11でも利用可能とドキュメントで案内されています。

GitHub Star数は執筆時点で2.8kとなっており、前述のSlickやSwiperと比較すると多いとは言えないですが個人的には採用するのが不安にならないStar数だと感じました。

また執筆時点でのバージョンはv7.0.5となっており、かなり積極的にバージョンアップがされているように感じました。
GitHubのreleasesを確認しても月1回程度バージョンアップがされているので継続的にメンテナンスされているようです。

> It's library agnostic, dependency free and 100% open source.

依存関係がないことも謳われており、バンドルサイズも5.9KBとかなり軽量です。
https://bundlephobia.com/package/embla-carousel@7.0.5

使い方に関しても最小限で使う場合だと下記のように参照用のclass名をつけてスライドのスタイルをつけてhookを1つ呼び出すだけで実装可能です。
下記公式のexampleの引用です。

```tsx
import React from 'react'
import useEmblaCarousel from 'embla-carousel-react'

export const EmblaCarousel = () => {
  const [emblaRef] = useEmblaCarousel()

  return (
    <div className="embla" ref={emblaRef}>
      <div className="embla__container">
        <div className="embla__slide">Slide 1</div>
        <div className="embla__slide">Slide 2</div>
        <div className="embla__slide">Slide 3</div>
      </div>
    </div>
  )
}
```

```css
.embla {
  overflow: hidden;
}
.embla__container {
  display: flex;
}
.embla__slide {
  flex: 0 0 100%;
}
```

exampleには他のカルーセルライブラリで実現できるような主要なユースケースについてのサンプルがあります。
https://www.embla-carousel.com/examples/

ベースがかなりシンプルなのでこだわったUIにしたい場合やアクセシビリティの要件への対応も柔軟に行えそうだと感じました。

さらにMITライセンスなので商用プロダクトへの導入も検討しやすく嬉しいことづくしです。

## おわりに
いかがだったでしょうか。
私はこれまでカルーセルUIライブラリの選定時に目にしたことがなかったのですが、見つけた瞬間「これだ！」と思いました。

私は最近Reactを使う際にTailwindCSSを使用することが多いので、TailwindCSSとの相性なども今後試していきたいと思っています。

要件や環境によっては他のライブラリの方がフィットする場合もあると思いますが、カルーセルUIライブラリの選定の選択肢として検討してみてはいかがでしょうか。