Duolingoが公開している利用OSライブラリを分析してみた
先日Xでこのようなポストをしたところ、ありがたいことに思いのほか多くの反響がありました。
せっかくなので、この記事では英語学習アプリDuolingo(デュオリンゴ)が公開しているオープンソースライブラリを確認して、領域毎にどのようなライブラリを活用しているのかを分析してみようと思います。
参照しているDuolingoの公開記事
1. 全体を俯瞰した時の採用ライブラリの傾向
Duolingoの各クライアントで利用しているOSSを俯瞰したところ、以下のような傾向が見えてきました。
- WebクライアントはReact + TypeScriptエコシステムが中心。状態管理にはReduxに加えて Jotaiなどモダンなライブラリも併用している。
- iOS/Androidではフレームワーク標準やGoogle/Firebase系のSDKが多数採用されている。
- UI・アニメーション表現のためにRiveやLottieといったマルチプラットフォーム対応のライブラリが揃っている。
- 計測やトラッキングのSDK(Firebase、FullStory、Sentry など)が豊富で、ユーザー行動分析にかなり注力していることが伺える。
- ネットワーク通信、データ永続化、メディア再生など、各領域で複数のOSSを使い分けている。
2. Webで利用されているOSS
2-1. React 本体と UI 周辺
-
react-router / react-router-dom
SPAルーティング -
react-helmet / react-helmet-async
<head>要素のメタ情報管理 -
react-meta-tags
メタタグ管理の代替実装 -
react-modal
モーダルUI -
react-datepicker
日付選択UI -
react-hover-video-player
ホバーで再生される動画コンポーネント -
react-countdown
カウントダウンUI
2-2. UIレイアウト・スタイリング・アニメーション
-
classnames
className操作ユーティリティ -
normalize.css
CSS初期化 -
modernizr
ブラウザ機能検出 -
@popperjs/core / react-popper
ポップオーバー・ツールチップ -
@floating-ui/react-dom
高度な位置決めライブラリ -
react-transition-group
マウント/アンマウントのアニメーション -
react-spring
物理ベースアニメーション -
motion
Framer Motionのコア -
smoothscroll-polyfill
スムーズスクロールポリフィル
2-3. フォーム・入力補助
-
formik
フォーム管理 -
react-textarea-autosize
自動リサイズテキストエリア -
textarea-caret
キャレット位置取得
2-4. アニメーション・メディア・描画
-
lottie-web
Lottieアニメーション描画 -
@rive-app/react-canvas
Riveアニメーション -
howler
音声再生 -
html2canvas
DOMを画像化 -
html2pdf.js
HTML→PDF生成 -
react-inlinesvg
SVGインライン描画
2-5. スクロール・リスト・バーチャル化
-
react-infinite-scroller
無限スクロール -
react-window
大量リストの仮想化 -
react-virtual
非DOM依存の高性能バーチャルリスト
2-6. 状態管理・データフロー
-
redux / react-redux
状態管理 -
redux-thunk
非同期処理 -
redux-logger
デバッグ用ログ -
seamless-immutable
変更不可データ構造 -
redux-seamless-immutable
Redux統合 -
immer
イミュータブル更新 -
reselect
メモ化セレクタ -
jotai / jotai-devtools
モダンなAtomベース状態管理 -
eventemitter3
イベント管理
2-7. ネットワーク / データ通信
-
axios
HTTPクライアント -
unfetch
fetchポリフィル -
websocket
WebSocketサポート -
protobufjs
Protocol Buffers -
js-cookie
Cookie管理 -
js-base64
Base64 -
js-sha256
SHA256 -
browser-deeplink
ディープリンク制御
2-8. 可視化・グラフ描画
-
resumable.js
分割アップロード
2-9. 日付・テキスト処理・ユーティリティ
2-10. ビルド / 言語 / Lint周り
-
ESLint関連
-
core-js
Polyfill一式 -
json-loader
Webpack JSONローダー
2-11. テスト関連
-
TypeScript型定義集(@types/*)
2-12. アナリティクス・トラッキング
-
@fullstory/browser
セッションリプレイ -
heap
行動分析 -
@rollbar/react
エラートラッキング -
Sentry
エラートラッキング
2-13. 決済・認証・セキュリティ
3. iOSで利用されているOSS
iOS クライアントは Swift/Objective-Cの標準エコシステムを中心に、UIレイアウト・アニメーション・認証・クラッシュレポートまで広範囲のOSSを採用しているようです。
3-1. UI / レイアウト / グラフィックス
-
SnapKit
Auto Layout の DSL ライブラリ -
SVGKit
SVG 画像のレンダリング -
shapeview-ios
シェイプ描画 -
textlayerlabel-ios
テキスト描画最適化 -
SwiftMath
高度な数学処理 -
SwiftCollections
データ構造(Deque, OrderedSet など) -
swift-algorithms
アルゴリズム集 -
swift-numerics
浮動小数計算支援 -
swift-log
ロギング API -
swift-tagged
型安全なタグ付き値 -
swift-concurrency-extras
Swift Concurrency の補完実装 -
swift-snapshot-testing
UI スナップショットテスト -
SnapshotPreviews
UI プレビュー
3-2. 認証 / セキュリティ / ネットワーク
-
AppAuth-iOS
OAuth2 / OIDC 認証 -
GTMAppAuth
Google 向け AppAuth ラッパ -
GTMSessionFetcher
ネットワーク通信ユーティリティ -
GoogleSignIn-iOS
Google ログイン - keychain-ios
iOS キーチェーンラッパ(リンク非公開) -
Promises
Promise ベースの非同期処理
3-3. ログ / デバッグ / クラッシュレポート
-
CocoaLumberjack
高度なログ管理 -
NSLogger
ネットワークログビューア -
CleanroomLogger
ロギングフレームワーク -
SimpleDebugger
軽量デバッガ(OSS 出典不明) -
PLCrashReporter
ネイティブクラッシュレポート -
HockeySDK-iOS
旧 App Center のクラッシュ SDK -
appcenter-sdk-apple
App Center 統合 SDK
3-4. アニメーション / メディア
-
lottie-ios
Lottie アニメーション -
RiveRuntime
Rive アニメーション再生 -
DGCharts
iOS のチャート描画 -
PhoneNumberKit
電話番号解析(libphonenumber の Swift 版) -
ZIPFoundation
ZIP圧縮/解凍 -
FlyingFox
ローカル HTTP サーバー
3-5. データ処理 / 低レベルツール
-
SwiftProtobuf
Protocol Buffers -
HanziVG / KanjiVG
漢字のベクターデータ
4. Androidで利用されているOSS
Androidクライアントは Kotlin/AndroidX/Google Play Services/Firebase の標準的な構成に加え、RxJava, Retrofit, Rive/Lottieなどで機能を拡張しているようです。
4-1. UI / レイアウト / AndroidX
- Android AppCompat
- androidx.core:core
- ConstraintLayout
- RecyclerView
- CardView
- GridLayout
- ViewPager2
- Material Components
- FlowLayouts
4-2. ライフサイクル / ロジック / アーキテクチャ
-
AndroidX Lifecycle
ViewModel / SavedState / ProcessLifecycle / ServiceLifecycle -
DataStore
設定データ保持 - Preferences KTX
- WorkManager
- Room
- Hilt / Auto Dagger Core
-
orbit-mvi
MVI アーキテクチャ -
CombineExt
Kotlin Combine 拡張
4-3. ネットワーク / 通信
- Retrofit
- Retrofit Kotlin Serialization Converter
- OkHttp
- okhttp-logging-interceptor / okhttp-urlconnection
- Volley
- libphonenumber
4-4. RxJava / 非同期処理
- RxJava
- RxAndroid
- RxKotlin
- Adapter: RxJava 3
- RxJava Replaying Share
- Room RXJava3
- Android WorkManager RxJava3 support
4-5. アニメーション・グラフィックス・メディア
- Lottie
- rlottie
- com.duolingo.rlottie:axrlottie
- Rive Android
- MPAndroidChart
4-6. Firebase / Google / 広告・計測
- firebase-bom
- firebase-analytics
- firebase-crashlytics
- firebase-messaging
- GoogleAppMeasurement
- GoogleDataTransport / GoogleUtilities
- InteropForGoogle
- Google Sign-In
- Google Mobile Ads/play-services-ads
- Google Play Auth/play-services-auth
- Adjust Android SDK
- Facebook Android SDK
- com.facebook.battery:metrics-jetified
- com.tencent.mm.opensdk:wechat-sdk-android-without-mta
4-7. デバッグ / 安定性向上
- LeakCanary
-
Use Plumber Android
リーク抑止 - ANR-Watchdog
-
com.jraska:falcon
デバッグスクリーンショット -
Reaper
デッドコード検証ツール -
Network Connection Class
アーカイブ済
4-8. データ / 低レベルツール
- nanopb
- leveldb
- PCollections
- localization-lib
不明 - GZIP
まとめ
こうして一覧してみると、Duolingoが「必要だから入れている」ものと「歴史的に積み上がって残っている」もの、「ユーザー体験を磨くために攻めている」ものが入り混じっているのが見えているように思えます。特に Web は React/TSの巨大エコシステムの中から相当こまかく選択していて、iOS・Androidは各プラットフォームが持つ文化に寄り添いつつも RiveやLottieのような共通表現を積極的に採り入れている。このあたり、プロダクトとしての一貫性とチーム構成のリアルさがそのまま技術選定に滲んでいる気がします。
もちろん、OSSの羅列だけでは「なぜその選択肢だったのか」までは分かりませんが、クライアント間での表現統一や計測基盤の作り込みを見ると、Duolingoがユーザー体験と改善サイクルにどれだけ投資しているかがけっこうはっきり浮かび上がってきますね。普段目にする独特なUIの軽やかさに対して、裏ではかなり雑多な技術スタックが動いているというギャップも興味深いところです。
今回の自分用メモ的な分析がどこかしら参考になればうれしいですし、また面白いプロダクトのスタックを見つけたら同じように掘ってみようと思います。綺麗にまとまってないですが、このくらいで。
Discussion