--- name: ramda description: Guidance for using Ramda in transformation-heavy TypeScript or JavaScript. Use when editing data pipelines, collection/object transformations, reducers, selectors, or parser code that can benefit from Ramda operators. --- # Ramda Skill Use this skill when editing transformation-heavy TypeScript or JavaScript in this repo. ## Principles - Prefer Ramda when it makes data transformations more declarative and easier to scan. - Avoid point-free code that hides types, branching, errors, or important domain names. - Prefer `R.pipe` for readable left-to-right transformations when it avoids noisy intermediate variables. - Plain loops are acceptable for complex branching, early exits, async control flow, or hot paths where Ramda obscures intent. - Prefer a single `reduce` over `filter` plus `map` when one pass remains clear. ## Preferred Operators - Selection and shape: `pick`, `pickBy`, `omit`, `props`, `path`, `pathOr`, `assoc`, `assocPath`, `evolve`. - Combining and merging: `mergeLeft`, `mergeRight`, `mergeDeepRight`, `union`, `intersection`, `difference`, `symmetricDifference`. - Collections: `groupBy`, `countBy`, `uniq`, `range`, `indexBy`, `partition`, `sortBy`, `ascend`, `descend`. - Predicates: `any`, `all`, `anyPass`, `allPass`, `propEq`, `pathEq`, `includes`. - String/list transforms: `split`, `splitAt`, `splitEvery`, `join`. - Fan-out and composition: `juxt`, `applySpec`, `converge`, `pipe`. - Object utilities: `invert`, `invertObj`, `toPairs`, `fromPairs`, `mapObjIndexed`. ## Type Discipline - Keep `undefined` and `null` separate. Do not use `R.isNil` when absent and explicitly-null states need different behavior. - Prefer typed helper functions at transformation boundaries so component and reducer code does not need casts. - Reuse domain/API types when the transformation preserves the same shape. ## Review Checklist - Is the transformation clearer than the equivalent plain TypeScript? - Are all intermediate domain concepts still named when naming helps understanding? - Does the code preserve `undefined` versus `null` semantics when that distinction matters?