As to this part of the question:
There is no way anyone here can answer that definitively. It depends on your requirements, your history, your programming taste, and a million even more fuzzy factors.
I'm biased in favor of Ramda, but I still won't try to tell you which one is better.
But there are significant overlaps in capability between these two and significant differences in underlying philosophy.
Both are grab-bags of utility function, with little or no cohesion between the functions. That is, they are libraries and not frameworks. They don't at all try to determine how you write or organize your code.
They have a great deal of overlap. Among the 305 current lodash functions and the 261 current Ramda ones, there are 103 with shared names, and almost always, similar purposes. Probably half the remaining functions are found in the other library under different names.
Although there were some experimental functional libraries before it, Underscore was the one that brought many of these concepts to the mainstream of Javascript. It stood alone for a while as the undisputed leader in this space.
But there were problems with its performance. Eventually, lodash was created in large part to try to do the same thing with better performance. By creating custom versions of classic functions like map, lodash was quickly able to outperform Underscore. But it started as a drop-in replacement for Underscore and kept that focus for a long while.
The Ramda founders were impressed with the ideas in Reginald Braithwaite's JavaScript Allongé and created Ramda as an educational tool to help turn these ideas into a pragmatic library. They were less focused on performance, and more on a clean API and functional composition, as well as immutable data and side-effect-free coding.
Through an odd series of events, it eventually grew quite popular. These days you don't hear much about Underscore. It's still out there, and still used a fair bit, but you don't hear much buzz.
For most users, lodash fills that space well. Ramda grew quickly but seems to have settled down at about 20 - 25% of the downloads that lodash gets.
But all three libraries continue to grow in capability and in usage, with Underscore and Ramda about the same usage, far below lodash.
At one point, lodash created a version that tries to take into account some of Ramda's core concerns. I personally have never used lodash-fp so I can't speak to how successfully it does this.
Lodash focuses on flexibility and performance. Its focus, as its creator once described, is on
While no general-purpose library can ever be quite as fast as custom-written code, lodash gets as close as possible.
And lodash is flexible. As described several years ago
Ramda is less concerned with performance, and more with simple and clean API design. The idea for Ramda is that a function should do one thing only, and should have a single clear interface.
Ramda's filter function takes a predicate function and an object of a filterable type and returns another object of that type. (Of course, this raises the question of what constitutes a filterable type, but that's for its documentation.)
Ramda's focus is on making it simple to compose functions, to work as though all data is immutable, and to avoid side effects. It also incorporates other functional programming concerns, such as supplying lenses and working with the algebraic types of the FantasyLand specification.
Lodash functions mostly take their data first, followed by those things that work on the data, followed sometimes by optional arguments that change the behaviour.
Ramda puts the arguments least likely to change first. This means that in data-transformation functions the data is last. And Ramda avoids optional arguments altogether.
Ramda curries all its functions, as well as nearly all the functions it returns to you.
Lodash has a curry function, but you would need to call it explicitly. This is fairly central to Ramda's ideas on function composition.
Lodash focuses on reference equality.
Ramda focuses on value equality.
So while these are similar:
// lodash
_.union ([1, 2, 3, 4, 5], [2, 3, 5, 7, 11]) //=> [1, 2, 3, 4, 5, 7, 11]
_.intersection ([1, 2, 3, 4, 5], [2, 3, 5, 7, 11]) //=> [2, 3, 5]
// Ramda
R.union ([1, 2, 3, 4, 5], [2, 3, 5, 7, 11]) //=> [1, 2, 3, 4, 5, 7, 11]
R.intersection ([1, 2, 3, 4, 5], [2, 3, 5, 7, 11]) //=> [2, 3, 5]
these act very differently:
// lodash
_.union (
[{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 5}],
[{x: 2}, {x: 3}, {x: 5}, {x: 7}, {x: 11}]
)
//=> [{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 5}, {x: 2}, {x: 3}, {x: 5}, {x: 7}, {x: 11}]
_.intersection (
[{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 5}],
[{x: 2}, {x: 3}, {x: 5}, {x: 7}, {x: 11}]
) //=> []
// Ramda
R.union (
[{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 5}],
[{x: 2}, {x: 3}, {x: 5}, {x: 7}, {x: 11}]
)
//=> [{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 5}, {x: 7}, {x: 11}]
R.intersection (
[{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 5}],
[{x: 2}, {x: 3}, {x: 5}, {x: 7}, {x: 11}]
) //=> [x: 2}, {x: 3}, {x: 5}]
So, Ramda's design is more closely aligned with functional systems but comes at a substantial performance price whenever equality-checking is involved. Lodash is perhaps two orders of magnitude faster than Ramda for such tasks.
Ramda is chiefly designed to build functions through composition, in short, or long pipelines.
Lodash is chiefly designed to work with imperative code.
You can use either library for either job, but typical Ramda code might look like
const myFn = R.pipe (
R.fn1,
R.fn2 ('arg1', 'arg2'),
R.fn3 ('arg3'),
R.fn4
)
where the equivalent lodash code might look like
const myFn = (x, y) => {
const var1 = _.fn1 (x, y)
const var2 = _.fn2 (var1, 'arg1', 'arg2')
const var3 = _.fn3 (var2, 'arg3')
return _.fn4 (var3)
}
Lodash's focus on performance means that it will supply many well-optimized functions. For instance, Lodash has all of these functions:
isArguments
isArray
isArrayBuffer
isArrayLike
isArrayLikeObject
isBoolean
isBuffer
isDate
isElement
isEqual
isEqualWith
isError
isFinite
isFunction
isInteger
isLength
isMap
isMatch
isMatchWith
isNaN
isNativeisNull
isNumber
isObject
isObjectLike
isPlainObject
isRegExp
isSafeInteger
isSet
isString
isSymbol
isTypedArray
isUndefined
isWeakMap
isWeakSet
Ramda, by contrast, expects you to supply more arguments to common functions. It has only
is
isEmpty
isNil
But it's is
handles nearly all the cases above, either by calling explicitly:
is(Array, [1, 2, 3])
or by partially applying it to make a reusable function
const isArray = is(Array)
Some of these differences presumably vanish with lodash-fp. But I don't get any real sense that lodash-fp is a major part of the landscape. And for lodash proper, we can see that the libraries are quite different.
The question asked about benchmarks. I know of no comprehensive benchmark suite. It seems except when the issue of value-equality vs reference-equality is involved, lodash is 10 - 20% faster at most tasks. Ramda is not as hyper-optimized as lodash, but it is written with performance in mind, so long as its other more fundamental criteria are met.
In those cases that do involve value-vs-reference equality, the lodash team can point to much higher speeds, but the Ramda team would probably respond that getting the wrong answer quickly is hardly a win.
Underscore helped bring functional programming tools to Javascript. It is a general-purpose utility library and was designed for any JS developer who wants to be more productive. Lodash inherited this focus. Both are written with developer ergonomics as a central focus.
Ramda has a much more restricted audience. It is for those who want to take not just specific tools from functional programming, but who want to take its more fundamental ideas such as functional purity and data immutability.
It is aimed both at JS developers who want to move to a more FP style and at those from FP language who want to use JS in a familiar manner. It is written with simplicity and a central focus.
These libraries overlap a great deal in functionality. But their designs, their underlying philosophies, and their developer experience are quite different.
If you're choosing between them, there is a right answer for you, based on the above, but there is no clear definitive best library for everyone.
And you should also consider whether you need one at all. It's not hard to develop your own list of reusable functions to be included in whatever projects need them. The platform has become much more capable than when these libraries were conceived.
Design A News Feed System In this post, we are going to design a news feed system. What is a news feed? According to the Facebook help page, "News feed is the constantly updating list of stories in the middle of your home page. News Feed includes status updates, photos, videos, links, app activity, and likes from people, pages, and groups you follow on Facebook".
Design A Notification System A notification system has already become a very popular feature for many applications in recent years. A notification alerts users with important information like breaking news, product updates, events, offerings, etc. It has become an indispensable part of our daily life.