remeda-utility

star 5.4k

Conventions for authoring, modifying, testing, and documenting a Remeda utility function — including the migration mapping pages for Lodash/Ramda/Just users. Use this skill whenever editing a file under `packages/remeda/src/` or `packages/docs/src/content/mapping/{lodash,ramda,just}/`, when reviewing a PR or local changes touching those directories, or whenever an issue, PR, or chat refers to a specific Remeda function or to a migration mapping page.

remeda By remeda schedule Updated 6/7/2026

name: remeda-utility description: Conventions for authoring, modifying, testing, and documenting a Remeda utility function — including the migration mapping pages for Lodash/Ramda/Just users. Use this skill whenever editing a file under packages/remeda/src/ or packages/docs/src/content/mapping/{lodash,ramda,just}/, when reviewing a PR or local changes touching those directories, or whenever an issue, PR, or chat refers to a specific Remeda function or to a migration mapping page.

A new or modified Remeda function ships across five surfaces: implementation, tests, JSDoc, the public export, and — when there's a Lodash/Ramda equivalent — migration mappings on the docs site. Skipping any one of them leaves the function half-shipped (e.g., a working implementation that isn't re-exported, or a behavior change with no test covering it). Work through the sections in order — later sections assume the earlier ones are in place.

1. Implementation (src/functionName.ts)

When any of the edits involves the runtime implementation of a function, one of its overloading function signatures, or any of the type definitions that it uses (either directly on the same file, or indirectly via imports) read reference/implementation.md.

2. Tests

Each function has up to three test files, one per kind:

  • Runtime tests (functionName.test.ts) — Vitest. Cover happy path, edge cases, empty inputs, and both calling styles (data-first and data-last inside pipe, map or filter). When editing, read reference/testing-runtime.md.
  • Type tests (functionName.test-d.ts) — expectTypeOf from Vitest. Verify inferred return types, narrowing, and that invalid inputs are compile errors. When editing, read reference/testing-types.md.
  • Property-based tests (functionName.test-prop.ts) — @fast-check/vitest. Optional but encouraged for functions with well-defined algebraic properties (idempotence, involutions, round-trips). When adding, read reference/testing-properties.md.

Conventions that apply across all three kinds:

  • Runtime and type assertions are strictly separatedexpect() lives in .test.ts, expectTypeOf() lives in .test-d.ts. Never mix them in the same test block, and never put one kind in the other file.
  • Test names describe what is being tested in the function's own vocabulary — "lazy early exit with hasMany", not "take and flat".
  • Test names should be terse and concise, and should rely on context from parent describe() blocks and not repeat them.
  • Test names do not need to read as prose!
  • Tests for a specific bug must reference the issue number, either in the test name or a comment so that the reporting issue can always be traced back.
  • Input data needs enough variation to produce distinct outputs — [1, 1, 1] hides bugs that [1, 2, 3] catches.

3. JSDoc

Each overload needs its own JSDoc block. Required tags:

Tag Notes
Description Present tense, precise vocabulary. First sentence is a concise one-line summary; further detail goes after a blank line.
@param One per parameter.
@signature The call as it looks at the call site, e.g., filter(data, predicate) for data-first, filter(predicate)(data) for data-last.
@example Simple, almost trivial — show params and output, not a full usage pattern. Data-last examples use pipe, map, of filter.
@dataFirst / @dataLast One per overload, matching the signature style. The docs site uses these to label and group overloads.
@lazy Only if the function supports lazy evaluation in pipe.
@category The function's category (Array, Object, String, etc.) — drives docs-site navigation.

If the new function is closely related to others where a user might pick the wrong one (e.g., indexBy vs. fromKeys vs. pullObject vs. fromEntries), list those alternatives with a one-line "use this when…" gloss in the description body of every overload. Update the related functions' JSDoc to cross-reference back, so the disambiguation is symmetric — a user who lands on either function discovers the others.

The function description, @params, @returns, and @deprecated should be copied verbatim between the overloads, unless there is a strong reason not to, and then that reason should be made extremely clear in both blocks.

4. Export

Add export * from "./functionName"; to src/index.ts (alphabetical order).

5. Migration Mappings

Many Remeda functions are genuinely novel and have no Lodash, Ramda, or Just counterpart — those skip this section entirely. But if the function has a matching upstream function (or replaces one), it needs a per-library mapping page on the docs site so migrators landing from a search for the upstream name find a clean answer for their call site.

Read reference/migration.md when:

  • Authoring a new Remeda function that has a Lodash, Ramda, or Just equivalent.
  • Editing any existing file under packages/docs/src/content/mapping/{lodash,ramda,just}/.
  • Reviewing changes that add or modify a mapping page.

reference/migration.md covers the file location and frontmatter, the bullets-then-examples body structure, the comment-header convention inside code blocks (// Lodash / // Remeda / // Native), the linking rules, and the __MISSING.md cleanup. This is interim guidance — eventually migration work will live behind its own skill, but until then this reference is the source of truth.

Install via CLI
npx skills add https://github.com/remeda/remeda --skill remeda-utility
Repository Details
star Stars 5,379
call_split Forks 167
navigation Branch main
article Path SKILL.md
More from Creator