lodash vs radash 徹底比較

lodash の詳細radash の詳細
AI生成コンテンツ

この記事はAIによって生成されました。内容の正確性は保証されません。最新の情報は公式ドキュメントをご確認ください。

lodash vs radash — ユーティリティライブラリ徹底比較

1. 結論

新規プロジェクトでモダンなTypeScript環境を使うなら radash を第一候補にしてください。 既存の大規模プロジェクトで長年の実績・網羅的なAPI・豊富な情報を重視するなら lodash(特に lodash-es)が依然として堅実な選択です。どちらも「配列・オブジェクト・関数のユーティリティ集」という同じ領域を担いますが、設計思想と時代背景が大きく異なります。


2. 比較表

観点lodashradash
初回リリース2012年2022年
最新バージョン(2025年時点)4.17.2112.x
npm 週間DL数約5,000万〜約50万〜
バンドルサイズ(フル)約 71 kB (min+gzip)約 4 kB (min+gzip)
Tree Shakinglodash-es で対応ネイティブ対応(ESM)
TypeScript対応@types/lodash が必要ソースがTypeScriptで書かれている
関数の数300+90+
設計思想網羅的・汎用的厳選・モダン・型安全
ミュータブル操作一部あり(_.set 等)原則イミュータブル
非同期ユーティリティほぼなしtryit, parallel, retry 等あり
学習コスト低(情報が豊富)低(APIが少なく直感的)
ライセンスMITMIT

3. それぞれの強み

lodash の強み

  • 圧倒的な実績と安定性: 10年以上の歴史があり、Fortune 500企業を含む無数のプロダクションで稼働しています。
  • 網羅的なAPI: 300以上の関数があり、「こんなユーティリティないかな?」と思ったらほぼ見つかります。
  • 情報量の多さ: Stack Overflow、ブログ記事、書籍など、日本語を含む情報が圧倒的に豊富です。
  • エコシステム連携: Webpack の lodash-webpack-plugin や Babel の babel-plugin-lodash など、最適化ツールが充実しています。
  • _.chain によるメソッドチェーン: 複雑なデータ変換をパイプライン的に記述できます。

radash の強み

  • TypeScriptファースト: ソースコード自体がTypeScriptで書かれており、型推論が非常に正確です。@types/* のバージョン不一致に悩むことがありません。
  • 極めて小さいバンドルサイズ: ESMネイティブ設計のため、Tree Shakingが完璧に効きます。使った関数だけがバンドルに含まれます。
  • イミュータブル設計: すべての関数が元のデータを変更しません。React / Vue などの状態管理と相性が良いです。
  • 非同期ユーティリティの充実: retryparalleltryit など、モダンなasync/awaitベースの関数が組み込まれています。
  • ゼロ依存: 外部依存パッケージが一切ありません。

4. コード例で比較

4-1. 配列のグルーピング

// === lodash ===
import groupBy from "lodash/groupBy";

interface User {
  name: string;
  role: "admin" | "member";
}

const users: User[] = [
  { name: "Alice", role: "admin" },
  { name: "Bob", role: "member" },
  { name: "Carol", role: "admin" },
];

const grouped = groupBy(users, "role");
// => { admin: [Alice, Carol], member: [Bob] }
// ⚠ 戻り値の型は Dictionary<User[]> — キーの型が string に広がる
// === radash ===
import { group } from "radash";

interface User {
  name: string;
  role: "admin" | "member";
}

const users: User[] = [
  { name: "Alice", role: "admin" },
  { name: "Bob", role: "member" },
  { name: "Carol", role: "admin" },
];

const grouped = group(users, (u) => u.role);
// => { admin: [Alice, Carol], member: [Bob] }
// ✅ 戻り値の型は Partial<Record<"admin" | "member", User[]>> — 型が正確

4-2. オブジェクトの特定キー抽出(pick)

// === lodash ===
import pick from "lodash/pick";

const config = { host: "localhost", port: 3000, debug: true };
const result = pick(config, ["host", "port"]);
// => { host: "localhost", port: 3000 }
// ⚠ 型は Partial<typeof config> 相当で、存在しないキーを渡してもエラーにならない
// === radash ===
import { pick } from "radash";

const config = { host: "localhost", port: 3000, debug: true };
const result = pick(config, ["host", "port"]);
// => { host: "localhost", port: 3000 }
// ✅ 存在しないキーを渡すとコンパイルエラーになる

4-3. 非同期リトライ処理

// === lodash ===
// lodash には該当する関数がないため、自前で実装する必要がある
async function fetchWithRetry(
  fn: () => Promise<string>,
  retries: number
): Promise<string> {
  for (let i = 0; i < retries; i++) {
    try {
      return await fn();
    } catch (e) {
      if (i === retries - 1) throw e;
    }
  }
  throw new Error("Unreachable");
}

const data = await fetchWithRetry(() => fetch("/api").then((r) => r.text()), 3);
// === radash ===
import { retry } from "radash";

const data = await retry({ times: 3, delay: 1000 }, async () => {
  const res = await fetch("/api");
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.text();
});
// ✅ リトライ回数・遅延・バックオフを宣言的に指定できる

4-4. 安全なエラーハンドリング

// === lodash ===
// lodash には該当する関数がない
let result: string;
try {
  result = JSON.parse(untrustedInput);
} catch (e) {
  result = "default";
}
// === radash ===
import { tryit } from "radash";

const [err, result] = await tryit(async () => {
  return JSON.parse(untrustedInput) as string;
})();

if (err) {
  console.error("パース失敗:", err);
}
// ✅ Go言語風のエラーハンドリングで try-catch のネストを避けられる

5. どちらを選ぶべきか — ユースケース別の推奨

radash を選ぶべきケース

ユースケース理由
新規のTypeScriptプロジェクト型安全性が段違いで、設定不要で恩恵を受けられる
フロントエンド(React / Vue / Svelte)バンドルサイズが小さく、イミュータブル設計が状態管理と好相性
非同期処理が多いバックエンドretry, parallel, tryit などが標準装備
バンドルサイズを極限まで削りたいESMネイティブで完璧なTree Shaking

lodash を選ぶべきケース

ユースケース理由
既存の大規模プロジェクトの保守移行コストに見合わない場合が多い
JavaScriptプロジェクト(型なし)radash の最大の利点(型安全性)が活きにくい
ニッチなユーティリティが必要_.cloneDeep, _.merge, _.template など radash にない関数が必要な場合
チームの学習コストを最小化したい日本語情報が豊富で、知っているメンバーが多い
_.chain スタイルのパイプラインを多用radash にはチェーンAPIがない

どちらでもよいケース

  • 小規模なスクリプトやCLIツールで、使う関数が数個程度の場合はどちらを選んでも差は出ません。
  • そもそもユーティリティライブラリが不要な場合もあります。 ES2024+ の Object.groupByArray.prototype.toSorted などネイティブAPIの充実により、ライブラリなしで済むケースが増えています。

6. まとめ

lodash  = 歴史と網羅性の「百科事典」
radash  = 型安全とモダン設計の「厳選ツールキット」

lodash は10年以上にわたりJavaScriptエコシステムを支えてきた偉大なライブラリです。しかし、TypeScriptの普及・ESMの標準化・バンドルサイズへの意識の高まりという時代の変化の中で、radash はそれらの課題を最初から解決する設計で登場しました。

迷ったら、まず radash を試してみてください。 足りない関数があれば lodash から個別インポートで補完する、というハイブリッド戦略も現実的です。どちらも MIT ライセンスの優れたOSSであり、プロジェクトの要件に合わせて柔軟に選択することが最善のアプローチです。