Lodash _.flow() Method

Beginner
⏱️ 8 min read
📚 Updated: Jul 2026
🎯 6 Examples + 3 Try It
Util utilities

What You’ll Learn

By the end of this tutorial, you’ll chain small functions into one pipeline with Lodash’s _.flow(), running steps left to right.

01

Core Syntax

_.flow(f, g, h) or an array of functions.

02

Left to Right

Output of each step feeds the next.

03

First Step Args

Only the first function gets all call arguments.

04

String Pipelines

Trim, lowercase, and normalize text.

05

Data Transforms

Parse JSON, filter, aggregate.

06

vs flowRight

Know when direction reverses.

What Is _.flow()?

_.flow() is a Lodash util helper for function composition. You supply two or more functions; Lodash returns a new function that runs them in sequence. The return value of step one becomes the input to step two, and so on— like a conveyor belt moving data through transforms.

💡
Beginner tip — read left to right

_.flow(double, square, subtractTen)(5) means: start with 5, run double, then square, then subtractTen. It is equivalent to subtractTen(square(double(5))).

Composition keeps each step small and testable. Instead of one long function with ten lines of logic, you name each step and wire them with _.flow().

📝 Syntax

Pass functions as variadic arguments or inside one array:

javascript
_.flow([funcs])
// or
_.flow(funcs)

Syntax Rules

  • funcs — one or more functions, or a single array of functions.
  • Order — left to right: first listed function runs first.
  • Return value — a new composed function you call later.
  • First call — all arguments go to the first function only.
  • Later steps — each receives one value (previous return).
javascript
import flow from "lodash/flow";

const double = (x) => x * 2;
const square = (x) => x * x;
const subtractTen = (x) => x - 10;

const pipeline = flow(double, square, subtractTen);

pipeline(5);
// double(5) -> 10, square(10) -> 100, subtractTen(100) -> 90

⚡ Quick Reference

TaskCode patternEquivalent
Compose three fns_.flow(f, g, h)h(g(f(x)))
Array form_.flow([f, g, h])Same as variadic
Call pipelinepipeline(input)Runs left to right
Reverse order_.flowRight(f, g, h)f(g(h(x)))
With partial_.flow(_.partial(fn, 2), g)Fix early args
Identity start_.flow(_.identity, f)Pass-through first
Direction
L → R

First fn runs first

Returns
Function

Composed pipeline

Opposite
flowRight

Right to left

Category
Util

Composition

🧰 Parameters

How arguments work in a _.flow() pipeline:

funcs Required

Functions to compose, passed individually or as one array. At least one function is required for a meaningful pipeline.

_.flow(trim, lower, slug)
first function Multi-arg OK

Receives every argument from the outer call: pipeline(a, b) invokes first(a, b).

_.flow(add, double)(3, 4)
later functions Unary

Each subsequent step gets one value—the return of the prior step. Binary ops like (a,b) => a - b break unless you curry or partial first.

_.flow(f, g, h)(x)
return value Function

The composed function’s return value is whatever the last step returns.

const run = _.flow(steps)

For multi-argument math on two numbers, either keep everything in the first function or use _.partial() to bake in arguments before flow.

Examples Gallery

Practical _.flow() patterns with copy-ready code, sample output, and interactive Try It Yourself labs.

📚 Getting Started

Build a numeric pipeline and trace each step.

Example 1 — Numeric pipeline

Double, square, then subtract ten—composed left to right.

javascript
const double = (x) => x * 2;
const square = (x) => x * x;
const subtractTen = (x) => x - 10;

const pipeline = _.flow(double, square, subtractTen);

console.log(pipeline(5));
// 5 -> 10 -> 100 -> 90
Try It Yourself

How It Works

pipeline(5) expands to subtractTen(square(double(5))). Order matters: swapping steps changes the result entirely.

Example 2 — String cleanup pipeline

Trim whitespace, lowercase, then remove spaces for a slug-like token.

javascript
const trim = (str) => str.trim();
const toLower = (str) => str.toLowerCase();
const removeSpaces = (str) => str.replace(/\s+/g, "");

const normalize = _.flow(trim, toLower, removeSpaces);

const input = "   Hello World   ";
console.log(normalize(input)); // "helloworld"
Try It Yourself

How It Works

Each step is a unary string transform. The pipeline reads top-to-bottom in the order you list functions—natural for text processing.

📈 Practical Patterns

JSON analytics, pure arithmetic, and explicit nesting equivalents.

Example 3 — Parse JSON, filter, average

Turn a JSON string into the average of positive numbers.

javascript
const parseJSON = (json) => JSON.parse(json);
const keepPositive = (arr) => arr.filter((n) => n > 0);
const average = (arr) =>
  arr.reduce((sum, n) => sum + n, 0) / arr.length;

const statsFromJson = _.flow(parseJSON, keepPositive, average);

console.log(statsFromJson("[1, 2, 3, -4, 5]"));
// (1 + 2 + 3 + 5) / 4 = 2.75
Try It Yourself

How It Works

Wrap risky JSON.parse in the first step—or pair with _.attempt() if input may be invalid. Later steps assume an array.

Example 4 — Pure unary transforms

Small arithmetic steps with no shared state—easy to test in isolation.

javascript
const inc = (x) => x + 1;
const double = (x) => x * 2;
const dec = (x) => x - 3;

const transform = _.flow(inc, double, dec);

console.log(transform(5));
// inc(5)=6, double(6)=12, dec(12)=9

How It Works

Pure functions (no mutation, same input → same output) compose predictably. Debug by testing each step, then the full flow.

Example 5 — Equivalent nested calls

See how flow desugars into nested function calls.

javascript
const f = (x) => x + 2;
const g = (x) => x * 3;
const h = (x) => x - 1;

const piped = _.flow(f, g, h);
const nested = (x) => h(g(f(x)));

console.log(piped(4));  // h(g(f(4))) = h(18) = 17
console.log(nested(4)); // 17

How It Works

_.flow(f, g, h)(x) always equals h(g(f(x))) for unary functions. Flow names the pipeline; nesting inlines it.

🚀 Beyond the Basics

Compare direction with flowRight and know what not to do.

Example 6 — flow vs flowRight

Same three functions, opposite evaluation order.

javascript
const f = (x) => x + 1;
const g = (x) => x * 2;
const h = (x) => x - 1;

console.log(_.flow(f, g, h)(5));
// f(5)=6, g(6)=12, h(12)=11  — left to right

console.log(_.flowRight(f, g, h)(5));
// h(5)=4, g(4)=8, f(8)=9   — right to left

When to prefer flow

Use _.flow() when you read transforms in data order (parse → filter → map). Use _.flowRight() when you think in mathematical compose (inner function first).

🧠 How _.flow() Works

1

Collect functions

Lodash flattens variadic args or uses the array you pass in.

Setup
2

Return composed fn

The new function closes over the ordered list of steps.

Factory
3

Run left to right

On call, invoke the first fn with all args, then pipe each return to the next.

Execute
=

Final return value

Whatever the last function returns becomes the pipeline result.

📝 Notes

  • Only the first function receives multiple arguments from pipeline(a, b).
  • Steps after the first should be unary—one input, one output.
  • Order matters: _.flow(f, g) is not the same as _.flow(g, f).
  • _.flow() is for composing return-value functions—not Express (req, res, next) middleware.
  • Handle errors in individual steps; flow does not add try/catch between steps.
  • Next in the series: _.flowRight() for right-to-left composition.

Conclusion

_.flow() turns a list of small functions into one reusable pipeline that runs left to right. Name each transform, compose them once, and call the result anywhere you need that sequence.

Keep steps unary after the first, verify order with nested-call equivalents, and switch to _.flowRight() when compose-style right-to-left fits better.

💡 Best Practices

✅ Do

  • Write one responsibility per function (trim, parse, filter)
  • Order steps in the sequence data actually flows
  • Test each step alone, then the composed pipeline
  • Use array form when building the list dynamically
  • Pair with _.partial when an early step needs fixed args

❌ Don’t

  • Chain binary math ops after the first step without currying
  • Assume flow works like Express middleware arrays
  • Hide side effects inside steps without documenting them
  • Swap order casually—results change completely
  • Build huge pipelines when a plain function reads clearer

Key Takeaways

Knowledge Unlocked

Five things to remember about _.flow()

Use these points when composing function pipelines.

5
Core concepts
🔀 02

Pipe value

Output → next input.

Mechanics
📝 03

Unary steps

After first function.

Pitfall
📈 04

Pipelines

Strings & JSON.

Practical
05

flowRight

Reverse direction.

Next step

❓ Frequently Asked Questions

_.flow() takes one or more functions and returns a new composed function. When you call it, the first function runs with your arguments; each later function receives the return value of the previous one. Execution order is left to right.
Pass them as separate arguments (_.flow(f, g, h)) or as one array (_.flow([f, g, h])). Both forms work in Lodash 4.
Only the first function in the pipeline receives all arguments from the outer call. Every subsequent function receives a single value—the previous function's return value. Design steps after the first as unary functions.
_.flow() composes left to right (f then g then h). _.flowRight() composes right to left (h then g then f)—like mathematical compose. flow reads naturally for data pipelines; flowRight matches compose notation.
No. Express middleware chains use (req, res, next) signatures and side effects. _.flow() composes unary (or first-step multi-arg) functions that return values—better for pure transforms than HTTP middleware wiring.
Use it when you have a fixed sequence of small transforms—string cleanup, number mapping, JSON parse-then-filter—and want one reusable function instead of nested calls like h(g(f(x))).
Did you know?

_.flow(f, g, h)(x) is the same as h(g(f(x))) for unary functions—the same direction as reading the functions left to right in the flow call. _.flowRight reverses that order to match mathematical compose notation.

Practice _.flow() in the Live Editor

Open the Try It editor, run the examples, and build your own left-to-right pipelines.

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