You've arrived at the rubico tour!


Glad you could make it. If you are wondering what this page is for, please see the github repo.

The rubico tour will cover:

  1. [a]synchrony
  2. Pipelines
  3. Data Shape
  4. Polymorphism
  5. Control Flow
  6. Transformation

You can expect each of the above sections to contain an editable and runnable code example.
You'll get a lot more out of this page if you play with the examples.

const {
  pipe, fork, assign,
  tap, tryCatch, switchCase,
  map, filter, reduce, transform, flatMap,
  any, all, and, or, not,
  eq, gt, lt, gte, lte,
  get, pick, omit,
} = rubico

// functional version of console.log
// put this in a pipe
const trace = tap(console.log)

👆 Additionally, these functions are globally available to you in all code areas.


You can pass rubico synchronous or asynchronous functions. When any functions are asynchronous, rubico handles the promise resolution for you. That means you can stop worrying about explicitly calling .then or Promise.all.

We can concisely make five requests to an API in parallel.


rubico's pipe is the happy marriage between the expressiveness of a modern programming language and the Unix philosophy. You can think about rubico's pipe as an analog to the Unix pipe; instead of command line utilities, you're piping functions. Without rubico, pipelines of this nature are inconvenient because most of the functions you'd want to pipe reside on the prototypes of the data, e.g. rubico inverts these prototype methods so you can create pipelines with ease, for example, with map.

If we pipe the input array [1, 2, 3, 4, 5] through the pipeline squaredOdds, we expect the output array [1, 9, 25]

Data Shape

There will be times when you'll want to control the shape of your data. For example, you may want to extend an object in your pipeline with new properties, or create a step whereby you construct a new object from an existing one. For times like these, use get in conjunction with fork or assign.

Here you can expect the object { original: 3, resultOfDouble: 6, resultOfSquare: 9 } from doingMaths on 3.


With rubico, you can act on more collections than just arrays. For example, in addition to arrays, you can also map over asyncIterables, Strings, Sets, Maps, TypedArrays, Generated Iterables, and Objects.

We square multiple collections of 1, 2, 3, 4, 5 below.

Control Flow

You can fully express logic statements with switchCase and predicate composers and, or, and not. Coupled with comparison functions like eq and gt, you would have complete control over the flow of your pipeline.

We can use rubico's flow control expressions to functionally create stats for numbers.


WARNING: this section covers transducers. If you are not completely comfortable with the subject, I've written you a crash course.

"transform" is a word that sounds cool and is even cooler in practice. When we say "transform this data", we mean "take this data and convert it to something else". It's that general. The more powerful, less expressive, and perhaps more familiar version of transform is reduce. You can use either of these to create transformations of very large, even infinite collections of data.

Here is something familiar with a twist.

Here is a decimal number converted to notes of the alphabet song.


That's all folks, thanks for reading! If you found the tour helpful, please leave a 🌟 at the github repo.

This website was created with rubico. You can find the full source on github

(c) 2020 Richard Tong. MIT Licensed.