Remeda logo

Remeda

专为 TypeScript 打造的「data-first」与「data-last」双模式工具函数库,提供一流的类型支持与惰性求值能力。

工具函数TypeScript双模式惰性求值

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-FirstR.filter(array, fn) — 数据参数在前,适合命令式编程
  • Data-LastR.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-beltTypeScript 函数式编程库,提供 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 社区对贡献者友好,新增函数需要:

  1. 实现函数逻辑(同时支持 data-first 和 data-last)
  2. 编写运行时测试
  3. 编写类型测试(确保类型推导正确)
  4. 添加 JSDoc 文档注释

迁移工具

官方提供从 Lodash 迁移的专门指南:remedajs.com/migrate/lodash

性能与安全

性能特点

指标RemedaLodash说明
完整包体积~8 KB~70 KBRemeda 约为 Lodash 的 1/9
Tree-shaking原生 ESM,自动生效需使用 lodash-esRemeda 开箱即用
基础操作性能与 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

维度RemedaLodashes-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

维度RemedaRamda
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 中名称不同(如 _.groupByR.groupBy
  • 惰性求值行为可能与 Lodash chain 不完全一致,需测试边界情况

学习资源

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 的竞争将推动两者在性能和体积上持续优化