Remeda
专为 TypeScript 打造的「data-first」与「data-last」双模式工具函数库,提供一流的类型支持与惰性求值能力。
Remeda 是完全使用 TypeScript 编写的现代工具函数库,首创同时支持 data-first(命令式)与 data-last(函数式)两种调用风格。在 pipe 中自动启用惰性求值,类型精确到元组级别。GitHub 5,400+ Stars,周下载量约 50 万次,被列为 2026 年 npm 增长最快的包之一,是 TypeScript 项目替代 Lodash 的主流选择。
Remeda
专为 TypeScript 打造的「data-first」与「data-last」双模式工具函数库,提供一流的类型支持与惰性求值能力。
技术简介说明
Remeda 是一款从底层就完全使用 TypeScript 编写的现代工具函数库,区别于 Lodash、Ramda 等「先有 JS 再补类型」的方案。它首创了同时支持 data-first(命令式)与 data-last(函数式)两种调用风格的设计,让开发者可以在同一套 API 中自由切换编程范式,而无需引入额外的库或进行复杂的类型配置。
Remeda 的核心价值在于「类型即文档」。每一个函数都拥有精确到极致的 TypeScript 类型推导,不仅能在编译阶段捕获错误,还能在 IDE 中提供比原生类型更精准的类型提示。例如,对固定长度数组执行 map 操作后,返回类型依然是精确的元组类型 [string, string, string],而非宽泛的 string[]。
在生态定位上,Remeda 填补了 Lodash(功能丰富但类型滞后)和 Ramda(函数式纯粹但学习曲线陡峭)之间的空白。截至 2026 年,它已拥有超过 5,400 个 GitHub Star,周下载量约 50 万次,被列为 2026 年 npm 增长最快的包之一,成为 TypeScript 项目中替代 Lodash 的主流选择。
基本信息
- 官网:https://remedajs.com
- GitHub:https://github.com/remeda/remeda
- License:MIT
- 最新版本:v2.39.0(2026 年 6 月发布)
- 主要维护者/公司:Remeda 社区(原始作者 Lukas Zuch)
- GitHub Stars:5.4k+
- npm 周下载量:约 500K
- 语言构成:TypeScript 97.7%、Astro 1.5%
- 发布历史:242+ releases,825+ commits
快速上手
安装
# npm
npm install remeda
# pnpm
pnpm add remeda
# yarn
yarn add remeda
# bun
bun install remeda
# Deno (JSR)
deno add jsr:@remeda/remeda基础配置
Remeda 无需额外配置,安装后即可直接导入使用。它同时支持 CJS 和 ESM 模块格式,具备完整的 Tree-shaking 支持。
tsconfig.json 推荐配置:
{
"compilerOptions": {
"strict": true
}
}Remeda 的类型系统充分利用了 TypeScript 的高级特性(条件类型、模板字面量类型等),建议在 strict: true 模式下使用以获得最佳类型推导效果。
最小示例
Data-First 风格(命令式):
import * as R from 'remeda'
const users = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 17 },
{ name: 'Charlie', age: 30 },
]
// 直接调用,数据在前
const adults = R.filter(users, (user) => user.age >= 18)
// => [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 30 }]Data-Last 风格(函数式):
import * as R from 'remeda'
// 数据在后,可复用
const getAdults = R.filter((user: { age: number }) => user.age >= 18)
const adults = getAdults(users)Pipe 组合风格:
import { pipe, map, filter, take, unique } from 'remeda'
const numbers = [1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const result = pipe(
numbers,
map((n) => n * 2), // [2, 4, 4, 6, 8, 10, 12, 14, 16, 18, 20]
filter((n) => n > 5), // [6, 8, 10, 12, 14, 16, 18, 20]
unique(), // [6, 8, 10, 12, 14, 16, 18, 20]
take(3), // [6, 8, 10]
)
// result 类型被精确推导为 number[]核心概念与架构
Data-First 与 Data-Last 双模式
Remeda 的每个函数都同时支持两种调用方式,通过 TypeScript 函数重载自动切换:
- Data-First:
R.filter(array, fn)— 数据参数在前,适合命令式编程 - Data-Last:
R.filter(fn)(array)— 函数参数在前,数据最后传入,适合函数式组合
这种设计让开发者无需像 Lodash 那样使用 _.chain() 或 _.flow() 来切换风格,也不用像 Ramda 那样强制使用 data-last。
Pipe 与惰性求值
pipe() 函数是 Remeda 的核心枢纽。当函数以 data-last 形式传入 pipe() 时,Remeda 会自动启用惰性求值(Lazy Evaluation):
import { pipe, map, filter, take } from 'remeda'
// 惰性求值:只遍历数组一次,遇到足够的元素后提前终止
const result = pipe(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 1000],
map((n) => n * 2),
filter((n) => n % 3 === 0),
take(2), // 找到 2 个结果后停止遍历,不会处理后面的 1000
)
// => [6, 12]相比 Lodash 的 _.chain() 惰性求值,Remeda 的惰性求值是自动的、类型安全的,无需手动管理。
Tree-Shakable 架构
Remeda 使用原生 ESM 导出,支持现代打包工具的 Tree-shaking。你可以导入整个库或按需导入单个函数:
// 整库导入(未使用的函数会被打包工具移除)
import * as R from 'remeda'
// 按需导入
import { pipe, map, filter } from 'remeda'核心特性
- 一流的 TypeScript 支持:完全使用 TypeScript 编写,类型精确到元组级别,编译阶段即可捕获类型错误
- Data-First / Data-Last 双模式:每个函数同时支持命令式和函数式调用,无需额外导入
- 惰性求值:在
pipe()中自动启用,避免不必要的遍历,处理大数据集时性能显著 - Tree-Shakable:原生 ESM 导出,支持 CJS 和 ESM 双格式,按需打包
- 零依赖:无任何外部运行时依赖
- JSDoc 完整文档:所有函数均有 JSDoc 注释,IDE 内联提示完整
- 运行时与类型双重测试:不仅测试运行时行为,还通过
tsd测试类型推导正确性 - 约 200 个工具函数:覆盖数组、对象、字符串、数字、异步等常见操作场景
- Lodash 迁移指南:官方提供从 Lodash 迁移的详细对照文档
生态图
关键依赖
- 零运行时依赖:生产环境无需安装任何额外包
- 开发依赖:TypeScript、Vitest(测试)、Biome(代码格式化)、Husky(Git hooks)
相关生态
| 相关项目 | 说明 |
|---|---|
| es-toolkit | 另一个 TypeScript 优先的轻量工具库,与 Remeda 定位类似但更追求极致体积 |
| Radash | 现代 TypeScript 工具库,侧重异步能力 |
| ts-belt | TypeScript 函数式编程库,提供 Option/Result 类型 |
| Lodash | 传统 JavaScript 工具库巨头,Remeda 的主要替代对象 |
| Ramda | 函数式编程工具库,Remeda 借鉴了其 data-last 模式 |
构建工具集成
Remeda 原生 ESM 输出与主流打包工具兼容良好:
- Vite / Rollup:开箱即用,Tree-shaking 完美
- Webpack 5+:原生支持 ESM Tree-shaking
- Turbopack / esbuild:完整兼容
- Deno:通过 JSR 提供原生支持
社区生态
- 掘金社区有中文教程与深度解读
- 多篇 Medium/Dev.to 技术文章推荐
- Reddit r/typescript 社区经常推荐为 Lodash 替代方案
适用场景
- TypeScript 严格模式项目:需要精确类型推导的企业级项目,编译阶段发现更多错误
- 函数式编程风格团队:data-last + pipe 模式天然支持函数式数据管道
- 大数据集处理:惰性求值在过滤、映射大数组时避免不必要的遍历
- 替代 Lodash 的新项目:新项目无历史包袱,直接使用类型更安全的 Remeda
- 全栈 TypeScript 项目:前后端统一使用一套类型安全的工具函数
- 微前端/Serverless 场景:Tree-shaking 确保只打包用到的函数,减小冷启动体积
- 需要命令式与函数式混合编程的团队:双模式设计让不同风格的开发者各取所需
开发与工程化
开发流程
Remeda 的开发流程采用现代化工程实践:
- 测试框架:Vitest,同时覆盖运行时行为和类型推导
- 代码规范:Biome 格式化 + Prettier 代码风格
- Git Hooks:Husky + lint-staged 在提交前自动检查
- CI/CD:GitHub Actions 自动化测试与发布
- 文档站:基于 Astro 构建,部署在 Netlify
构建与发布
# 克隆项目
git clone https://github.com/remeda/remeda.git
cd remeda
# 安装依赖
pnpm install
# 运行测试
pnpm test
# 类型检查
pnpm typecheck
# 构建
pnpm build贡献新函数
Remeda 社区对贡献者友好,新增函数需要:
- 实现函数逻辑(同时支持 data-first 和 data-last)
- 编写运行时测试
- 编写类型测试(确保类型推导正确)
- 添加 JSDoc 文档注释
迁移工具
官方提供从 Lodash 迁移的专门指南:remedajs.com/migrate/lodash
性能与安全
性能特点
| 指标 | Remeda | Lodash | 说明 |
|---|---|---|---|
| 完整包体积 | ~8 KB | ~70 KB | Remeda 约为 Lodash 的 1/9 |
| Tree-shaking | 原生 ESM,自动生效 | 需使用 lodash-es | Remeda 开箱即用 |
| 基础操作性能 | 与 Lodash 持平 | 基准线 | 单次操作性能相当 |
| 大数据集管道 | 显著更优 | 需手动 chain | 惰性求值避免多余遍历 |
| pipe + take 场景 | 提前终止 | 需显式 chain | 惰性求值自动优化 |
惰性求值性能优势
// 非惰性:遍历 1000 个元素 × 3 次(map + filter + take 各一次)
const result1 = take(filter(map(hugeArray, fn1), fn2), 3)
// 惰性(pipe 内):只遍历到找到 3 个匹配元素即停止
const result2 = pipe(hugeArray, map(fn1), filter(fn2), take(3))安全注意事项
- 零依赖意味着零供应链攻击风险
- 所有代码经过 TypeScript 严格模式编译
- 运行时与类型双重测试保障正确性
- MIT 许可证,无商业使用限制
已知性能注意点
- 对于极简单的操作(如
R.map仅一次调用),Remeda 可能有微弱的函数调用开销 - 惰性求值仅在
pipe()内生效,单独调用函数时不会触发
技术对比
Remeda vs Lodash vs es-toolkit
| 维度 | Remeda | Lodash | es-toolkit |
|---|---|---|---|
| TypeScript 支持 | 原生编写,类型一流 | 外部 @types/lodash,类型宽泛 | 原生编写,类型精确 |
| 包体积 | ~8 KB | ~70 KB | ~5 KB |
| Tree-shaking | 原生 ESM,自动 | 需 lodash-es | 原生 ESM,自动 |
| Data-First | 支持 | 支持 | 支持 |
| Data-Last | 支持 | 不支持 | 不支持 |
| 惰性求值 | pipe 内自动 | 需 chain() | 不支持 |
| 函数数量 | ~200 | ~300 | ~150 |
| 异步工具 | 有限 | 无 | 部分支持 |
| 周下载量 | ~500K | ~25M | ~2M |
| 学习曲线 | 中等 | 低 | 低 |
| Pipe 中类型推导 | 精确收窄 | 丢失类型 | 较好 |
Remeda vs Ramda
| 维度 | Remeda | Ramda |
|---|---|---|
| TypeScript | 原生编写 | 外部类型,不完整 |
| Data-First | 支持 | 不支持(仅 data-last) |
| Data-Last | 支持 | 支持 |
| 惰性求值 | 支持 | 不支持 |
| 学习曲线 | 较低(可选函数式) | 较高(纯函数式) |
| 实际项目采用度 | 快速增长 | 稳定但小众 |
最佳实践
1. 优先使用 pipe 组合数据管道
// 推荐:使用 pipe 获得惰性求值和类型收窄
const result = pipe(
users,
filter((u) => u.active),
map((u) => u.name),
take(10),
)
// 不推荐:多次中间变量
const activeUsers = users.filter((u) => u.active)
const names = activeUsers.map((u) => u.name)
const top10 = names.slice(0, 10)2. 善用 data-first 处理简单操作
// 简单场景直接用 data-first,更直观
const sorted = R.sortBy([3, 1, 2], (n) => n)
const grouped = R.groupBy(users, (u) => u.role)3. 利用类型收窄
// Remeda 的类型会在 pipe 中逐步收窄
const result = pipe(
[1, 'a', 2, 'b', 3] as const,
R.filter(R.isNumber), // 过滤后类型收窄为 readonly number[]
R.map((n) => n * 2), // 此处 n 被推导为 number,无需手动断言
)4. 禁用惰性求值的场景
// 如果需要在 pipe 中强制立即求值(例如调试),用箭头函数包裹
const result = pipe(
data,
(d) => R.map(d, fn), // 立即执行,不惰性
filter(predicate), // 继续惰性
)5. 使用官方迁移工具
从 Lodash 迁移时,参考 官方迁移指南 对照函数名差异。
技术局限与边界
已知限制
- 函数数量少于 Lodash:约 200 个 vs Lodash 的 300 个,部分冷门函数可能缺失
- 无 debounce/throttle:这些时间相关工具需要浏览器环境,Remeda 倾向于不包含
- 无 deep merge:深度合并对象需借助其他库或自行实现
- 社区规模仍较小:相比 Lodash 的庞大生态,遇到问题时可参考的资料较少
- 学习成本:需要了解 data-first/data-last 的区别和 pipe 的工作方式
不适用场景
- 需要 Lodash 特定函数(如
_.merge、_.debounce):需搭配其他库 - 非 TypeScript 项目:虽然可用 JavaScript,但无法享受核心类型优势
- 极简体积要求:es-toolkit(~5 KB)可能比 Remeda(~8 KB)更合适
- 纯函数式编程:Ramda 仍是更纯粹的选择
迁移注意事项
- 从 Lodash 迁移需逐函数对照 API 差异
- 部分 Lodash 函数在 Remeda 中名称不同(如
_.groupBy→R.groupBy) - 惰性求值行为可能与 Lodash chain 不完全一致,需测试边界情况
学习资源
- 官方文档:https://remedajs.com/docs
- Lodash 迁移指南:https://remedajs.com/migrate/lodash
- GitHub 仓库:https://github.com/remeda/remeda
- JSR 包:https://jsr.io/@remeda/remeda
- 掘金中文教程:Remeda:data-first 和 data-last,它全都要
- 深度解读:懶有懶的好處,聊聊 Lazy Evaluation
- 技术文章:Remeda - A Modern TypeScript-First Utility Library
- Reddit 讨论:r/typescript - FP utility libraries
- 对比文章:es-toolkit vs remeda vs lodash 2026
2026 年现状
最新版本
- v2.39.0(2026 年 6 月发布),保持了高频更新节奏
- 已累计发布 242+ 个版本,开发活跃度极高
发展趋势
- 增长迅速:被列入「2026 年 npm 增长最快的 20 个包」,周下载量约 50 万次
- 社区认可:GitHub Stars 达到 5.4k+,在 TypeScript 社区中被广泛推荐为 Lodash 替代方案
- 生态扩展:已登陆 JSR(Deno 包注册表),支持 Deno 生态
- 中文社区:掘金等平台有高质量中文教程
未来展望
- 持续增加新工具函数(通过社区 Issue 和 Discussion 驱动)
- TypeScript 类型系统持续精进,利用最新 TS 特性改进类型推导
- 随着 TypeScript 严格模式在企业中的普及,Remeda 的类型安全优势将更加突出
- 与 es-toolkit 的竞争将推动两者在性能和体积上持续优化