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 separated —
expect() 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.
Source: remeda/remeda — distributed by TomeVault.
1---2name: remeda-utility3description: 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. Use when this capability is needed.4---56A new or modified Remeda function ships across five surfaces: implementation,7tests, JSDoc, the public export, and — when there's a Lodash/Ramda equivalent —8migration mappings on the docs site. Skipping any one of them leaves the9function half-shipped (e.g., a working implementation that isn't re-exported,10or a behavior change with no test covering it). Work through the sections in11order — later sections assume the earlier ones are in place.1213# 1. Implementation (`src/functionName.ts`)1415When any of the edits involves the runtime implementation of a function, one of16its overloading function signatures, or any of the type definitions that it uses17(either directly on the same file, or indirectly via imports) read18`reference/implementation.md`.1920# 2. Tests2122Each function has up to three test files, one per kind:2324- **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`.25- **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`.26- **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`.2728Conventions that apply across all three kinds:2930- Runtime and type assertions are **strictly separated** — `expect()` 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.31- Test names describe **what** is being tested in the function's own vocabulary — "lazy early exit with hasMany", not "take and flat".32- Test names should be terse and concise, and should rely on context from parent `describe()` blocks and not repeat them.33- Test names do not need to read as prose!34- 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.35- Input data needs enough variation to produce distinct outputs — `[1, 1, 1]` hides bugs that `[1, 2, 3]` catches.3637# 3. JSDoc3839Each overload needs its own JSDoc block. Required tags:4041| Tag | Notes |42| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |43| Description | Present tense, precise vocabulary. First sentence is a concise one-line summary; further detail goes after a blank line. |44| `@param` | One per parameter. |45| `@signature` | The call as it looks at the call site, e.g., `filter(data, predicate)` for data-first, `filter(predicate)(data)` for data-last. |46| `@example` | Simple, almost trivial — show params and output, not a full usage pattern. Data-last examples use `pipe`, `map`, of `filter`. |47| `@dataFirst` / `@dataLast` | One per overload, matching the signature style. The docs site uses these to label and group overloads. |48| `@lazy` | Only if the function supports lazy evaluation in `pipe`. |49| `@category` | The function's category (`Array`, `Object`, `String`, etc.) — drives docs-site navigation. |5051If 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.5253The 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.5455# 4. Export5657Add `export * from "./functionName";` to `src/index.ts` (alphabetical order).5859# 5. Migration Mappings6061Many 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.6263Read `reference/migration.md` when:6465- Authoring a new Remeda function that has a Lodash, Ramda, or Just equivalent.66- Editing any existing file under `packages/docs/src/content/mapping/{lodash,ramda,just}/`.67- Reviewing changes that add or modify a mapping page.6869`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.7071---72> Source: [remeda/remeda](https://github.com/remeda/remeda) — distributed by [TomeVault](https://tomevault.io).73<!-- tomevault:4.0:skill_md:2026-06-19 -->