Blog

Reusable JavaScript Functions Across Make Scenarios: One Function, Many Scenarios

Updated October 2026

Make has no built-in way to share a piece of JavaScript between scenarios below the Enterprise plan: the Code app keeps each script inside its own module, and Make's Custom Functions, which do share code across a team, are Enterprise-only and capped at 300 ms with no network access. The working option on any Make plan is a stored function: write the JavaScript once in CustomJS, give it named parameters, and call it from every scenario that needs it with the Execute Stored Function module.

This guide shows one stored function, priceQuote, called from three scenarios with different parameters: a webhook intake, a CRM sync and a nightly report. It also says when a stored function is overkill. The Make limits quoted here were checked against Make's documentation on October 7, 2026.

TL;DR

  • A Make Code module stores its script inside that module. Reuse means copy-paste or a blueprint export. There is no shared library.
  • Make Custom Functions do share code, but only on Enterprise, and limited to 300 ms, 5,000 characters, synchronous code, no HTTP and no libraries.
  • A CustomJS stored function is written once, has named parameters, is versioned, and is called by name from any number of scenarios, on every plan including free.
  • Move code out of a scenario when you paste a snippet a second time, apply a fix twice, pass about 40 lines, or need an npm package or an async HTTP call.
  • Test the function once with sample parameters in the editor, then wire the scenarios to it. A later fix reaches all of them on their next run.

Why can't I share code between Make scenarios?

Because Make's native code options were built for one scenario at a time. The Code app (JavaScript and Python, open beta, paid Make plans only) is a module like any other: its script lives in the module's settings. If two scenarios need the same logic, each holds its own copy. The only transport is copy-paste or a blueprint export, and a blueprint moves a whole scenario, not one function. When you later fix a bug, you fix it once per copy, and you have to remember where the copies are.

Make Custom Functions deserve a fair description. They live in a Functions section at the team level, every team member can use them in the mapping panel of any scenario, every save creates a history record you can compare and restore, and there is a debug console under the editor. That is a real shared library. The catch is the fence around it, checked on October 7, 2026 at help.make.com/custom-functions: Enterprise plan only, no more than 300 milliseconds per call, no more than 5,000 characters of code, synchronous only, no HTTP requests, no third-party libraries, no recursion, no calling one custom function from another. Good for a short pure formula, unusable for anything that fetches, waits or imports.

So no plan below Enterprise has a sharing mechanism, and the Enterprise mechanism cannot run the code most people want to share. A stored function fills that gap from outside Make.

When should I move inline code to a stored function?

Inline code is the right default. The Execute Inline JavaScript module keeps the snippet next to the scenario that uses it, and most snippets never need more than that. Four signals say it is time to move the code out:

  • You paste the same snippet into a second scenario. Two copies are two places to fix. Three is a maintenance problem.
  • You had to apply one fix twice. If you ever searched your scenarios for "where else did I use this", that was the moment.
  • The script passes about 40 lines. The module's code field is a plain text box. Past 40 lines, missing braces cost more time than opening a real editor.
  • The script needs an npm package or an async HTTP call. These are the scripts you least want duplicated, because a changed endpoint then has to be changed everywhere.

Our usage data backs the fourth signal. Across stored functions on the platform, 39% make an HTTP call, 40% use async, and 30% import an npm package. The median stored function is 110 lines long, and a request can run up to 60 seconds on paid plans (30 seconds on free). None of that fits a 300 ms, 5,000 character, no-network box.

How does a stored function work in Make?

You write the function in the code editor at app.customjs.space and save it under a name. In the panel next to the code you define dynamic parameters, here items, currency, tier and taxRate. In the code, each one is available as input.items, input.currency and so on. The code ends with return, and the returned value is what Make receives. The function also gets a response type (text, JSON, HTML, PDF or PNG); for data, return an object and pick JSON.

In Make, add the CustomJS app and choose the Execute Stored Function module (Make lists it as "Execute a Stored Function"). Select the function by name. Make then shows one input field per parameter, so one scenario maps items from a webhook bundle and another from a CRM deal, without touching the code. Each call costs 1 Make credit and 1 CustomJS request, however long the code runs. The require() list from the npm modules page is available inside the function on every plan.

Two details save time. Parameters arrive as strings; a Make collection or array goes through Make's Transform to JSON module first, and the function parses it with JSON.parse. And values that should change without a code edit (a discount table, an HTML template) can live in a static variable of the function, readable as variables.name.

Example: one priceQuote function, three scenarios

The function takes line items, a currency, a customer tier and a tax rate, and returns subtotal, discount, tax, total and a formatted string. The business rules (tier discounts, rounding to cents) live in one place.

// Stored function "priceQuote"
// Parameters defined in the editor: items, currency, tier, taxRate
const items = typeof input.items === "string" ? JSON.parse(input.items) : input.items;
const currency = (input.currency || "EUR").toUpperCase();
const tier = input.tier || "standard";
const taxRate = Number(input.taxRate) || 0;

// Business rules live here, once. Add a tier and every scenario gets it.
const discounts = { standard: 0, partner: 0.15 };
const discountRate = discounts[tier] ?? 0;

if (!Array.isArray(items) || items.length === 0) {
  return { error: "items must be a non-empty array", currency, tier };
}

const round = (n) => Math.round(n * 100) / 100;
const lines = items.map((it) => ({
  sku: it.sku,
  qty: Number(it.qty) || 0,
  lineTotal: round((Number(it.qty) || 0) * (Number(it.unitPrice) || 0)),
}));

const subtotal = round(lines.reduce((sum, l) => sum + l.lineTotal, 0));
const discount = round(subtotal * discountRate);
const tax = round((subtotal - discount) * taxRate);
const total = round(subtotal - discount + tax);
const money = new Intl.NumberFormat("en-US", { style: "currency", currency });

return {
  currency, tier, subtotal, discount, tax, total,
  totalFormatted: money.format(total),
  lineCount: lines.length,
  lines,
};

Input, as the webhook intake scenario fills the four parameter fields (items arrives as a JSON string from Transform to JSON, shown parsed here):

{
  "items": [
    { "sku": "DESK-120", "qty": 2, "unitPrice": 349.0 },
    { "sku": "CHAIR-A", "qty": 2, "unitPrice": 189.5 }
  ],
  "currency": "EUR",
  "tier": "standard",
  "taxRate": "0.19"
}

Output, shown by Make as mappable fields in every following module:

{
  "currency": "EUR",
  "tier": "standard",
  "subtotal": 1077,
  "discount": 0,
  "tax": 204.63,
  "total": 1281.63,
  "totalFormatted": "€1,281.63",
  "lineCount": 2,
  "lines": [
    { "sku": "DESK-120", "qty": 2, "lineTotal": 698 },
    { "sku": "CHAIR-A", "qty": 2, "lineTotal": 379 }
  ]
}

This function makes no network call and finishes in roughly 120 ms per request; the median inline script on the platform takes 121 ms.

The three scenarios map the same four parameters from different sources:

Scenarioitemscurrency / tier / taxRateWhat happens with the output
1. Webhook intakeCart array from the order form, through Transform to JSONEUR / standard / 0.19totalFormatted goes into the confirmation email, total into the orders sheet
2. CRM syncDeal line items from HubSpot, aggregated and transformed to JSONUSD / partner / 0total and discount are written back to the deal amount and a discount property
3. Nightly reportYesterday's unbilled orders, one call per order inside an IteratorFrom the customer record / from the customer record / by countryTotals are aggregated into one row per customer and sent to the finance channel

The CRM sync call, for example, sends ten DESK-120 units at 349.00 with tier partner and tax rate 0, and gets back subtotal 3490, discount 523.5, total 2966.5 and "$2,966.50". Same code, different numbers, no second copy.

The payoff shows up at the first change. Say finance adds a reseller tier at 25%, or finds that half cents were rounded the wrong way. You edit the function once, save, and all three scenarios use the new version on their next run. With inline code that is three edits in three scenarios, and the one you forget produces wrong invoices for a month.

Use our Make App to execute JavaScript directly in Make.

How do I test a stored function before wiring three scenarios to it?

Test it once, in the editor, with sample input. The editor lets you fill in each parameter and run the function without a scenario attached, so you see the returned object or the error directly. Four runs catch most problems:

  • The happy path. Paste the sample items, set currency, tier and tax rate, and check the totals with a calculator: 698 + 379 = 1077, tax 204.63, total 1281.63.
  • Missing or empty items. The function returns an error field instead of throwing, so the scenario can route on it with a filter.
  • Strings where numbers are expected. Make often delivers "2" rather than 2. The Number() calls handle that; test it anyway.
  • An unknown tier. "vip" is not in the table and should fall back to 0% rather than produce NaN.

Only then add the Execute Stored Function module to the first scenario, map the parameters, and run it once. The function is already proven, so the only open question is the mapping. Repeat for the other two. Saved versions mean a later change that goes wrong can be rolled back without touching any scenario.

How do the four ways to run code in Make compare?

Make limits checked on October 7, 2026 against Make's documentation; CustomJS limits from the pricing page.

Make Code app (inline)Make Custom FunctionsCustomJS inlineCustomJS stored function
Sharing across scenariosNone. Copy-paste or blueprint exportYes, team-wide, with version historyNone. Copy-pasteYes, called by name from any scenario, versioned
Time limit30 s (Enterprise: 300 s)300 ms30 s free, 60 s paid30 s free, 60 s paid
Code sizeNot a stated limit5,000 charactersModule text fieldEditor, median function 110 lines
npm packagesmoment, moment-timezone, lodash; others on EnterpriseNoneFull list, every planFull list, every plan
Network and asyncYesNo HTTP, synchronous onlyfetch, async/awaitfetch, async/await
PlanPaid Make plans, 2 credits per secondMake EnterpriseAny Make plan, 1 credit per call, CustomJS free tier 600 requests/monthAny Make plan, 1 credit per call, CustomJS free tier 600 requests/month

Read the table in both directions. On Make Enterprise with a pure formula under 300 ms, Make Custom Functions are the native answer and need no third party. On a paid Make plan with a one-second script in a single scenario, the Code app is fine and, as the pricing comparison shows, often cheaper. The stored function wins when code has to be shared, when it needs a package or an HTTP call, or when the Make plan is below Enterprise.

Who actually uses stored functions?

One number from our own data, because it describes the pattern rather than the product: customers who use stored functions are the longest-tenured group on the platform, with a median tenure of 15 months. We read that as a property of the workflow. Once logic lives in one named, versioned place, the scenarios around it become cheaper to change, and people keep building on them instead of rebuilding them. It is the same reason developers put shared code in a library.

When Make's built-in is enough

A stored function is one more thing to maintain. Do not create one in these cases:

  • The logic is a one-line mapping formula. formatDate, replace, split, sum and the rest of Make's functions cost nothing extra and need no code step. A formula repeated in three scenarios is fine.
  • The code is short and used in one scenario. Keep it inline. Moving a 12-line snippet to a stored function gains nothing until a second scenario needs it.
  • You are on Make Enterprise and the function is pure. Synchronous, under 300 ms, under 5,000 characters, no fetch, no library: use Make Custom Functions. They are shared, versioned and native.
  • You want to reuse a whole scenario. Scenario templates and blueprint export are built for that. A stored function shares logic, not modules and connections.
  • The task is a single API call with no transformation. Make's HTTP module does that without code. The custom API calls guide covers where code starts to earn its place.
  • A ready-made module exists. Group & Aggregate Array, Format Date & Convert Timezone and Parse Localized Number are forms, not functions. If a module already does the job, a function is a step backwards.

What about n8n?

n8n has a free built-in Code node, and the priceQuote logic runs there unchanged with $input.all() or $json in place of input. To share one function across Make and n8n, call the stored function's REST URL from n8n's HTTP Request node, so both tools run the same code.

The free tier includes 600 requests per month and the full npm list, no credit card. Write the function once, test it, and point the first scenario at it.

Create a stored function

Frequently Asked Questions

Related Articles

Continue reading on similar topics

Statistics and Exact Money Math in Make.com
·Guide

Statistics and Exact Money Math in Make.com

Median, standard deviation, percentiles, regression and cent-exact money splits in Make.com with one JavaScript step. No Google Sheets detour, copy-paste recipes.

makemake-comstatistics