Built-in Utilities
Every expression can use a small set of helpers under the utils namespace — no setup required, available in any binding on any page. They cover the everyday jobs of turning raw data into something a user can read: dates, durations, numbers, JSON, and file downloads. Each helper degrades quietly instead of throwing, so a formatting mistake never crashes your page.
Helpers at a Glance
| Helper | What it does | Quick example |
| utils.formatDate | Format a date with a custom date-fns pattern | {{ utils.formatDate(order.createdAt, 'dd MMM yyyy') }} → 15 Jan 2024 |
| utils.formatDateByFormatType | Format a date with a named preset, including relative forms like "2 hours ago" | {{ utils.formatDateByFormatType(order.createdAt, 'Mdy') }} → January 05, 2024 |
| utils.formatTime | Turn a millisecond duration into readable units like 1d 1h 1m | {{ utils.formatTime(90061000, 'seconds') }} → 1d 1h 1m 1s |
| utils.formatNumber | Format a number — locale grouping, compact notation, units | {{ utils.formatNumber({ value: 1234567, notation: 'compact' }) }} → 1.2M |
| utils.parseJson | Parse a JSON string safely — never throws | {{ utils.parseJson(webhook.body).total }} → 250 |
| utils.stringifyJson | Serialize a value to JSON safely — never throws | {{ utils.stringifyJson(filters.value) }} → {"status":"open"} |
| utils.downloadFile | Download a file in the current browser tab (side effect — use in actions, not rendered bindings) | {{ utils.downloadFile(invoice.fileUrl, 'invoice.pdf') }} |
| utils.dateTime.values.todayDate | Today's date as dd-MM-yyyy (snapshot, not a live clock) | {{ utils.dateTime.values.todayDate }} → 06-07-2026 |
| utils.dateTime.values.startOfTodayTimestamp | Local midnight timestamp — use for "today only" filters | {{ order.createdAt >= utils.dateTime.values.startOfTodayTimestamp }} |
| utils.getAuthToken | Mobile apps only. Returns the signed-in session's auth token, or empty string. | {{ utils.getAuthToken() }} |
utils.formatDate
Formats a date or timestamp using a date-fns pattern (https://date-fns.org/docs/format).
utils.formatDate(date, formatStr)
| Parameter | Type | Required | Description |
| date | Date | string | number | Required (required) | A Date object, ISO string, or numeric timestamp. A numeric string (e.g. '1704067200000') is treated as an epoch timestamp — see gotchas. |
| formatStr | string | Required (required) | Any date-fns pattern. Common tokens: dd day, MMM short month, yyyy year, H 24-hour, h 12-hour, mm minutes, a AM/PM. |
Examples
{{ utils.formatDate(order.createdAt, 'dd MMM yyyy') }} // → 15 Jan 2024 {{ utils.formatDate(order.createdAt, 'MMM dd, yyyy h:mm a') }} // → Jan 15, 2024 10:30 AM {{ utils.formatDate('not-a-date', 'dd MMM yyyy') }} // → not-a-date (echoes invalid input)
utils.formatDateByFormatType
Formats a date using a named preset instead of a raw pattern — including relative forms like "2 hours ago".
utils.formatDateByFormatType(date, formatType, options)
| Parameter | Type | Required | Default | Description |
| date | Date | string | number | Required (required) | — | The date to format. |
| formatType | string | Optional (optional) | mdyhm | A preset name from the table below, or any raw date-fns pattern. Unknown strings are treated as raw patterns. |
| options | object | Optional (optional) | — | Only used by relative-time presets. |
Date Format Presets
| Preset | Pattern | Output (example: Jan 05, 2024, 09:07:03) |
dmyhms | dd MMM yyyy, H:mm:ss | 05 Jan 2024, 9:07:03 |
dmyhm | dd MMM yyyy, H:mm | 05 Jan 2024, 9:07 |
mdyhm (default) | MM/dd/yyyy H:mm | 01/05/2024 9:07 |
Mdy | MMMM dd, yyyy | January 05, 2024 |
dMy | d MMM yyyy | 5 Jan 2024 |
yyyyMMdd | yyyy-MM-dd | 2024-01-05 |
ddMMyyyy | dd-MM-yyyy | 05-01-2024 |
hhmm | HH:mm | 09:07 |
hma | h:mm a | 9:07 AM |
iso | yyyy-MM-dd'T'HH:mm:ssxxx | 2024-01-05T09:07:03+05:30 |
relative-time-ago | Relative with "ago" | 2 hours ago (requires timestamp input) |
relative-time-to-now | Relative with "about" | about 2 hours |
utils.formatTime
Turns a duration in milliseconds into readable units. This is elapsed time, not a clock time.
utils.formatTime(ms, precision, notation, maxSignificantUnits)
| Parameter | Type | Default | Description |
| ms | number | — | Duration in milliseconds. |
| precision | string | 'milliseconds' | Smallest unit to show: 'years', 'months', 'days', 'hours', 'minutes', 'seconds', 'milliseconds'. |
| notation | string | 'compact' | 'compact' → 1d 1h; 'comfortable' → 1 day 1 hour. |
| maxSignificantUnits | number | 7 | Show at most this many units (clamped 1–6). |
Examples
{{ utils.formatTime(90061000, 'seconds') }} // → 1d 1h 1m 1s {{ utils.formatTime(90061000, 'seconds', 'comfortable') }} // → 1 day 1 hour 1 minute 1 second {{ utils.formatTime(90061000, 'seconds', 'compact', 2) }} // → 1d 1h
utils.formatNumber
Formats a number with locale grouping, compact notation, or units. Takes a single options object — not a plain number.
utils.formatNumber({ value, locale, notation, compactDisplay, maximumFractionDigits, padDecimalPlaces, unit, unitDisplay })
| Property | Type | Required | Default | Description |
| value | number | Required (required) | — | The number to format. |
| locale | string | Optional (optional) | Runtime locale | e.g. 'en-US', 'de-DE' |
| notation | string | Optional (optional) | 'standard' | 'standard', 'compact', 'scientific', 'engineering', or 'text' (disables grouping). |
| compactDisplay | string | Optional (optional) | — | With compact notation: 'short' (1.2M) or 'long' (1.2 million). |
| maximumFractionDigits | number | Optional (optional) | — | Maximum digits after the decimal. |
| padDecimalPlaces | boolean | Optional (optional) | — | Pad decimals with zeros to maximumFractionDigits. Has no effect without maximumFractionDigits. |
| unit | string | Optional (optional) | — | e.g. 'percent', 'kilometer-per-hour', 'megabyte'. |
| unitDisplay | string | Optional (optional) | — | 'short', 'narrow', or 'long'. |
Examples
{{ utils.formatNumber({ value: 1234567.891, maximumFractionDigits: 2 }) }} // → 1,234,567.89 {{ utils.formatNumber({ value: 1234567, notation: 'compact', compactDisplay: 'short', maximumFractionDigits: 1 }) }} // → 1.2M {{ utils.formatNumber({ value: 5, maximumFractionDigits: 2, padDecimalPlaces: true }) }} // → 5.00 {{ utils.formatNumber({ value: 20, unit: 'percent' }) }} // → 20% {{ utils.formatNumber({ value: 20, unit: 'kilometer-per-hour', unitDisplay: 'long' }) }} // → 20 kilometers per hour
Warning: utils.formatNumber does not support currency formatting. To show monetary values, format the number and add the currency symbol yourself in your expression: {{ '$' + utils.formatNumber({ value: total, maximumFractionDigits: 2 }) }}
utils.parseJson
Parses a JSON string safely. Invalid JSON never throws — you get the fallback value instead.
utils.parseJson(str, fallback, retriever)
| Parameter | Type | Default | Description |
| str | string | — | The JSON text to parse. |
| fallback | any | {} | Returned on a parse error and when the parsed value is null. |
| retriever | function | — | A JSON reviver — advanced, usually omitted. |
Examples
{{ utils.parseJson(webhook.body).total }} // → 250 {{ utils.parseJson('oops', []) }} // → [] (fallback) {{ utils.parseJson('null') }} // → {} (null result → fallback)
utils.stringifyJson
Serializes a value to a JSON string. On failure (e.g. circular reference) returns the fallback instead of throwing.
utils.stringifyJson(obj, fallback, space, replacer)
| Parameter | Type | Default | Description |
| obj | any | — | The value to serialize. |
| fallback | string | — | Returned on failure. If absent, failure returns null. |
| space | number | 0 | Indentation for pretty-printing. |
| replacer | function | — | JSON replacer function — advanced, usually omitted. |
utils.downloadFile
Starts a file download in the current browser tab. This is a side effect — put it in an action (button's On Click), not in a text/label binding that recomputes on every render.
utils.downloadFile(fileOrUrl, filename)
| Parameter | Type | Description |
| fileOrUrl | string | Blob | A file URL/path, or in-memory file content. Platform file URLs are resolved automatically. |
| filename | string | The name to save the file as. |
Usage — in a button's On Click action
// Use in a Run Script action on the button, NOT in a text binding {{ utils.downloadFile(invoice_query.data.fileUrl, 'invoice-2024.pdf') }}
Gotchas
| Gotcha | Details |
| Helpers degrade silently | None of these helpers throw on bad input — they return a safe fallback. A formatting mistake shows as unformatted output, not an error screen. |
| Numeric string = timestamp in formatDate | A string of digits (e.g. '1704067200000') is treated as an epoch timestamp by formatDate, not as text. |
| formatNumber takes an object, not a number | Write {{ utils.formatNumber({ value: total }) }} — not {{ utils.formatNumber(total) }}. Passing a plain number returns the number unchanged. |
| downloadFile is a side effect | A binding re-evaluates on every render. Placing utils.downloadFile in a text/label binding downloads on every re-render. Place it in button actions only. |
| formatTime = elapsed time, not clock time | Takes a duration in milliseconds, not a time of day. If precision is coarser than the whole span (e.g. hours on a 90-second duration), the result is an empty string — not "0h". |
| relative-time-ago needs a timestamp | The relative-time-ago preset reads its input as a number. An ISO date string produces an invalid result — use relative-time-to-now for ISO strings. |
| dateTime values are snapshots | todayDate and startOfTodayTimestamp are computed when the page context is built — they reflect the time of last rebuild, not a live clock. |
| getAuthToken is mobile-only | utils.getAuthToken() does not exist on web apps — it is only available in mobile apps. |