What is currying?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
Currying transforms a function of several arguments into a chain of functions that each take exactly one, so f(a, b, c) becomes f(a)(b)(c). Every call in the chain returns another function until the last one, which returns the result.
const add = (a) => (b) => (c) => a + b + c;
add(1)(2)(3); // 6
const add1 = add(1); // a function waiting for b
const add1and2 = add1(2);
add1and2(3); // 6
It works because of closures: each returned function keeps the arguments captured by the ones before it.
Writing a generic curry
You rarely nest arrows by hand. A helper collects arguments until it has enough:
function curry(fn) {
return function curried(...args) {
return args.length >= fn.length
? fn(...args)
: (...rest) => curried(...args, ...rest);
};
}
const volume = curry((l, w, h) => l * w * h);
volume(2)(3)(4); // 24
volume(2, 3)(4); // 24 — this flexibility is why libraries call it "curry"
Note fn.length counts declared parameters, so it does not work with default or rest parameters — a common gotcha when currying arbitrary functions.
Why anyone does this
The point is building specialised functions from general ones without repeating yourself, and making functions easy to compose since each step takes and returns a single value:
const prop = curry((key, obj) => obj[key]);
const getName = prop("name");
users.map(getName);
Putting the data argument last is what makes this work, which is why functional libraries such as Ramda order parameters that way.
Be honest about the cost
Every call allocates a closure, and add(1)(2)(3) is harder for most teams to read than add(1, 2, 3). In everyday JavaScript a plain function or a single bind usually communicates better. Currying earns its place in heavily functional codebases and in pipelines where composition is the main idea.
