Rambda: TypeScript-first functional pipelines without Ramda compatibility
Typescript focused FP library similar to Remeda and Ramda
At a glance
- What is it?
- Rambda is a TypeScript utility library centered on curried functions, `pipe`, and inferred data types. Its small API and Deno support suit codebases that want readable functional pipelines, but version 10 deliberately broke Ramda drop-in compatibility.
- Who is it for?
- Adopt Rambda when TypeScript inference inside `pipe` is the priority and the team accepts its deliberately limited, curried API. Do not adopt it for an unchanged Ramda migration, uncurried calls, or generic helpers such as `curry` and `assoc`.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 31 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Star history
- selfrefactor/rambda1,758 ★ · +0
| Repository | 2026-10-16 | 2026-10-23 |
|---|---|---|
| selfrefactor/rambda | 1.8k | 1.8k |
0 Stars in the last 7 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
Rambda's pipe-first TypeScript design
Rambda solves a specific problem for TypeScript developers who want to transform data through functional operations without repeatedly writing argument types. Its functions are designed for `pipe` and `pipeAsync` chains, where the input value is supplied first and each operation receives the output of the previous one. This gives TypeScript a concrete value from which to infer subsequent parameter and return types.
The choice is restrictive by design. Calling `filter` as `R.filter(fn, list)` does not work. The documented form is `R.filter(fn)(list)`, which usually appears inside `pipe` as `pipe(list, filter(fn))`. Functions that require two arguments are divided into stages, while functions that require three use the first two arguments before returning a function for the third. This is not convenience currying over every possible arrangement. It is a single calling convention selected to make pipelines and their type definitions predictable.
That focus also explains omitted functions. The README says Rambda leaves out difficult-to-remember logic, generic helpers such as `curry` and `assoc`, and functions such as `length`, `difference`, `cond`, and `ifElse`. The expected result is a narrower library whose operation names communicate intent, but applications that rely on a broad collection of utilities may find gaps that require local code.
How Rambda moves data through pipe and pipeAsync
The defining data flow is straightforward: a caller passes an initial value to `pipe`, followed by unary functions that transform or inspect it. In the README example, the input array goes into `filter`, the filtered values go into `map`, and `map` produces the final array. The pipeline returns one value at each stage rather than constructing an abstraction around the whole chain.
Rambda treats this form as part of its public contract. The README states that methods are tested for correct types when used within `R.pipe` and `R.pipeAsync` chains. It also warns that a direct curried call such as `R.filter(x => x > 1)([1, 2, 3])` can trigger a TypeScript error because it differs from `pipe([1, 2, 3], R.filter(x => x > 1))`. This warning is significant for adoption because idiomatic code depends on routing operations through the intended composition API.
The API also removes some ambiguity through specialized syntax. `R.path` can accept either an array path or dot notation such as `R.path('a.b')`. Numeric-looking segments passed through a string are converted to numbers, so code that must address the string key `'1'` needs the array form. `R.pick` and `R.omit` accept comma notation, but the README says no spaces are allowed between properties. These conveniences are compact, although the array form remains necessary when keys contain delimiters or numeric-looking names.
Installing rambda and running the first pipe
The README does not provide an installation command. It identifies the published package as `rambda` and links to the documentation site, so readers should obtain the package through their normal JavaScript or TypeScript package workflow and consult the project documentation for the applicable setup. The repository uses Yarn and includes a `yarn.lock`, but that does not by itself establish a user-facing installation command.
Once `rambda` is available, the README's first real use imports `pipe`, `filter`, and `map`, then composes an array transformation. The expected result is `[6, 8]`, according to the README:
import { pipe, filter, map } from 'rambda'
const result = pipe(
[1, 2, 3, 4],
filter(x => x > 2),
map(x => x * 2),
)The repository's `package.json` identifies the package as an ES module and exposes separate TypeScript declaration entry points, an ESM default file, and a CommonJS file. The package also has no runtime dependencies. This package metadata supports a small installation footprint, but compatibility with a particular TypeScript configuration, bundler, or module resolution mode still needs checking in the consuming project.
For Deno, the README gives a direct URL import rather than a package-manager installation. It imports the namespace as `R` and applies `R.filter` in curried form:
import * as R from "https://deno.land/x/rambda/mod.ts";
R.filter(x => x > 1)([1, 2, 3])This snippet demonstrates the direct Deno entry point documented by the project. It also illustrates that direct use is not discouraged in every context, even though `pipe` remains the preferred composition style.
ESM, CommonJS, Deno, and repository build outputs
Rambda publishes for several consumption models. In `package.json`, the default export points to `dist/rambda.js` for ESM, while the `require` condition points to `dist/rambda.cjs`. Type declarations are separated into `index.d.ts` and `index.d.cts`, matching the ESM and CommonJS paths. This structure is relevant to TypeScript projects because a JavaScript bundle can load while declarations fail under the wrong module mode.
The repository contains `source/`, `src/`, top-level module files, declaration files, and `dist/`. Its build script uses Rollup to create the main CommonJS output, the web UMD output named `R`, and the ESM output. The README does not explain the exact division between source directories, so adopters should not assume that importing an internal file is a stable public entry point. The `exports` map in `package.json` is the more concrete boundary.
The Deno entry point is a remote `https://deno.land/x/rambda/mod.ts` import. The README does not explain how that endpoint maps to a particular release or how upgrades are pinned, so applications that require reproducible dependency resolution would need to establish that separately. The presence of both distribution systems is useful, but it introduces more than one path to evaluate when planning upgrades.
Version 10 compatibility and upgrade boundaries
Rambda was not always this selective. According to the README, the project aimed to match much of the Ramda API through version 9.4.2. From version 10.0.0 onward, it no longer aims to be a drop-in replacement for Ramda. Migration therefore cannot be treated as a package-version-only change. Teams must review function availability, argument order, and the required use of curried calls.
The release history lists `v10.0.0-beta.1` on 2025-03-24, `v10.0.0` on 2025-04-17, and `v10.3.4` on 2025-11-22. The checked-in `package.json` declares version `11.3.0`, while the release list does not include a corresponding 11.x release. The repository does not explain this difference, so consumers should confirm which published artifact they actually install rather than selecting a version from assumptions.
The repository was not archived, and its last push was on 2026-09-22. That indicates recent repository activity, but the README does not document a support policy for older releases, a compatibility matrix for every TypeScript version, or a detailed migration guide beyond the Ramda compatibility statement. Upgrading an established codebase still requires reviewing `CHANGELOG.md` and project-specific type tests.
Rambda compared with Ramda and broad utility libraries
The real alternative is Ramda, but Rambda now differs from it at the API philosophy and typing model. Ramda is the reference implementation named throughout the Rambda README, and Rambda previously tried to match much of its API. Since version 10, Rambda explicitly rejects drop-in compatibility. Its fixed currying style and pipe-oriented tests are designed around TypeScript inference rather than broad Ramda parity.
A second alternative is writing small local transformation helpers. That approach may be more suitable for a codebase that needs only `filter`, `map`, and a few object operations but wants no dependency. The cost is maintaining those helpers and their tests. Rambda's argument is that its included functions are common enough to avoid recreating them, while its exclusions keep uncommon behavior out of the package.
Rambda is the wrong tool when call sites need mixed uncurried and curried styles. It is also a poor fit if generic helpers such as `curry` or `assoc` are foundational to an existing utility layer. Code that relies on Ramda parity should use Ramda or budget for a deliberate migration, because importing Rambda version 10 or later under the assumption of API equivalence will encounter documented differences.
Rambda's MIT license and maintenance cost
Rambda is distributed under the MIT license. That permissive license generally provides broad permission to use, copy, modify, merge, publish, distribute, sublicense, and sell copies, subject to its notice and disclaimer terms. This is a concise description of the license category, not legal advice; a consuming organization should review the repository's `LICENSE` file for the exact obligations applicable to its distribution.
The main maintenance cost is not an API surface spanning many generalized utilities. Rambda's omissions reduce the number of imported functions, while its pipe-first convention creates a single rule the team must follow consistently. The cost shifts toward accepting a curated library and implementing excluded behavior in application code. A Ramda migration can add further cost because calls must be reorganized around currying and removed functions may need local equivalents.
For runtime dependencies, `package.json` lists none. Development and project-maintenance work is more involved: the repository defines formatting, build, Vitest, and TypeScript checks with scripts including `yarn test:ci`, `yarn test:typings`, `yarn build`, and `yarn format`. These are repository commands rather than documented consumer commands, so cloning the repository is necessary before using them.
Editorial conclusion
Adopt Rambda when TypeScript inference inside `pipe` is the priority and the team accepts its deliberately limited, curried API. Do not adopt it for an unchanged Ramda migration, uncurried calls, or generic helpers such as `curry` and `assoc`. Before upgrading an existing project, verify the changed calling convention, package entry points, and any methods removed after version 9.4.2.
Frequently asked questions
How do I install and start using Rambda?
The README does not give a package-manager installation command. It identifies the package as `rambda`, links to the documentation site, and shows imports such as `import { pipe, filter, map } from 'rambda'` for a first pipeline.
Can I use Ramda's uncurried function calls with Rambda?
No. Rambda documents a curried calling convention, so `R.filter(fn, list)` does not work; the intended form is `R.filter(fn)(list)`, usually composed inside `pipe`. From version 10.0.0 onward, Rambda is no longer intended as a Ramda drop-in replacement.
Does Rambda support TypeScript, Deno, ESM, and CommonJS?
The repository identifies TypeScript as its primary language, the README documents a Deno import, and `package.json` provides ESM and CommonJS export conditions with corresponding declaration files. The exact compatibility still depends on the consuming project's module configuration.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/selfrefactor-rambda)Star history chart for your README
[](https://hysenlabs.com/projects/selfrefactor-rambda)Was this useful?