[underscore.js] Differences between Lodash and Underscore.js

Why would someone prefer either the Lodash or Underscore.js utility library over the other?

Lodash seems to be a drop-in replacement for underscore, the latter having been around longer.

I think both are brilliant, but I do not know enough about how they work to make an educated comparison, and I would like to know more about the differences.

This question is related to underscore.js javascript lodash

The answer is


Underscore vs Lo-Dash by Ben McCormick is the latest article comparing the two:

  1. Lodash's API is a superset of Underscore.js's.
  1. Under the hood, Lodash has been completely rewritten.
  1. Lodash is definitely not slower than Underscore.js.
  1. What has Lodash added?
  • Usability improvements
  • Extra functionality
  • Performance gains
  • Shorthand syntaxes for chaining
  • Custom builds to only use what you need
  • Semantic versioning and 100% code coverage

They are pretty similar, with Lodash is taking over...

They both are a utility library which takes the world of utility in JavaScript...

It seems Lodash is getting updated more regularly now, so more used in the latest projects...

Also Lodash seems is lighter by a couple of KBs...

Both have a good API and documentation, but I think the Lodash one is better...

Here is a screenshot for each of the documentation items for getting the first value of an array...

Underscore.js:

Underscore.js

Lodash:

Lodash

As things may get updated time to time, just check their website also...

Lodash

Underscore.js


If, like me, you were expecting a list of usage differences between Underscore.js and Lodash, there's a guide for migrating from Underscore.js to Lodash.

Here's the current state of it for posterity:

  • Underscore _.any is Lodash _.some
  • Underscore _.all is Lodash _.every
  • Underscore _.compose is Lodash _.flowRight
  • Underscore _.contains is Lodash _.includes
  • Underscore _.each doesn’t allow exiting by returning false
  • Underscore _.findWhere is Lodash _.find
  • Underscore _.flatten is deep by default while Lodash is shallow
  • Underscore _.groupBy supports an iteratee that is passed the parameters (value, index, originalArray), while in Lodash, the iteratee for _.groupBy is only passed a single parameter: (value).
  • Underscore.js _.indexOf with third parameter undefined is Lodash _.indexOf
  • Underscore.js _.indexOf with third parameter true is Lodash _.sortedIndexOf
  • Underscore _.indexBy is Lodash _.keyBy
  • Underscore _.invoke is Lodash _.invokeMap
  • Underscore _.mapObject is Lodash _.mapValues
  • Underscore _.max combines Lodash _.max & _.maxBy
  • Underscore _.min combines Lodash _.min & _.minBy
  • Underscore _.sample combines Lodash _.sample & _.sampleSize
  • Underscore _.object combines Lodash _.fromPairs and _.zipObject
  • Underscore _.omit by a predicate is Lodash _.omitBy
  • Underscore _.pairs is Lodash _.toPairs
  • Underscore _.pick by a predicate is Lodash _.pickBy
  • Underscore _.pluck is Lodash _.map
  • Underscore _.sortedIndex combines Lodash _.sortedIndex & _.sortedIndexOf
  • Underscore _.uniq by an iteratee is Lodash _.uniqBy
  • Underscore _.where is Lodash _.filter
  • Underscore _.isFinite doesn’t align with Number.isFinite
    (e.g. _.isFinite('1') returns true in Underscore.js, but false in Lodash)
  • Underscore _.matches shorthand doesn’t support deep comparisons
    (e.g., _.filter(objects, { 'a': { 'b': 'c' } }))
  • Underscore = 1.7 & Lodash _.template syntax is
    _.template(string, option)(data)
  • Lodash _.memoize caches are Map like objects
  • Lodash doesn’t support a context argument for many methods in favor of _.bind
  • Lodash supports implicit chaining, lazy chaining, & shortcut fusion
  • Lodash split its overloaded _.head, _.last, _.rest, & _.initial out into
    _.take, _.takeRight, _.drop, & _.dropRight
    (i.e. _.head(array, 2) in Underscore.js is _.take(array, 2) in Lodash)

I'm agree with most of things said here, but I just want to point out an argument in favor of Underscore.js: the size of the library.

Specially in case you are developing an app or website which intend to be use mostly on mobile devices, the size of the resulting bundle and the effect on the boot or download time may have an important role.

For comparison, these sizes are those I noticed with source-map-explorer after running Ionic serve:

Lodash: 523 kB
Underscore.js: 51.6 kB

One can use BundlePhobia to check the current size of Lodash and Underscore.js.


For the most part Underscore.js is subset of Lodash.

At times, like presently, Underscore.js will have cool little functions Lodash doesn't have, like mapObject. This one saved me a lot of time in the development of my project.


In 2014 I still think my point holds:

IMHO, this discussion got blown out of proportion quite a bit. Quoting the aforementioned blog post:

Most JavaScript utility libraries, such as Underscore, Valentine, and wu, rely on the “native-first dual approach.” This approach prefers native implementations, falling back to vanilla JavaScript only if the native equivalent is not supported. But jsPerf revealed an interesting trend: the most efficient way to iterate over an array or array-like collection is to avoid the native implementations entirely, opting for simple loops instead.

As if "simple loops" and "vanilla Javascript" are more native than Array or Object method implementations. Jeez ...

It certainly would be nice to have a single source of truth, but there isn't. Even if you've been told otherwise, there is no Vanilla God, my dear. I'm sorry. The only assumption that really holds is that we are all writing JavaScript code that aims at performing well in all major browsers, knowing that all of them have different implementations of the same things. It's a bitch to cope with, to put it mildly. But that's the premise, whether you like it or not.

Maybe all of you are working on large scale projects that need twitterish performance so that you really see the difference between 850,000 (Underscore.js) vs. 2,500,000 (Lodash) iterations over a list per second right now!

I for one am not. I mean, I worked on projects where I had to address performance issues, but they were never solved or caused by neither Underscore.js nor Lodash. And unless I get hold of the real differences in implementation and performance (we're talking C++ right now) of, let’s say, a loop over an iterable (object or array, sparse or not!), I rather don't get bothered with any claims based on the results of a benchmark platform that is already opinionated.

It only needs one single update of, let’s say, Rhino to set its Array method implementations on fire in a fashion that not a single "medieval loop methods perform better and forever and whatnot" priest can argue his/her way around the simple fact that all of a sudden array methods in Firefox are much faster than his/her opinionated brainfuck. Man, you just can't cheat your runtime environment by cheating your runtime environment! Think about that when promoting ...

your utility belt

... next time.

So to keep it relevant:

  • Use Underscore.js if you're into convenience without sacrificing native'ish.
  • Use Lodash if you're into convenience and like its extended feature catalogue (deep copy, etc.) and if you're in desperate need of instant performance and most importantly don't mind settling for an alternative as soon as native API's outshine opinionated workarounds. Which is going to happen soon. Period.
  • There's even a third solution. DIY! Know your environments. Know about inconsistencies. Read their (John-David's and Jeremy's) code. Don't use this or that without being able to explain why a consistency/compatibility layer is really needed and enhances your workflow or improves the performance of your application. It is very likely that your requirements are satisfied with a simple polyfill that you're perfectly able to write yourself. Both libraries are just plain vanilla with a little bit of sugar. They both just fight over who's serving the sweetest pie. But believe me, in the end both are only cooking with water. There's no Vanilla God so there can't be no Vanilla pope, right?

Choose whatever approach fits your needs the most. As usual. I'd prefer fallbacks on actual implementations over opinionated runtime cheats anytime, but even that seems to be a matter of taste nowadays. Stick to quality resources like http://developer.mozilla.com and http://caniuse.com and you'll be just fine.


I just found one difference that ended up being important for me. The non-Underscore.js-compatible version of Lodash's _.extend() does not copy over class-level-defined properties or methods.

I've created a Jasmine test in CoffeeScript that demonstrates this:

https://gist.github.com/softcraft-development/1c3964402b099893bd61

Fortunately, lodash.underscore.js preserves Underscore.js's behaviour of copying everything, which for my situation was the desired behaviour.


Lodash is inspired by Underscore.js, but nowadays it is a superior solution. You can make your custom builds, have a higher performance, support AMD and have great extra features. Check this Lodash vs. Underscore.js benchmarks on jsperf and... this awesome post about Lodash:

One of the most useful feature when you work with collections, is the shorthand syntax:

var characters = [
  { 'name': 'barney', 'age': 36, 'blocked': false },
  { 'name': 'fred',   'age': 40, 'blocked': true }
];

// Using "_.filter" callback shorthand
_.filter(characters, { 'age': 36 });

// Using Underscore.js
_.filter(characters, function(character) { return character.age === 36; } );

// ? [{ 'name': 'barney', 'age': 36, 'blocked': false }]

(taken from Lodash documentation)


Lodash has got _.mapValues() which is identical to Underscore.js's _.mapObject().


In addition to John's answer, and reading up on Lodash (which I had hitherto regarded as a "me-too" to Underscore.js), and seeing the performance tests, reading the source-code, and blog posts, the few points which make Lodash much superior to Underscore.js are these:

  1. It's not about the speed, as it is about consistency of speed (?)

If you look into Underscore.js's source-code, you'll see in the first few lines that Underscore.js falls-back on the native implementations of many functions. Although in an ideal world, this would have been a better approach, if you look at some of the performance links given in these slides, it is not hard to draw the conclusion that the quality of those 'native implementations' vary a lot browser-to-browser. Firefox is damn fast in some of the functions, and in some Chrome dominates. (I imagine there would be some scenarios where Internet Explorer would dominate too). I believe that it's better to prefer a code whose performance is more consistent across browsers.

Do read the blog post earlier, and instead of believing it for its sake, judge for yourself by running the benchmarks. I am stunned right now, seeing a Lodash performing 100-150% faster than Underscore.js in even simple, native functions such as Array.every in Chrome!

  1. The extras in Lodash are also quite useful.
  2. As for Xananax's highly upvoted comment suggesting contribution to Underscore.js's code: It's always better to have GOOD competition, not only does it keep innovation going, but also drives you to keep yourself (or your library) in good shape.

Here is a list of differences between Lodash, and it's Underscore.js build is a drop-in replacement for your Underscore.js projects.


I am not sure if that is what OP meant, but I came across this question because I was searching for a list of issues I have to keep in mind when migrating from Underscore.js to Lodash.

I would really appreciate if someone posted an article with a complete list of such differences. Let me start with the things I've learned the hard way (that is, things which made my code explode on production:/):

  • _.flatten in Underscore.js is deep by default, and you have to pass true as second argument to make it shallow. In Lodash it is shallow by default and passing true as second argument will make it deep! :)
  • _.last in Underscore.js accepts a second argument which tells how many elements you want. In Lodash there is no such option. You can emulate this with .slice
  • _.first (same issue)
  • _.template in Underscore.js can be used in many ways, one of which is providing the template string and data and getting HTML back (or at least that's how it worked some time ago). In Lodash you receive a function which you should then feed with the data.
  • _(something).map(foo) works in Underscore.js, but in Lodash I had to rewrite it to _.map(something,foo). Perhaps that was just a TypeScript-issue.

Examples related to underscore.js

Add property to an array of objects Comparing two arrays of objects, and exclude the elements who match values into new array in JS using lodash .groupBy. how to add your own keys for grouped output? Remove Duplicate objects from JSON Array Lodash .clone and .cloneDeep behaviors find the array index of an object with a specific key value in underscore Bootstrap - Uncaught TypeError: Cannot read property 'fn' of undefined Map over object preserving keys Remove an item from array using UnderscoreJS Find by key deep in a nested array

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to lodash

Can't perform a React state update on an unmounted component Angular 4 HttpClient Query Parameters use Lodash to sort array of object by value How to group an array of objects by key Removing object properties with Lodash How to merge two arrays of objects by ID using lodash? Error: EACCES: permission denied Replacing objects in array lodash: mapping array to object Correct way to import lodash