Currying transforms a function that takes multiple arguments into a sequence of functions that each take a single argument. It enables powerful partial application patterns used throughout functional-style JavaScript.
1Currying (Introduction) | JavaScript Tutorial - In-Depth Guide Part 1
Currying turns 'f(a, b, c)' into 'f(a)(b)(c)' — a chain of single-argument functions, each returning the next until all arguments are collected.
function add(a) {
return (b) => a + b;
}
add(2)(3); // 5One at a Time
2Currying (Introduction) | JavaScript Tutorial - In-Depth Guide Part 2
Partial application means fixing some arguments now and getting a specialized function back for the rest — currying is one way to achieve it.
const add2 = add(2); // partially applied
add2(10); // 12
add2(20); // 22Partial Application
3Currying (Introduction) | JavaScript Tutorial - In-Depth Guide Part 3
A generic 'curry' utility can transform any regular multi-argument function into its curried form automatically.
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) return fn(...args);
return (...more) => curried(...args, ...more);
};
}Generic curry()
4Currying (Introduction) | JavaScript Tutorial - In-Depth Guide Part 4
A curried function stays flexible about how arguments are grouped — you can supply them one at a time, or several at once.
const curriedAdd3 = curry((a, b, c) => a + b + c);
curriedAdd3(1)(2, 3); // 6
curriedAdd3(1, 2)(3); // 6Flexible Grouping
5Currying (Introduction) | JavaScript Tutorial - In-Depth Guide Part 5
Currying is most useful for pre-configuring reusable, composable functions — like creating a family of specialized validators or formatters from one general one.
const matchesRegex = curry((pattern, input) => pattern.test(input));
const isEmail = matchesRegex(/^[^@]+@[^@]+$/);
isEmail('a@b.com'); // trueReusable Specializations
6Step-by-Step Breakdown
Currying turns 'f(a, b, c)' into 'f(a)(b)(c)' — a chain of single-argument functions, each returning the next until all arguments are collected.
Partial application means fixing some arguments now and getting a specialized function back for the rest — currying is one way to achieve it.
Checkpoint: When you call add(2), does it immediately compute a sum?
- →Yes, it returns 2 plus some default
- →No, it returns a new function waiting for the next argument
A generic 'curry' utility can transform any regular multi-argument function into its curried form automatically.
A curried function stays flexible about how arguments are grouped — you can supply them one at a time, or several at once.
Checkpoint: Does a generic curry() utility require arguments to be passed strictly one at a time?
- →Yes, exactly one argument per call
- →No, it can accept several arguments per call until enough are collected
Currying is most useful for pre-configuring reusable, composable functions — like creating a family of specialized validators or formatters from one general one.
Next, we'll explore 'Memoization'.
Level Up 🚀
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Curried Validators Improve Consistency of Accessible Error Messaging
Building a library of curried, reusable validation functions (isRequired, minLength(3)) ensures every form field in an app produces consistent, predictable error messages that can reliably be wired to aria-describedby.
SEO Implications
- 1
No Direct SEO Effect
Currying is a code-organization technique; its only relevant effect on SEO is indirect, through more consistent, reusable validation and formatting logic reducing the odds of malformed rendered content.
Best Practices
Use Currying to Build Named, Reusable Specializations
Instead of repeating a validator or formatter's configuration everywhere it's used, curry it once and export named, pre-configured versions (isEmail, isPhoneNumber) for reuse.
Reserve Currying for Functions That Genuinely Benefit From Partial Application
Not every multi-argument function needs to be curried — apply it where it enables real reuse or composition, not as a blanket style choice that adds indirection without benefit.
Frequent Bugs
Currying a function that uses rest parameters (`...args`) or default parameters, whose `fn.length` does not reflect the real number of expected arguments, causing a generic curry() utility to invoke it too early.
Generic curry utilities rely on Function.length, which excludes rest/default parameters — either avoid currying such functions automatically, or specify the intended arity explicitly to the curry helper.
Assuming a curried function called with fewer arguments than expected will throw, when it actually just returns another function silently.
Remember a curried function's job is to return a waiting function until enough arguments arrive — if a caller forgets an argument, they get a function back instead of a runtime error, which can hide the mistake.
Real-World Examples
Curried Validators for a Form Library
A form validation library needed many small, reusable, composable validators driven by different configuration values.
const minLength = curry((min, value) => value.length >= min);
const isStrongPassword = minLength(8);
isStrongPassword('short'); // false
isStrongPassword('longenough'); // true