Skip to main content

JavaScript in agent functions

Agent functions run modern JavaScript in a secure sandbox, not in Node.js or a browser. This page lists what the language gives you, the built-ins added for you, and what's blocked.

Language version​

Everything up to ES2024 works, including:

  • async / await, async generators and for await
  • optional chaining ?., ?? and ??=, ||=, &&=
  • classes with private #fields and static blocks
  • Array.prototype.at, findLast, toSorted, Object.groupBy, Object.hasOwn, String.prototype.replaceAll
  • Map, Set, WeakMap, WeakSet, Reflect, BigInt, JSON, Math, Date, RegExp (including the d flag), Promise
  • Uint8Array, ArrayBuffer, DataView

Code runs as a module, in strict mode.

export default async function* ({ orders = [] }) {
const byStatus = Object.groupBy(orders, (order) => order.status ?? "unknown");
const newest = orders.toSorted((a, b) => b.createdAt.localeCompare(a.createdAt)).at(0);
return { counts: Object.fromEntries(Object.entries(byStatus).map(([k, v]) => [k, v.length])), newest };
}

Built-ins you get without an import​

NameUse it for
consoleLogs you see in the run panel and in Analysis. See Test and debug.
BufferBytes and encodings: base64, hex, latin1
URL, URLSearchParamsBuilding and reading links and query strings
IntlFormatting numbers, money and dates

Buffer​

Buffer covers the common parts of Node's: Buffer.from, alloc, concat, byteLength, compare, isBuffer, and on a buffer toString, slice, subarray, equals, write, copy, fill and toJSON. The encodings are utf8, hex, base64, ascii and latin1 (binary). base64url, utf16le and Node's readUInt8-style methods aren't available. A buffer can be up to 1 MB.

// base64 encode and decode, instead of btoa / atob
const encoded = Buffer.from("user:secret").toString("base64"); // "dXNlcjpzZWNyZXQ="
const decoded = Buffer.from(encoded, "base64").toString("utf8"); // "user:secret"

// base64url, by hand
const base64url = encoded.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");

// bytes to hex
const hex = Buffer.from("hello").toString("hex"); // "68656c6c6f"

URL and URLSearchParams​

const link = new URL("https://shop.example.com/track");
link.searchParams.set("order", orderId);
link.searchParams.set("lang", "en");
link.toString(); // "https://shop.example.com/track?order=A-1001&lang=en"

const params = new URLSearchParams("utm_source=whatsapp&utm_campaign=diwali");
params.get("utm_campaign"); // "diwali"

Intl​

Intl.NumberFormat and Intl.DateTimeFormat format with a locale. They support a smaller set of options than a browser:

FormatterOptions
Intl.NumberFormat(locale, options)style: "decimal", "currency" or "percent"; currency: a 3-letter code such as "INR"; minimumFractionDigits, maximumFractionDigits
Intl.DateTimeFormat(locale, options)dateStyle: "short", "medium" or "long"

Any other option, such as timeZone or timeStyle, stops the function with an error that lists the allowed ones. Dates are formatted as a date only, in UTC. The locale defaults to "en".

const price = new Intl.NumberFormat("en-IN", { style: "currency", currency: "INR" }).format(149999.5);
// "₹1,49,999.50"

const share = new Intl.NumberFormat("en", { style: "percent", maximumFractionDigits: 1 }).format(0.256);
// "25.6%"

const day = new Intl.DateTimeFormat("en-GB", { dateStyle: "long" }).format(new Date("2026-10-29T10:00:00Z"));
// "29 October 2026"

Dates and time zones​

The function's clock is in UTC. new Date() is the current time, and methods such as getHours() return UTC values. To show a local time, add the offset yourself:

const now = new Date();
const ist = new Date(now.getTime() + 5.5 * 60 * 60 * 1000); // India, UTC+5:30
const time = `${String(ist.getUTCHours()).padStart(2, "0")}:${String(ist.getUTCMinutes()).padStart(2, "0")}`;
const isBusinessHours = ist.getUTCHours() >= 9 && ist.getUTCHours() < 18;

Math.random() works. For IDs and anything secret, use crypto.randomUUID() and crypto.randomBytes().

What's blocked​

These names don't exist, or throw when used. Using one is usually caught when you save.

BlockedUse instead
fetch, XMLHttpRequest, WebSocket, Workerapis.execute
setTimeout, setInterval, setImmediate, clearTimeout, queueMicrotaskawait your calls. A function can't wait or schedule work for later.
require, process, module, exports, __dirname, fs, http, child_process and other Node.js modules; npm packagesThe modules listed in Structure of an agent function
eval, new Function(…)Write the logic in the function body
atob, btoaBuffer.from(text).toString("base64") and Buffer.from(b64, "base64").toString()
TextEncoder, TextDecoderBuffer.from(text) and buffer.toString("utf8")
Proxy, WeakRef, FinalizationRegistry, performance, WebAssembly, SharedArrayBuffer, AtomicsNot needed in functions
Int8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array, BigInt64Array, BigUint64ArrayUint8Array, DataView or Buffer
Symbol.for, Symbol.keyFor, RegExp.$1 … RegExp.inputSymbol(), and the match array a regex returns

Global names from classic functions, such as data, ymLib, app and resolve, don't exist either. What a classic function read from data.profile, data.user, data.sender and data.source is on the context argument.

Built-ins can't be changed​

Built-in objects and their prototypes are frozen, so code can call them but not change them. Array.prototype.last = …, Object.assign = … or adding a name to globalThis throws. Your own objects and classes work as usual.

// Fails: changes a built-in
Array.prototype.last = function () { return this[this.length - 1]; };

// Works: a helper of your own
const last = (list) => list[list.length - 1];
  • Limits: time, memory and calls per run
  • Crypto helpers: hashing, signing, encryption and random values