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.
Fundamentals
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().
Foundation
📝 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).
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
📤 Console output:
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
📤 Console output:
17
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
📤 Console output:
11
9
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).
Compare
📋 _.flow vs related patterns
Topic
_.flow
_.flowRight
Nested calls
_.chain
Direction
Left → right
Right → left
Manual order
Method chain
Returns
Composed fn
Composed fn
Inline value
Wrapper object
Best for
Data pipelines
Compose notation
One-off calls
Lodash methods on data
Purity
Small pure fns
Same
Same
May mutate (tap)
Express middleware
Not equivalent
Not equivalent
N/A
N/A
🧠 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.
Important
📝 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.
Wrap Up
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.
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
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about _.flow()
Use these points when composing function pipelines.
5
Core concepts
→01
L → R
First fn runs first.
Basics
🔀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.