Lodash Seq — sequence & chaining

Beginner
⏱️ 10 min read
📚 Updated: Jul 2026
🎯 3 Code examples
Lodash

What you’ll learn

  • What to know before you start (see Prerequisites).
  • How _.chain() and _(value) wrap data for fluent pipelines.
  • When to use _.tap() (side effects) versus _.thru() (transform).
  • Why .value() is required to unwrap a chain and get a plain result.
  • Where each Seq method maps on this site (/lodash/seq/...).

Prerequisites

Comfort with _.map(), _.filter(), and other Lodash helpers you plan to chain. Optional familiarity with Object methods when pipelines reshape plain objects.

  • Method chaining concept: each step receives the output of the previous step (or the same value for tap).
  • Lodash imports: chaining requires the full wrapper—typically import _ from "lodash" or import chain from "lodash/chain" plus related methods.
  • Return values: know whether a Lodash method mutates in place or returns a new value—both work in chains but affect debugging.

Key concepts

Lodash Seq is about how you call other Lodash methods—not a separate data type. A wrapper holds your value, exposes chainable versions of helpers, and waits for .value() before returning plain JavaScript data.

Wrapper object

_.chain(x) returns a Lodash wrapper—not the transformed data until you unwrap.

Fluent pipeline

Read top-to-bottom: map, filter, pick, groupBy—each step feeds the next.

tap vs thru

tap for logging or metrics; thru when the step must change the value type.

Unwrap

.value() terminates the chain and returns the final result.

Overview

Seq methods sit at the edges of a pipeline—starting a chain, peeking with side effects, or routing through a custom function—while Array, Collection, and Object methods do the heavy data work in the middle.

Start

_.chain or _(value) wraps input once.

Observe

tap logs or records metrics without altering flow.

Transform

thru plus any chainable Lodash method in between.

⚖️ Chaining vs plain Lodash calls

Lodash chaining reads well for multi-step data pipelines. For one or two operations, nested calls or native array methods are often shorter and tree-shake more easily.

SituationPrefer plain callsConsider chaining
Single map or filter_.filter(_.map(x, fn), pred)Usually unnecessary
3+ sequential Lodash stepsNested calls get hard to read_.chain(x).map(...).filter(...).value()
Debug logging mid-pipelineTemp variables.tap(v => console.log(v))
Custom transform between stepsAssign to a variable.thru(arr => ...)
Bundle size mattersPer-method importsFull lodash or chain bundle often larger
1

Install and import

Chaining typically imports the main Lodash entry or chain plus the methods you call in the pipeline.

Terminal
npm install lodash
javascript
import _ from "lodash";

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

const result = _.chain(data)
  .map(function (x) { return x * 2; })
  .filter(function (x) { return x > 5; })
  .value();

// result -> [6, 8, 10]
2

tap and thru in a chain

tap inspects without changing the value; thru replaces it with the function return value.

javascript
const users = [
  { name: "Ada", active: true },
  { name: "Bob", active: false }
];

const names = _.chain(users)
  .filter("active")
  .tap(function (list) { console.log("active count:", list.length); })
  .thru(function (list) { return _.map(list, "name"); })
  .value();

// names -> ["Ada"]
3

Unwrap with .value()

Without .value(), you hold a wrapper object—not the array or object you expect.

javascript
const wrapped = _.chain([1, 2, 3]).map(function (n) { return n + 1; });
console.log(Array.isArray(wrapped)); // -> false

const plain = wrapped.value();
console.log(plain); // -> [2, 3, 4]

🔄 Wrapper vs unwrapped results

Every chain step returns another wrapper until you call .value(), .valueOf(), or Symbol.iterator (for lazy next iteration).

CallReturnsRule of thumb
_.chain(x)WrapperStart of pipeline.
.map / .filter / ...WrapperChain continues.
.tap(fn)Wrapper (same inner value)Side effects only.
.thru(fn)Wrapper (new inner value)Value may change type.
.value()Plain JavaScript valueAlways finish here in app code.

Suggested learning path

Walk these in order once individual Seq tutorials are published on CodeToFun.

  1. Start wrapping: _.chain() and _(value) entry points.
  2. Build pipelines: chain map, filter, and pick in one fluent sequence.
  3. Side effects: _.tap() for logging; _.thru() for custom transforms.
  4. Unwrap: .value() and when to use .commit().
  5. Advanced wrapper: wrapper prototype methods (plant, next, reverse).

💻 Environment and versions

  • Lodash 4.x: the index below reflects the Seq surface shipped with lodash@^4.
  • Browsers & Node: chaining works identically; bundlers may pull a larger chunk when using _.chain.
  • TypeScript: wrapper types are loose—annotate final results after .value() when strict typing matters.

Top-level Seq methods

URLs follow /lodash/seq/{method-kebab} (for example /lodash/seq/chain).

MethodWhat it does
_.chain()Wrap a value in a Lodash sequence so collection/array/object methods chain fluently; finish with .value().
_.tap()Run a side-effect function on the current value, then pass the original value through unchanged.
_.thru()Pass the current value through a function and continue the chain with the return value.

Wrapper & prototype helpers

These live on the object returned by _.chain()—documented under /lodash/seq/prototype/... as tutorials are added.

MethodWhat it does
_(value) / lodash()Shorthand entry point—wrap a value the same way as _.chain() to start a sequence.
Wrapper prototypeMethods on the chain wrapper: value, commit, plant, next, reverse, and more.
_.value()Execute the chain and return the unwrapped result (alias valueOf).
_.commit()Execute pending chain actions and return the wrapper for hybrid chaining.
_.plant()Create a clone of the chain with a new wrapped value at the same pipeline stage.
_.next()Advance lazy iteration on wrapped sequences (iterator protocol).
_.reverse()Reverse the wrapped array in place inside the chain.
_.at()Apply a function at a specific index or path within the chain context.

Pitfalls to avoid

Unwrap

Forgetting .value()

A chain without .value() looks like data but is a wrapper—common source of “why isn’t this an array?” bugs.

Lazy myth

Expecting stream-style laziness

General _.chain pipelines run eagerly when unwrapped—they defer extraction, not infinite lazy evaluation.

Bundle

Importing all of Lodash for one chain

Per-method imports avoid wrapper overhead when you only need map and filter once.

❓ FAQ

Seq is Lodash's chaining category. _.chain(value) wraps data so you can call map, filter, pick, and other Lodash methods in a fluent pipeline, then unwrap with .value().
Both create a Lodash wrapper around a value. _.chain(value) is explicit; _(value) (or lodash(value)) is the shorthand entry point—they behave the same for starting a sequence.
Intermediate chain steps return a wrapper object, not the plain result. .value() (or .valueOf()) executes the pipeline and returns the underlying JavaScript value.
_.tap() runs a side-effect function but passes the original value onward. _.thru() passes the value through a function and continues the chain with whatever that function returns.
Not in the general sense. _.chain() defers unwrapping until .value(), but when you unwrap, the steps run eagerly. For huge datasets, prefer plain method calls or native iterators unless you specifically need wrapper features.
Chaining can improve readability for multi-step Lodash pipelines. For simple one-liners, direct calls like _.filter(_.map(x, fn), pred) or native array methods are often clearer and tree-shake better.

Summary

  • Scope: Seq is Lodash’s chaining layer—wrap, transform with other Lodash methods, unwrap with .value().
  • tap vs thru: observe without changing vs pass through a transforming function.
  • Next steps: open Lodash _.chain(), revisit _.valuesIn(), or pick any row in the index.
Did you know?

The most common chain bug is forgetting .value()_.chain([1,2,3]).map(n => n * 2) returns a wrapper object, not an array. Call .value() (or .valueOf()) to unwrap.

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.

9 people found this page helpful