Differences between Lodash and Underscore.js
Solution 1
I created Lodash to provide more consistent cross-environment iteration support for arrays, strings, objects, and arguments
objects1. It has since become a superset of Underscore.js, providing more consistent API behavior, more features (like AMD support, deep clone, and deep merge), more thorough documentation and unit tests (tests which run in Node.js, RingoJS, Rhino, Narwhal, PhantomJS, and browsers), better overall performance and optimizations for large arrays/object iteration, and more flexibility with custom builds and template pre-compilation utilities.
Because Lodash is updated more frequently than Underscore.js, a lodash underscore
build is provided to ensure compatibility with the latest stable version of Underscore.js.
At one point I was even given push access to Underscore.js, in part because Lodash is responsible for raising more than 30 issues; landing bug fixes, new features, and performance gains in Underscore.js v1.4.x+.
In addition, there are at least three Backbone.js boilerplates that include Lodash by default and Lodash is now mentioned in Backbone.js’s official documentation.
Check out Kit Cambridge's post, Say "Hello" to Lo-Dash, for a deeper breakdown on the differences between Lodash and Underscore.js.
Footnotes:
- Underscore.js has inconsistent support for arrays, strings, objects, and
arguments
objects. In newer browsers, Underscore.js methods ignore holes in arrays, "Objects" methods iteratearguments
objects, strings are treated as array-like, and methods correctly iterate functions (ignoring their "prototype" property) and objects (iterating shadowed properties like "toString" and "valueOf"), while in older browsers they will not. Also, Underscore.js methods, like_.clone
, preserve holes in arrays, while others like_.flatten
don't.
Solution 2
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 features, when you work with collections, is the shorthand syntax:
(although Underscore now also supports this 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)
Solution 3
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 returningfalse
- 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 parameterundefined
is Lodash_.indexOf
- Underscore.js
_.indexOf
with third parametertrue
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 aniteratee
is Lodash_.uniqBy
- Underscore
_.where
is Lodash_.filter
- Underscore
_.isFinite
doesn’t align withNumber.isFinite
(e.g._.isFinite('1')
returnstrue
in Underscore.js, butfalse
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 areMap
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)
Solution 4
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:
- 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!
- The extras in Lodash are also quite useful.
- 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.
Solution 5
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.

Comments
-
Brian M. Hunt almost 2 years
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.