Rapt logo

This week, I released Rapt, a small new open source javascript library I have been working on. A good moment to resurrect this blog! Below is an excerpt of the readme document available on GitHub. I am looking for feedback and contributions!


Rapt is a small package that wraps any value, allowing you to map over it. A bit like Lodash’s chain, or Gulp’s pipe, but for values rather than collections or streams.

Rapt does not exist to reduce the number of characters in your code, nor to make your code run faster. For many, it will not even be the clearest way to write your code. But if, like me, you find it easier to read and understand a list of functions than a variety of assignments, operators and returns, then Rapt might help you enjoy the code you write a little more.

It lends itself to a highly functional style of JS programming, allowing you to work with and transform values without having to assign them to variables. It works best with immutable values (numbers, strings, immutable collections). It is particularly well suited to the latter, and is very satisfying if you hate using let just so you can reassign an immutable value after modifying it, i.e. let x = Map(); x = x.set('a', 1).

It can be used with plain mutable objects and arrays but it may be counter-productive in terms of clarity, as the functions you pass to Rapt#map() will no longer be side-effect-free.

Rapt is particularly useful when you want to avoid unnecessarily executing expensive operations, but you don’t want to give up your functional style.

Examples

import {Map} from 'immutable'

// without Rapt
const processUser = user => {
  log(user)
  let userMap = Map(user)
  if (emailHasBeenVerified) {
    userMap = userMap.set('verified', true)
  }
  syncWithServer(userMap)
  return userMap
}

// with Rapt
const processUser = user =>
  rapt(user)
    .tap(log)
    .map(Map)
    .mapIf(emailHasBeenVerified, u => u.set('verified', true))
    .tap(syncWithServer)
    .val()
import _ from 'lodash'

// without Rapt
const countItems = (shouldFilter, hugeArrayOfItems) => {
  let arr = _.compact(hugeArrayOfItems)
  if (shouldFilter) {
    arr = arr.filter(expensiveFilterFunction)
  }
  const count = arr.length
  console.log(`We have ${count} items`)
  return count
}

// with Rapt
const countItems = (shouldFilter, hugeArrayOfItems) =>
  rapt(hugeArrayOfItems)
    .map(compact)
    .mapIf(shouldFilter, arr => arr.filter(expensiveFilterFunction))
    .map(items => items.length)
    .tap(count => console.log(`We have ${count} items`))
    .val()

Read more about Rapt on GitHub.

npm version Build Status Greenkeeper badge