Docs / The language & scripts
a9script standard library
Everything the language itself gives you, beside the platform’s own
functions. Do not edit this file — it is generated; change the rows and
run npm run docs:standard-library.
All of it answers immediately: nothing here pauses a run, and nothing here reaches outside the script. Every example below is executed, so what it says the answer is, is the answer.
Dates are always UTC and text is compared as it is written unless you pass a language — the two places where a machine’s own settings would otherwise decide, and where two runs of one script would then disagree.
Globals
| Built-in | What it does | Example |
|---|---|---|
NaN | The answer to a calculation that has no number. It is not equal to itself, so ask Number.isNaN rather than comparing. | NaN !== NaN → true |
Infinity | Larger than any number. Dividing a positive number by zero lands here. | 1 / 0 === Infinity → true |
Math | Rounding, powers, roots, comparisons and the two constants — the calculations below. | Math.max(2, 9) → 9 |
JSON | Text into data and back: JSON.parse reads it, JSON.stringify writes it. | JSON.parse('{"id":1}').id → 1 |
Object | Reads an object’s keys and values, copies between objects, and freezes one. | Object.keys({ a: 1, b: 2 }) → ["a","b"] |
Number | Turns a value into a number, and holds the numeric limits and the strict checks. | Number('42') → 42 |
Array | Recognises and builds lists. The methods you use daily live on the list itself. | Array.isArray([1, 2]) → true |
String | Turns any value into text — including the ones + '' would refuse. | String(42) → "42" |
Boolean | True or false by the same rule if uses: empty text, 0, null and undefined are false. | Boolean('') → false |
BigInt | A whole number of any size, for ids that do not survive as ordinary numbers. It cannot be mixed with them in arithmetic, and it is not valid JSON — write it out as text before returning it. | String(BigInt('9007199254740993')) → "9007199254740993" |
Map | A dictionary with keys of any type, remembering the order they were added. Use it when keys are data rather than field names. | new Map([['a', 1]]).get('a') → 1 |
Set | A collection that keeps each value once — the short way to remove duplicates. | new Set([1, 1, 2]).values() → [1,2] |
Date | A moment in time, always UTC. Build it from an ISO date, from milliseconds, or from nothing for the current moment. | new Date('2026-07-14').toISOString() → "2026-07-14T00:00:00.000Z" |
RegExp | A pattern for testing and picking apart text. Usually written between slashes (/[0-9]+/); this form is for a pattern built at run time. | new RegExp('[0-9]+').test('a1') → true |
parseInt | Reads a whole number off the front of some text and ignores the rest. | parseInt('42px') → 42 |
parseFloat | The same, for a number with decimals. | parseFloat('3.14 rad') → 3.14 |
isNaN | Would this value fail to become a number? It converts first — Number.isNaN is the one that does not. | isNaN('x') → true |
isFinite | Is this a real, finite number once converted? | isFinite('42') → true |
atob | Decodes base64 whose bytes are single characters. For text with accents or emoji, use base64Decode. | atob('aGk=') → "hi" |
btoa | Encodes single-character bytes as base64. For text, use base64Encode. | btoa('hi') → "aGk=" |
Math
| Built-in | What it does | Example |
|---|---|---|
Math.random | A number from 0 up to (but never reaching) 1. For an id or a token, use uuid or randomHex. | Math.random() → 0.8039261118570492 (varies) |
Math.abs | The number without its sign. | Math.abs(-3) → 3 |
Math.min | The smallest of the numbers given. | Math.min(3, 1, 2) → 1 |
Math.max | The largest of the numbers given. | Math.max(3, 1, 2) → 3 |
Math.floor | Down to the whole number below. | Math.floor(1.9) → 1 |
Math.ceil | Up to the whole number above. | Math.ceil(1.1) → 2 |
Math.round | To the nearest whole number; exactly half goes up. | Math.round(2.5) → 3 |
Math.trunc | Drops the decimals without rounding — towards zero, so -1.9 becomes -1. | Math.trunc(-1.9) → -1 |
Math.sign | -1, 0 or 1, depending on which side of zero the number is. | Math.sign(-5) → -1 |
Math.pow | The first number raised to the second. | Math.pow(2, 10) → 1024 |
Math.sqrt | The square root. | Math.sqrt(9) → 3 |
Math.log | The natural logarithm. | Math.log(1) → 0 |
Math.exp | e raised to this number. | Math.exp(0) → 1 |
Math.PI | The ratio of a circle’s circumference to its diameter. | Math.PI → 3.141592653589793 |
Math.E | The base of the natural logarithm. | Math.E → 2.718281828459045 |
JSON
| Built-in | What it does | Example |
|---|---|---|
JSON.parse | Turns a JSON string into data you can read. Malformed text throws, so catch it if the source is not yours. | JSON.parse('{"id":1}').id → 1 |
JSON.stringify | Turns data into a JSON string. Dates become ISO text; undefined values are left out. | JSON.stringify([1, 2]) → "[1,2]" |
Object
| Built-in | What it does | Example |
|---|---|---|
Object.keys | The object’s own field names, in the order they were set. | Object.keys({ a: 1, b: 2 }) → ["a","b"] |
Object.values | The values behind those names. | Object.values({ a: 1, b: 2 }) → [1,2] |
Object.entries | Name and value together, one pair per field — what you loop over to walk an object. | Object.entries({ a: 1 }) → [["a",1]] |
Object.assign | Copies fields into the first object and answers it. The first object is changed. | Object.assign({ a: 1 }, { b: 2 }) → {"a":1,"b":2} |
Object.freeze | Locks an object: later writes to its fields do nothing at all, silently. | Object.freeze({ a: 1 }).a → 1 |
Object.fromEntries | Name-and-value pairs back into an object — the other half of Object.entries. | Object.fromEntries([['a', 1]]) → {"a":1} |
Number
| Built-in | What it does | Example |
|---|---|---|
Number.isNaN | Is this value exactly the not-a-number value? Nothing is converted, so text answers false. | Number.isNaN('x') → false |
Number.isFinite | Is this a number, and a finite one? Text answers false — the bare isFinite converts first. | Number.isFinite('42') → false |
Number.isInteger | Is this a whole number? | Number.isInteger(5.0) → true |
Number.parseInt | The same function as the bare parseInt. | Number.parseInt('7') → 7 |
Number.parseFloat | The same function as the bare parseFloat. | Number.parseFloat('2.5') → 2.5 |
Number.MAX_SAFE_INTEGER | The largest whole number that still counts reliably. Past it, use BigInt or text. | Number.MAX_SAFE_INTEGER → 9007199254740991 |
Number.MIN_SAFE_INTEGER | The same limit on the negative side. | Number.MIN_SAFE_INTEGER → -9007199254740991 |
Number.MAX_VALUE | The largest number there is. | Number.MAX_VALUE → 1.7976931348623157e+308 |
Number.MIN_VALUE | The smallest positive number there is. | Number.MIN_VALUE → 5e-324 |
Number.EPSILON | The smallest gap between 1 and the next number — the tolerance for comparing decimals. | Number.EPSILON → 2.220446049250313e-16 |
Number.POSITIVE_INFINITY | The same value as Infinity. | Number.POSITIVE_INFINITY → Infinity |
Number.NEGATIVE_INFINITY | Infinity on the negative side. | Number.NEGATIVE_INFINITY → -Infinity |
Number.NaN | The same value as the bare NaN. | Number.NaN → NaN |
Number.toFixed | Text with exactly this many decimals, rounded. For money a reader will see, formatCurrency knows the country’s conventions. | (3.14159).toFixed(2) → "3.14" |
String
| Built-in | What it does | Example |
|---|---|---|
String.at | The character at a position; a negative position counts from the end. | 'hello'.at(-1) → "o" |
String.charAt | The character at a position, counting from 0. | 'hello'.charAt(1) → "e" |
String.charCodeAt | The numeric code of the character at a position. | 'A'.charCodeAt(0) → 65 |
String.codePointAt | The full code of the character at a position — an emoji counts as one, where charCodeAt sees half. | '\u{1F44B}'.codePointAt(0) → 128075 |
String.includes | Does this text contain that text? | 'hello'.includes('ell') → true |
String.startsWith | Does it begin with that text? | 'hello'.startsWith('he') → true |
String.endsWith | Does it end with that text? | 'hello'.endsWith('lo') → true |
String.indexOf | Where that text first appears, or -1 if it does not. | 'hello'.indexOf('l') → 2 |
String.lastIndexOf | Where it appears last, or -1. | 'hello'.lastIndexOf('l') → 3 |
String.slice | The part between two positions; negatives count from the end. | 'hello'.slice(1, 3) → "el" |
String.substring | The same, except negatives are treated as 0 and the two positions swap if they are the wrong way round. | 'hello'.substring(1, 3) → "el" |
String.toUpperCase | The text in capitals. | 'hi'.toUpperCase() → "HI" |
String.toLowerCase | The text in lower case. | 'HI'.toLowerCase() → "hi" |
String.trim | Without the spaces at either end. | ' hi '.trim() → "hi" |
String.trimStart | Without the spaces at the front. | ' hi'.trimStart() → "hi" |
String.trimEnd | Without the spaces at the end. | 'hi '.trimEnd() → "hi" |
String.padStart | Filled up to a length by adding at the front — how a number becomes 007. | '7'.padStart(3, '0') → "007" |
String.padEnd | The same, adding at the end. | '7'.padEnd(3, '0') → "700" |
String.repeat | The text over and over. | 'ab'.repeat(3) → "ababab" |
String.split | Cut into a list wherever the separator appears. A pattern works as the separator too. | 'a,b'.split(',') → ["a","b"] |
String.concat | Joined onto the end. + does the same thing. | 'a'.concat('b') → "ab" |
String.replace | Replaces the FIRST occurrence. With a pattern marked g, it replaces every one. | 'a-b-c'.replace('-', '+') → "a+b-c" |
String.replaceAll | Replaces every occurrence. | 'a-b-c'.replaceAll('-', '+') → "a+b+c" |
String.localeCompare | Sorts two pieces of text the way a country does — Swedish files ‘ä’ after ‘z’, German with ‘a’. The language is an argument, never the machine’s, so a sorted list stays sorted wherever it runs. | 'a'.localeCompare('b', 'en') → -1 |
String.match | The matches of a pattern. With g you get every match as text; without it, the first match and its groups. | 'a1b2'.match(/[0-9]/g) → ["1","2"] |
String.matchAll | Every match with its groups and position — a list you can loop over. | 'a1b2'.matchAll(/[0-9]/g).length → 2 |
String.search | Where a pattern first matches, or -1. | 'abc'.search(/b/) → 1 |
Array
| Built-in | What it does | Example |
|---|---|---|
Array.isArray | Is this value a list? | Array.isArray([1]) → true |
Array.of | A list of the values given. | Array.of(1, 2) → [1,2] |
Array.from | A list from something list-like — text, a Map’s keys — optionally mapping each item on the way. | Array.from('ab') → ["a","b"] |
Array.at | The item at a position; a negative position counts from the end. | [1, 2, 3].at(-1) → 3 |
Array.includes | Is this value in the list? | [1, 2].includes(2) → true |
Array.indexOf | Where the value first sits, or -1 if it is not there. | ['a', 'b'].indexOf('b') → 1 |
Array.lastIndexOf | Where it sits last, or -1. | ['a', 'b', 'a'].lastIndexOf('a') → 2 |
Array.slice | A copy of part of the list; negatives count from the end. The original is untouched. | [1, 2, 3].slice(1) → [2,3] |
Array.concat | A new list with the others appended. | [1].concat([2]) → [1,2] |
Array.join | The items as one piece of text, with a separator between them. | ['a', 'b'].join('-') → "a-b" |
Array.push | Adds to the end. Changes the list and answers its new length. | [1].push(2) → 2 |
Array.pop | Removes the last item and answers it. Changes the list. | [1, 2].pop() → 2 |
Array.shift | Removes the FIRST item and answers it. Changes the list. | [1, 2].shift() → 1 |
Array.unshift | Adds to the front. Changes the list and answers its new length. | [2].unshift(1) → 2 |
Array.splice | Cuts items out at a position (and optionally puts others in). Changes the list; answers what was removed. | [1, 2, 3].splice(0, 1) → [1] |
Array.reverse | Turns the list back to front. Changes the list. | [1, 2].reverse() → [2,1] |
Array.fill | Overwrites every item with one value. Changes the list. | [1, 2].fill(0) → [0,0] |
Array.flat | Unpacks lists inside the list, one level deep unless you ask for more. | [1, [2, [3]]].flat() → [1,2,[3]] |
Array.keys | The positions, as a list. | [10, 20].keys() → [0,1] |
Array.values | The items, as a list. | [10, 20].values() → [10,20] |
Array.entries | Position and item together, one pair each. | [10, 20].entries() → [[0,10],[1,20]] |
Array.map | A new list with every item put through a function. | [1, 2].map((n) => n * 2) → [2,4] |
Array.filter | A new list of the items a test keeps. | [1, 2, 3].filter((n) => n > 1) → [2,3] |
Array.reduce | Folds the list into one value, left to right, carrying a running result. | [1, 2, 3].reduce((sum, n) => sum + n, 0) → 6 |
Array.reduceRight | The same, right to left. | ['a', 'b'].reduceRight((all, s) => all + s, '') → "ba" |
Array.forEach | Runs a function for each item and answers nothing. Use map when you want the results. | [1, 2].forEach((n) => n) → undefined |
Array.some | Does at least one item pass the test? | [1, 2].some((n) => n > 1) → true |
Array.every | Do all of them pass? | [1, 2].every((n) => n > 0) → true |
Array.find | The first item that passes, or undefined. | [1, 2, 3].find((n) => n > 1) → 2 |
Array.findIndex | Where that first passing item sits, or -1. | [1, 2, 3].findIndex((n) => n > 1) → 1 |
Array.findLast | The last item that passes, searching from the end. | [1, 2, 3].findLast((n) => n < 3) → 2 |
Array.findLastIndex | Where that last passing item sits, or -1. | [1, 2, 3].findLastIndex((n) => n < 3) → 1 |
Array.flatMap | Map, then unpack one level — for turning each item into none, one or several. | [1, 2].flatMap((n) => [n, n]) → [1,1,2,2] |
Array.sort | Sorts the list IN PLACE. Without a comparison it sorts as text, so [10, 9] comes out [10, 9] — pass (a, b) => a - b for numbers. | [3, 1, 2].sort() → [1,2,3] |
Map
| Built-in | What it does | Example |
|---|---|---|
Map.get | The value stored under a key, or undefined. | new Map([['a', 1]]).get('a') → 1 |
Map.set | Stores a value under a key and answers the map, so calls chain. | new Map().set('a', 1).get('a') → 1 |
Map.has | Is there anything under this key? | new Map([['a', 1]]).has('a') → true |
Map.delete | Removes a key and says whether there was one. | new Map([['a', 1]]).delete('a') → true |
Map.clear | Empties the map. | new Map([['a', 1]]).clear() → undefined |
Map.keys | The keys, in the order they were added. | new Map([['a', 1]]).keys() → ["a"] |
Map.values | The values, in the same order. | new Map([['a', 1]]).values() → [1] |
Map.entries | Key and value together, one pair each — what you loop over. | new Map([['a', 1]]).entries() → [["a",1]] |
Map.forEach | Runs a function for each pair, value first, and answers nothing. | new Map([['a', 1]]).forEach((value) => value) → undefined |
Set
| Built-in | What it does | Example |
|---|---|---|
Set.add | Adds a value if it is not already there, and answers the set. | new Set().add(1).has(1) → true |
Set.has | Is this value in the set? | new Set([1]).has(1) → true |
Set.delete | Removes a value and says whether it was there. | new Set([1]).delete(1) → true |
Set.clear | Empties the set. | new Set([1]).clear() → undefined |
Set.keys | The values — a set’s keys and values are the same thing. | new Set([1, 2]).keys() → [1,2] |
Set.values | The values, in the order they were added. | new Set([1, 2]).values() → [1,2] |
Set.entries | Each value paired with itself — the shape that matches a Map’s. | new Set([1]).entries() → [[1,1]] |
Set.forEach | Runs a function for each value and answers nothing. | new Set([1]).forEach((value) => value) → undefined |
Date
| Built-in | What it does | Example |
|---|---|---|
Date.now | The current moment in milliseconds — the same clock now() reads. | Date.now() → 1774000000000 (varies) |
Date.getTime | The moment as milliseconds since the start of 1970. | new Date('2026-07-14').getTime() → 1783987200000 |
Date.toISOString | The moment as ISO text — the form to put in JSON, and the form other systems read. | new Date(0).toISOString() → "1970-01-01T00:00:00.000Z" |
Date.getUTCFullYear | The year. | new Date('2026-07-14').getUTCFullYear() → 2026 |
Date.getUTCMonth | The month, counting from 0 — July is 6. formatDate is the friendlier way to write a month out. | new Date('2026-07-14').getUTCMonth() → 6 |
Date.getUTCDate | The day of the month, counting from 1. | new Date('2026-07-14').getUTCDate() → 14 |
Date.getUTCDay | The day of the week, 0 for Sunday. | new Date('2026-07-14').getUTCDay() → 2 |
Date.getUTCHours | The hour, 0 to 23. | new Date('2026-07-14T05:06:07Z').getUTCHours() → 5 |
Date.getUTCMinutes | The minutes. | new Date('2026-07-14T05:06:07Z').getUTCMinutes() → 6 |
Date.getUTCSeconds | The seconds. | new Date('2026-07-14T05:06:07Z').getUTCSeconds() → 7 |
Date.getUTCMilliseconds | The milliseconds. | new Date('2026-07-14T05:06:07.008Z').getUTCMilliseconds() → 8 |
Date.setUTCFullYear | Moves the year. Changes the date and answers its new timestamp. | new Date('2026-07-14').setUTCFullYear(2027) → 1815523200000 |
Date.setUTCMonth | Moves the month, counting from 0. Changes the date. | new Date('2026-07-14').setUTCMonth(0) → 1768348800000 |
Date.setUTCDate | Moves the day of the month; a day past the end rolls into the next month. Changes the date. | new Date('2026-07-14').setUTCDate(20) → 1784505600000 |
Date.setUTCHours | Moves the hour. Changes the date. | new Date('2026-07-14').setUTCHours(5) → 1784005200000 |
Date.setUTCMinutes | Moves the minutes. Changes the date. | new Date('2026-07-14').setUTCMinutes(6) → 1783987560000 |
Date.setUTCSeconds | Moves the seconds. Changes the date. | new Date('2026-07-14').setUTCSeconds(7) → 1783987207000 |
Date.setUTCMilliseconds | Moves the milliseconds. Changes the date. | new Date('2026-07-14').setUTCMilliseconds(8) → 1783987200008 |
RegExp
| Built-in | What it does | Example |
|---|---|---|
RegExp.test | Does the pattern match anywhere in the text? | /[0-9]/.test('a1') → true |
RegExp.exec | The first match with its groups — position 0 is the whole match, 1 onwards the bracketed parts. | /([a-z])/.exec('hi')[1] → "h" |