Currying in JavaScript

Published: (February 5, 2026 at 06:07 AM EST)
2 min read
Source: Dev.to

Source: Dev.to

What is Currying?

Currying is a functional‑programming technique that transforms a function with multiple parameters into a sequence of functions, each accepting a single argument:

f(a, b, c)   →   f(a)(b)(c)

It relies heavily on closures: every nested function retains access to the arguments supplied in previous calls, allowing values to be accumulated until all required parameters are available. Once the expected number of arguments is collected, the original function executes and returns the final result.

Simple Example

function orderCoffee(type) {
  return function (size) {
    return function (milk) {
      return `You selected ${type} ${size} with ${milk}`;
    };
  };
}

const orderOne   = orderCoffee('Latte')('Medium')('Almond milk');
const orderTwo   = orderCoffee('Americano')('Large')('No milk');
const orderThree = orderCoffee('Mocha')('Medium')('Almond milk');

console.log(orderOne);   // You selected Latte Medium with Almond milk
console.log(orderTwo);   // You selected Americano Large with No milk
console.log(orderThree); // You selected Mocha Medium with Almond milk

Each call captures one piece of information and returns a new function that waits for the next input.

How It Works Internally

  1. First callorderCoffee('Latte')
    Returns a function that expects size. The type ('Latte') is remembered via closure.

  2. Second callorderCoffee('Latte')('Medium')
    Returns a function that expects milk. Both type and size are now stored.

  3. Third callorderCoffee('Latte')('Medium')('Almond milk')
    Returns the final string, using all three captured values.

Arrow‑Function Version

Arrow functions make the same pattern look more concise:

const orderCoffee = (type) => (size) => (milk) =>
  `You selected ${type} ${size} with ${milk}`;

const order = orderCoffee('Latte')('Medium')('Almond milk');
console.log(order); // You selected Latte Medium with Almond milk

Step‑by‑Step Breakdown

StepExpressionReturns
1orderCoffee('Latte')Function waiting for size
2orderCoffee('Latte')('Medium')Function waiting for milk
3orderCoffee('Latte')('Medium')('Almond milk')Final string "You selected Latte Medium with Almond milk"

Why Use Currying?

  • Reusability – Create partially applied functions that can be reused with different remaining arguments.
  • Readability – Break complex calls into smaller, intention‑revealing steps.
  • Composition – Works well with other functional techniques like function composition and pipelines.

Conclusion

Currying breaks a multi‑parameter function into a chain of single‑parameter functions, leveraging closures to remember earlier arguments. This pattern can simplify code, promote reuse, and fit naturally into a functional programming style in JavaScript.

Back to Blog

Related posts

Read more »

Replace Turbo confirm with native dialog

Rails, when using turbo‑links, ships with a built‑in confirmation dialog for destructive actions. You've probably used it countless times: erb The default turbo...