Lodash Wrapper .chain() Method

Beginner
⏱️ 7 min read
📚 Updated: Jul 2026
🎯 6 Examples + 3 Try It
Seq & chaining

What You’ll Learn

By the end of this tutorial, you’ll use wrapper .chain() to switch into explicit chaining mode and keep methods like head() wrapped until you call .value().

01

Explicit mode

_(x).chain()

02

Hybrid vs explicit

When unwrap happens.

03

head + pick

Classic use case.

04

vs _.chain()

Entry vs mid-pipeline.

05

Pipeline steps

filter, map, take.

06

Unwrap

Finish with .value().

What Is Wrapper .chain()?

Wrapper .chain() switches a Lodash wrapper from hybrid chaining to explicit chaining. After you call it, every subsequent method returns another wrapper until you unwrap with .value()—even methods like head() that would normally return a plain value immediately.

💡
Not _.prototype.chain() or entry-point _.chain()

There is no _.prototype.chain() function. Wrapper .chain() is called on an existing wrapper: _(users).chain().head().pick('user').value(). That is different from _.chain(value), which wraps a value to start a pipeline.

Use wrapper .chain() when hybrid mode would unwrap too early—for example, when you need head() followed by pick(), or any pipeline where an “exit” method should stay chainable.

📝 Syntax

Call .chain() on a wrapper with no arguments:

javascript
_(value).chain()
// or mid-pipeline on an existing wrapper
_.chain(value).chain()

Syntax Rules

  • No arguments.chain() takes nothing; it toggles explicit mode on the current wrapper.
  • Return — another Lodash wrapper in explicit chaining mode.
  • Hybrid default — without .chain(), some methods auto-unwrap (head, first, last, etc.).
  • Must unwrap — end with .value() to get plain JavaScript data.
  • Entry point alternative_.chain(value) starts in explicit mode from the beginning.
javascript
import _ from "lodash";

const users = [
  { user: "barney", age: 36 },
  { user: "fred", age: 40 }
];

const firstUserName = _(users)
  .chain()
  .head()
  .pick("user")
  .value();

// firstUserName -> { user: "barney" }

⚡ Quick Reference

TaskCode patternResult
Enable explicit mode_(users).chain()Wrapper (explicit)
head then pick.chain().head().pick('user')Stays wrapped
Without .chain()_(users).head()Plain object (unwraps)
Start explicit_.chain(users)See _.chain()
Hybrid shorthand_(users).map(...)See _(value)
Finish chain... .value()Plain result
Explicit
.chain()

Force wrap mode

Hybrid
_(value)

Default unwrap

Unwrap
.value()

Plain result

🧰 Parameters

Wrapper .chain() takes no arguments and returns another wrapper in explicit mode:

(no args) Required

Call with empty parentheses on an existing wrapper to enable explicit chaining.

_(users).chain()
return (wrapper) Wrapper

Same wrapped value, but subsequent methods stay in wrapper mode until unwrap.

_(users).chain().head()
.value() result Plain

After the full pipeline, unwrap to get a plain object, array, or primitive.

.value() // -> { user: "barney" }
hybrid default Without .chain()

Methods like head() unwrap immediately unless explicit mode is on.

_(users).head() // plain object

Prefer _.chain(value) when the entire pipeline should be explicit from the start.

Examples Gallery

Practical wrapper .chain() patterns with sample output and interactive Try It Yourself labs.

📚 Getting Started

Enable explicit chaining with .chain(), then call methods that would otherwise unwrap.

Example 1 — head() then pick() with .chain()

The classic use case: get the first user, then pick one field—both steps stay wrapped.

javascript
const users = [
  { user: "barney", age: 36 },
  { user: "fred", age: 40 }
];

const result = _(users)
  .chain()
  .head()
  .pick("user")
  .value();

console.log(result);
// -> { user: "barney" }
Try It Yourself

How It Works

.chain() forces explicit mode so head() returns a wrapper (the first user object), letting you call .pick() on it.

Example 2 — Without .chain(), head() unwraps early

In hybrid mode, head() returns a plain object—you cannot chain pick() on it.

javascript
const users = [
  { user: "barney", age: 36 },
  { user: "fred", age: 40 }
];

const hybrid = _(users).head();
// -> { user: "barney", age: 36 }  (plain object, chain ended)

const explicit = _(users).chain().head().pick("user").value();
// -> { user: "barney" }

console.log(hybrid);
console.log(explicit);
Try It Yourself

📈 Practical Patterns

Multi-step pipelines, helper functions, and when to start explicit from the beginning.

Example 3 — filter, map, and take pipeline

Build a readable transformation pipeline with explicit chaining throughout.

javascript
const users = [
  { name: "Alice", age: 28, active: true },
  { name: "Bob", age: 17, active: true },
  { name: "Carol", age: 35, active: false },
  { name: "Dave", age: 42, active: true }
];

const names = _(users)
  .chain()
  .filter({ active: true })
  .filter(function (u) { return u.age >= 18; })
  .map("name")
  .take(2)
  .value();

console.log(names);
// -> ["Alice", "Dave"]

Example 4 — Helper functions in an explicit chain

Extract predicates and mappers for cleaner, testable pipeline steps.

javascript
const users = [
  { name: "Alice", age: 28 },
  { name: "Bob", age: 17 },
  { name: "Carol", age: 35 }
];

const isAdult = function (user) { return user.age >= 18; };

const adultNames = _(users)
  .chain()
  .filter(isAdult)
  .map("name")
  .value();

console.log(adultNames);
// -> ["Alice", "Carol"]

🚀 Beyond the Basics

Wrapper .chain() vs entry-point _.chain() and when each fits best.

Example 5 — Wrapper .chain() vs entry-point _.chain()

Both enable explicit mode—one toggles mid-pipeline, the other starts explicit from the wrap.

javascript
const users = [
  { user: "barney", age: 36 },
  { user: "fred", age: 40 }
];

const midPipeline = _(users).chain().head().pick("user").value();

const fromStart = _.chain(users).head().pick("user").value();

console.log(JSON.stringify(midPipeline) === JSON.stringify(fromStart));
// -> true
Try It Yourself

Example 6 — When to skip wrapper .chain()

If the whole pipeline should be explicit, start with _.chain(value) instead of adding .chain() after _(value).

javascript
const data = [1, 2, 3, 4, 5];

// Redundant .chain() after _.chain() entry — both are explicit
const redundant = _.chain(data).chain().map(function (x) { return x * 2; }).value();

// Cleaner: _.chain() already starts explicit mode
const clean = _.chain(data).map(function (x) { return x * 2; }).value();

console.log(JSON.stringify(redundant) === JSON.stringify(clean));
// -> true

🧠 How Wrapper .chain() Works

1

Start with a wrapper

Begin from _(value) or any existing Lodash wrapper in hybrid mode.

Input
2

Call .chain()

Lodash re-wraps the current value and enables explicit chaining—exit methods no longer auto-unwrap.

Explicit
3

Chain more methods

Call head, pick, filter, etc.—each returns another wrapper until unwrap.

Pipeline
=

Unwrap when done

.value() runs the pipeline and returns plain JavaScript data—same as any other Lodash chain.

📝 Notes

  • There is no _.prototype.chain() function—the correct name is wrapper .chain() on a sequence object.
  • Wrapper .chain() is not the same as entry-point _.chain(value)—different purpose, same explicit mode.
  • Hybrid chaining (default with _(value)) auto-unwraps methods like head, first, last, and value.
  • If your entire pipeline needs explicit mode, start with _.chain(value) instead of adding .chain() after wrap.
  • Always end with .value() to get the final plain result in application code.
  • Next in the series: .commit() runs pending steps eagerly while keeping the wrapper.

Conclusion

Wrapper .chain() switches a Lodash wrapper into explicit chaining mode so methods like head() stay wrapped and you can keep building the pipeline. It solves the hybrid unwrap problem—especially the classic head().pick() pattern.

Next in the wrapper prototype series: .commit(), which executes pending chain actions eagerly while returning the wrapper for more steps.

💡 Best Practices

✅ Do

  • Use wrapper .chain() when hybrid mode unwraps before you are done chaining
  • Prefer _.chain(value) when the whole pipeline should be explicit
  • Extract helper functions for filter/map predicates in long pipelines
  • Keep pipelines readable—break very long chains into named steps
  • Always call .value() before passing results to non-Lodash code

❌ Don’t

  • Confuse wrapper .chain() with entry-point _.chain(value)
  • Call it _.prototype.chain()—that name does not exist in Lodash
  • Add redundant .chain() after _.chain(value)—already explicit
  • Chain excessively when two direct Lodash calls would be clearer
  • Forget that hybrid _(value).head() unwraps without .chain()

Key Takeaways

Knowledge Unlocked

Five things to remember about wrapper .chain()

Use these when hybrid chaining unwraps too early.

5
Core concepts
🔄 02

Hybrid default

Auto-unwraps.

Contrast
👤 03

head + pick

Classic pattern.

Use case
🚀 04

vs _.chain()

Mid vs start.

Compare
📦 05

Always unwrap

.value() required.

Critical

❓ Frequently Asked Questions

On an existing Lodash wrapper, .chain() enables explicit chaining. Subsequent methods stay wrapped until you call .value(), even methods like head() that would normally unwrap in hybrid mode.
No. _.chain(value) is the entry-point that wraps a value to start a pipeline. Wrapper .chain() is called on an already-wrapped value to switch from hybrid to explicit chaining mid-pipeline.
When you want to call a method that would auto-unwrap (like head, first, last, tap in some cases) and then continue chaining more Lodash methods on the result.
In hybrid mode, _(users).head() unwraps immediately and returns a plain object—you cannot call .pick() on it. Add .chain() to keep head()'s result wrapped.
No. Call it with no arguments: _(value).chain(). It re-wraps the current value in explicit chaining mode.
Yes. Explicit chaining still returns a wrapper for each step until you unwrap with .value() or .valueOf().
Did you know?

Lodash has two chaining modes: hybrid (default with _(value)) and explicit (after wrapper .chain() or entry-point _.chain(value)). In hybrid mode, _(users).head() returns a plain object immediately—add .chain() first if you need to keep chaining.

Practice Wrapper .chain() in the Live Editor

Compare hybrid vs explicit chaining and build head + pick pipelines instantly.

Open Try It editor →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful