Underscore.js
Underscore.js is a JavaScript library which provides utility functions for common programming tasks. It is comparable to features provided by Prototype.js and the Ruby language, but opts for a functional programming design instead of extending object prototypes.
Websites Using Underscore.js
What Is Underscore.js?
Underscore.js is a JavaScript utility-belt library that provides over a hundred functional programming helpers for working with arrays, objects, collections, and functions, without extending any built-in JavaScript objects. The direct answer to what Underscore is: it is the influential utility library that predated and shaped Lodash, gave early web applications a consistent set of helpers when JavaScript's standard library was sparse, and is still detected on many sites today, both directly and as a dependency of Backbone.js.
Underscore was created by Jeremy Ashkenas and first released in 2009, making it one of the foundational utility libraries of the modern JavaScript era. At the time, JavaScript lacked many of the array and object methods developers now take for granted, and browser support for the ones that existed was inconsistent. Underscore filled that gap with functions like map, filter, reduce, each, pluck, and groupBy, all exposed through a single global object, the underscore character _. Precise current market-share numbers are difficult to state with confidence because much Underscore usage is bundled or indirect, and detection methodologies differ, so any single percentage should be read cautiously. What detection sources such as Wappalyzer and BuiltWith consistently report is that Underscore remains widely present, heavily concentrated in older codebases and anywhere Backbone is used.
Underscore's design influence is hard to overstate: Lodash began life as an Underscore-compatible drop-in replacement, and many of the helper names and signatures developers use daily trace back to Underscore's original API.
How Underscore.js Works
Underscore is a collection of standalone, pure functions exposed on a single namespace object, conventionally the underscore character _. You call helpers as _.map(list, fn), _.filter(list, predicate), or _.pluck(list, 'name'). Crucially, Underscore does not modify the built-in Array.prototype or Object.prototype; it keeps its functions in its own namespace, which avoids polluting native objects and prevents conflicts with other code.
The library groups its functions into a few clear categories. Collection functions (each, map, reduce, filter, reject, find, groupBy, countBy, sortBy) work on both arrays and objects. Array functions (first, last, flatten, uniq, intersection, difference, zip) handle ordered data specifically. Object functions (keys, values, extend, pick, omit, defaults, clone, isEqual) manipulate plain objects. Function helpers (bind, partial, memoize, throttle, debounce, once) shape how and when functions run. Utility helpers (identity, times, uniqueId, escape, template) round out the set.
Underscore also supports a chaining style through _.chain(list), which wraps a value so multiple helpers can be applied in sequence and unwrapped with .value(). This lets you express a data pipeline (filter, then map, then sort) fluently.
A small but historically important feature is _.template, a micro-templating function that compiles HTML templates with interpolation (<%= %>) and embedded JavaScript (<% %>). Many early applications, especially Backbone apps, used _.template to render views before dedicated templating engines and frameworks took over.
Underscore is also unusually portable. The same _ namespace works in the browser and in Node.js (where it is required as a CommonJS module), and it does not assume the presence of any other library. That self-contained, environment-agnostic design is part of why it spread so widely and why so many other tools felt comfortable depending on it.
Because every function is independent and side-effect free, Underscore is predictable and easy to test, which is exactly why it became a dependency that other libraries (most notably Backbone) chose to build on.
How to Tell if a Website Uses Underscore.js
Underscore is straightforward to detect, though you must distinguish it from Lodash, which also uses the _ global.
Signals in the page and network
- Script filenames. Look for
underscore.js,underscore-min.js, orunderscore.min.jsin View Source or the Network tab, often loaded from a CDN path such ascdnjs.cloudflare.com/ajax/libs/underscore.js/orcdn.jsdelivr.net/npm/underscore. - The
window._global. In the DevTools Console, type_. If an object is returned, a utility library is present. To confirm it is Underscore rather than Lodash, check_.VERSIONand look for Underscore-specific behavior. - Version marker.
_.VERSIONreturns the version string (for example1.13.6). Underscore exposes this property directly. - Distinguishing from Lodash. Lodash exposes
_.VERSIONtoo, but it also defines a tell-tale_.runInContextand_.chainwith lazy evaluation, plus methods Underscore lacks. If_.pluckexists, that strongly suggests Underscore, since Lodash removedplucklong ago. If you see_.chunk,_.fromPairs, or_.flattenDeep-style methods, lean toward Lodash. - Paired Backbone.js. Because Backbone depends on Underscore, seeing
window.Backbonealongside_is a strong combined signal that the_is Underscore specifically.
Tools to confirm it
| Tool | What you do | What it reveals |
|---|---|---|
| View Source | Open the page source in your browser | underscore.min.js script tags and CDN paths |
| DevTools Console | Type _.VERSION and inspect _ | Confirms the global and prints the version |
| DevTools Console | Type typeof _.pluck | function strongly suggests Underscore over Lodash |
| DevTools Network | Filter requests by underscore | Shows the library file loading from a CDN or bundle |
| Wappalyzer | Run the browser extension on the page | Flags Underscore.js in the JavaScript libraries category |
| BuiltWith | Enter the domain on the BuiltWith site | Reports current and historical Underscore detection |
For a broader walkthrough of identifying any front-end dependency, see our guide on how to check what JavaScript libraries a website uses and the general primer on how to find out what technology a website uses.
Key Features
Underscore's value lies in the breadth and consistency of its helper functions.
- Collection helpers.
map,filter,reduce,each,find,groupBy,sortBy, and more that work uniformly on arrays and objects. - Array utilities.
uniq,flatten,intersection,difference,zip,first, andlastfor working with ordered data. - Object utilities.
extend,pick,omit,defaults,clone,keys,values, andisEqualfor manipulating plain objects. - Function helpers.
debounce,throttle,memoize,bind,partial, andoncefor controlling function execution. - Chaining.
_.chain(...).value()for expressing fluent, multi-step data pipelines. - Micro-templating.
_.templatefor compiling simple HTML templates with interpolation and embedded logic. - No prototype pollution. All functions live on the
_namespace and never modify built-in objects. - Tiny and dependency-free. A small footprint with no external dependencies of its own.
Three features stand out for the role Underscore played historically. Its function helpers (debounce and throttle in particular) solved real performance problems for scroll and resize handlers long before such utilities were common, and those exact names are now part of the shared front-end vocabulary. Its isEqual deep comparison offered reliable structural equality at a time when JavaScript had no native equivalent. And _.template quietly powered the rendering layer of a generation of Backbone applications, which is one reason the two libraries are so often found together.
Pros and Cons
Underscore's trade-offs reflect both its strengths as a pioneer and its age relative to newer options.
Pros
- Comprehensive, consistent utility API that smooths over gaps in older JavaScript.
- Functional and side-effect free, making code predictable and testable.
- Does not pollute native prototypes, avoiding conflicts.
- Very small footprint with no dependencies.
- Proven, stable, and well documented after many years in production.
Cons
- Much of its functionality is now native to modern JavaScript (
Array.prototype.map,filter,find,Object.entries, spread syntax). - Lacks Lodash's lazy evaluation, modular per-function imports, and some advanced helpers.
- The whole library is typically loaded as one file, which is less tree-shakeable than modern alternatives.
- Largely in maintenance mode; the ecosystem energy has shifted to Lodash and native methods.
- Sharing the
_global with Lodash can cause confusion when auditing a page.
Underscore.js vs Alternatives
Underscore competes with Lodash and, increasingly, with the native JavaScript standard library. The table frames the practical differences.
| Option | Footprint | Modularity | Lazy evaluation | Notes |
|---|---|---|---|---|
| Underscore.js | Small, single file | Limited | No | The original utility belt; Backbone dependency |
| Lodash | Larger, modular | Per-function imports | Yes | Underscore-inspired; richer and faster |
| Native JS (ES2015+) | Zero (built in) | N/A | No | Covers most simple cases; no install needed |
| Ramda | Medium | Modular | No | Functional-first, auto-currying, immutable focus |
The most useful comparison is Underscore versus Lodash, because the two are so closely related. Lodash began as an Underscore-compatible alternative and then surpassed it: it added lazy evaluation in chains (so long pipelines short-circuit efficiently), per-function imports for smaller bundles, and a deeper set of helpers with more consistent edge-case handling. For most teams that still want a utility library, Lodash became the default. The other major shift is toward native JavaScript: methods like Array.prototype.map, filter, find, Object.keys, Object.entries, and spread syntax now cover the simple cases Underscore was created for, which is why many modern projects use no utility library at all. Underscore's enduring relevance is largely as a dependency of legacy Backbone applications and as the historical root of the whole category.
If you are analyzing an older application, recognizing Underscore usually means recognizing the framework it supports; see our profile of Backbone.js, which depends on Underscore directly, and our profile of Lodash for the modern successor.
Use Cases
Underscore appears in a recognizable set of situations, most tied to older or dependency-driven code.
- Backbone.js applications. The single most common reason Underscore appears, since Backbone requires it as a dependency.
- Legacy data manipulation. Older codebases that lean on Underscore's collection and object helpers for filtering, grouping, and transforming data.
- Cross-browser support for older targets. Applications that needed consistent iteration and utility behavior before native methods were universally available.
- Simple client-side templating. Early apps that used
_.templateto render markup before adopting a dedicated framework. - Maintenance and migration projects. Teams keeping existing code running or migrating from Underscore to Lodash or native JavaScript.
For competitive research and lead generation, detecting Underscore (especially alongside Backbone) is a useful indicator of an older web stack, which can signal modernization opportunities or technical debt in a prospect's application.
Frequently Asked Questions
What is the difference between Underscore.js and Lodash?
They are close relatives. Lodash started as an Underscore-compatible drop-in replacement and then added lazy evaluation, modular per-function imports, more helper functions, and more consistent handling of edge cases. Both use the _ global, which can make them hard to tell apart at a glance. A quick test in the console is checking for _.pluck: it exists in Underscore but was removed from Lodash, so its presence strongly suggests Underscore.
Do I still need Underscore.js in modern JavaScript?
For most simple cases, no. Modern JavaScript has native map, filter, reduce, find, Object.keys, Object.entries, and spread syntax that cover much of what Underscore originally provided. You may still reach for a utility library for deep equality, debounce and throttle, or grouping helpers, but many teams choose Lodash or write small helpers instead of adding Underscore to a new project.
Why do so many sites load Underscore.js alongside Backbone.js?
Because Backbone.js depends on Underscore.js. Backbone uses Underscore's iteration and utility functions internally, particularly for its collection methods, so any page running Backbone will almost always load Underscore as well. If you see both window._ and window.Backbone defined in the console, the _ is Underscore specifically.
How do I check the Underscore.js version on a website?
Open the browser DevTools Console and type _.VERSION. Underscore exposes this property directly and returns a string such as 1.13.6. You can also inspect the script filename in View Source or the Network tab, since CDN URLs frequently include the version number in the path. Be aware that Lodash also exposes _.VERSION, so combine this check with a test like typeof _.pluck to confirm which library you are looking at.
Is Underscore.js still maintained?
Underscore is stable and receives occasional maintenance, but it is no longer where most utility-library innovation happens. The broader community has shifted toward Lodash and native JavaScript methods. For existing applications, Underscore remains reliable; for new work, it is rarely the first choice.
Can Underscore.js and Lodash both be present on the same page?
Yes, and it is a common source of confusion when auditing a site. Both libraries claim the _ global, so whichever loads last typically wins that name, while the other may still be present in a bundle under a different reference. If you suspect both are involved, inspect the loaded JavaScript files in the Network tab for underscore and lodash filenames, and test distinguishing methods in the console (for example _.pluck for Underscore versus Lodash-only helpers). Build tools sometimes bundle one as a transitive dependency even when the application author intended the other.
Want to identify the JavaScript libraries and full technology stack behind any website instantly? Try StackOptic at https://stackoptic.com.
Alternatives to Underscore.js
Compare Underscore.js
Analyze a Website
Check if any website uses Underscore.js and discover its full technology stack.
Analyze Now