Skip to main content

Standard library

The standard library is the set of functions that are always at hand, with no use or import: writing and reading on the console, waiting and measuring time, converting values, drawing random numbers, finding out which platform the program runs on and how much memory it uses. The global constants the compiler knows are here too.

They work the same on Windows and on the boards, except for what Platforms says.

Functions​

FunctionWhat it doesReturns
print(...), println(...)Write their arguments on the console; println adds a line break at the end.nil
readLine()Reads a line from the console.String
cls()Clears the console.nil
ink(color), paper(color)Change the color of the console's text and background.nil
pause(ms)Waits ms milliseconds.nil
clock()The milliseconds since startup.Integer
time(), time(format)The date and time.String
chr(code)The character of an ASCII code.String
int(x), float(x)Convert a number or a boolean.Integer, decimal
type(x)The type of a value.Integer (a t* constant)
randomize(seed)Seeds the random numbers.nil
random(), random(max), random(min, max)A random number.Integer or decimal
abs(x), round(x), sqrt(x)Absolute value, rounding and square root.Number
vlenght(x, y)The length of a vector.Decimal
len(x)The length of a string, a list or a map.Integer
rgb(r, g, b)A color in the 0xRRGGBB format.Integer
memUse(), memFree()The memory the VM uses and the memory left free.Integer
platform()Where the program runs.Integer (an HW_* constant)
vmerror()Nothing useful in 0.9.7: always 0.Integer
encode64(text), decode64(text)Encode and decode Base64.String

If you pass them an argument of another type, they throw ERR_TYPE_MISMATCH. With the wrong number of arguments, the program does not compile; cls, ink and paper say so when they run, with ERR_INVALID_ARG_NUMBER. Errors are covered in Errors and exceptions.

To end the program early there is exit: see exit.

Platforms​

WindowsESP32 / ESP32-S3ESP32-P4ESP32-S31
print, printlnWrite to the program's console.Write to the serial port.Write to the serial port.Write to the serial port.
readLine()Reads from the console.Gets nothing.Gets nothing.Gets nothing.
cls()Clears the console.Sends the terminal code that clears the screen.Sends the terminal code that clears the screen.Sends the terminal code that clears the screen.
ink(), paper()Do nothing.Send the terminal code of the color.Send the terminal code of the color.Send the terminal code of the color.
clock()Counts from when the VM started.Counts from when the board started.Counts from when the board started.Counts from when the board started.
time()The PC's date and time.Those of the board's clock.Those of the board's clock.Those of the board's clock.
memFree()Always 0.The free internal RAM, without the PSRAM.All the free memory, PSRAM included.All the free memory, PSRAM included.
platform()41 on the ESP32 and 2 on the S367
  • What the program writes on a board shows up in the Output with Open Serial (see Your program on a board).
  • Terminal codes (ANSI) are understood by a terminal program; the IDE's Output does not interpret them.
  • For the board's clock to have the right time, the board needs WiFi and NTP: you turn them on in ESP32 Tools (see Display, sound, SD and network).

Console​

print writes its arguments on the console, one after the other, with nothing between them. println does the same and adds a line break at the end; without arguments, println() just breaks the line. They take any number of arguments, of any type, and return nil.

var name = "Ann"
var points = 120
println("Player: ", name, " - points: ", points)
print("No line break, ")
println("and a line break")
println([1, "two", 3.5], " ", {"lives": 3})
Player: Ann - points: 120
No line break, and a line break
[1, two, 3.5] {lives: 3}

This is how they write each value:

ValueHow it comes outExample
IntegerAs it is.120
DecimalWith just the digits needed so that, read back, it's the same number, and without decimals if it has none.0.1 comes out as 0.1, 0.1 + 0.2 as 0.30000000000000004, and 10.0 as 10
StringWithout quotes.Ann
Boolean and nilWith their name.true, nil
List and mapWith their elements; strings without quotes.[1, two, 3.5], {lives: 3}
StructIts name and its fields.Point{x: 1, y: 2}
Class instanceThe name of the class.Cat instance
The error of a catchIts name and its message.ERR_KEY_NOT_FOUND: The given key was not present in the map.
Error valueError and its number.Error 9
  • To write a decimal with fewer digits, convert it first with its toString() method, which uses 15: with var x = 0.1, println(x.toString()) writes 0.1.
  • The arguments are written as they are worked out. If one throws an exception, the ones before it have already come out, with no line break: println("Price: ", prices[9]) leaves Price: written before the error.
  • To join texts into a single string, the string methods are in Strings.

readLine​

readLine waits for you to type a line on the console and press Enter, and returns it as a string, without the line break.

print("Type your name: ")
var name = readLine()
println("Hello " + name + ", welcome!")
readLine() on the boards

In 0.9.7, readLine() does not receive input over the serial port on the boards: the program waits forever. This happens to the examples that ask for data, such as CheckPrime or Palindromes. On Windows it works.

cls​

cls clears the console.

cls()

On a board, it sends through the serial port the terminal code that clears the screen.

ink / paper​

ink(color) changes the color of the text, and paper(color) that of the background, with a number from 0 to 15:

ColorNameColorName
0Black8Dark gray
1Blue9Light blue
2Green10Light green
3Cyan11Light cyan
4Red12Light red (with ink, orange)
5Magenta13Light magenta
6Brown14Yellow
7Light gray15White

With any other number they do nothing. On a board, they send through the serial port the terminal code of that color: the colors show in a terminal program that understands it, not in the IDE's Output.

ink(4)        // red text
println("This text is red")
ink(7) // back to light gray
paper(1) // blue background
println("Text with blue background")
paper(0) // back to the black background
ink and paper do nothing on Windows

In 0.9.7, ink() and paper() change no color on the Windows console: the text always comes out in the console's colors. They give no error either.

Time​

pause​

pause(ms) stops the program for ms milliseconds. It only takes integers: with a decimal it throws ERR_TYPE_MISMATCH.

println("This message comes out now.")
pause(3000)
println("And this one, 3 seconds later.")
  • While the pause lasts, the program does nothing else: whatever should fire in that time, such as a Timer callback, waits until it ends.
  • Do not use pause for the pace of a game: use Display.fps (see Display).

clock​

clock() returns the milliseconds since startup: on Windows, since the VM started; on a board, since the board started, and it keeps counting when the VM starts the program again. It is useful to measure how long something takes:

var start, finish, total_time
start = clock()

// Algorithm code would go here

finish = clock()
total_time = finish - start
println("The algorithm took ", total_time, " milliseconds")

time​

time() returns the date and time in a string, in English, in this format: the day of the week, the month, the day, the time and the year.

time(format) returns it as you say in format: each code with % is replaced by a piece of data, and the rest is copied as it is. The most useful codes are in the table below.

println(time())                    // Fri Nov  6 18:35:13 2026
println(time("%m/%d/%Y %H:%M")) // 11/06/2026 18:35
println(time("Today is %A")) // Today is Friday

(With the date and time of when you run it.)

CodeWhat it givesExample
%YThe year.2026
%yThe year, with two digits.26
%mThe month, from 01 to 12.11
%dThe day of the month, from 01 to 31.06
%eThe day of the month, with a space in front instead of the zero. 6
%HThe hour, from 00 to 23.18
%IThe hour, from 01 to 12.06
%pAM or PM.PM
%MThe minute, from 00 to 59.35
%SThe second, from 00 to 59.13
%A, %aThe day of the week, full or in three letters.Friday, Fri
%B, %bThe month, full or in three letters.November, Nov
%jThe day of the year, from 001 to 366.310
%uThe day of the week as a number, from 1 (Monday) to 7.5
%wThe day of the week as a number, from 0 (Sunday) to 6.5
%FThe date: %Y-%m-%d.2026-11-06
%TThe time: %H:%M:%S.18:35:13
%RThe hour and the minute: %H:%M.18:35
%%A %.%
  • The result can be up to 79 characters long. If it is longer, on Windows time returns an empty string.
  • On Windows, the date and time are the PC's. On a board, those of its clock (see Platforms).
A % code that does not exist closes the VM

On Windows, time() with a code that does not exist, such as time("%Q"), closes the VM without any message. Use the codes in the table.

Conversion and types​

chr​

chr(code) returns the character of an ASCII code, in a one-character string. chr(0) returns the empty string.

var letter = chr(65)
println(letter) // A

var newline = chr(10)
print("Line 1" + newline + "Line 2")

It only works for the ASCII codes, from 1 to 127: with a higher one it gives a single byte, which is not an accented letter.

int​

int(x) converts a decimal into an integer: it drops the decimal part (it truncates toward zero). It also converts booleans: true gives 1 and false, 0.

var decimal = 5.7
var integer = int(decimal)
println(integer) // 5
println(int(-5.7)) // -5

// Also works with booleans
println(int(true)) // 1
println(int(false)) // 0

It does not accept strings: int("7") throws ERR_TYPE_MISMATCH. To convert a string, use its toInt() method, for example text.toInt() (see Strings).

float​

float(x) converts an integer or a boolean into a decimal. It does not accept strings: float("3.5") throws ERR_TYPE_MISMATCH. To convert a string, use its toFloat() method, for example text.toFloat().

var integer = 10
var decimal = float(integer)
println(decimal) // 10

// Useful for operations requiring decimal precision
var result = float(5) / float(2)
println(result) // 2.5

println writes 10 and not 10.0: a decimal without a decimal part comes out without it (see print / println).

type​

type(x) returns an integer that says what type x is. Compare it with the t* constants:

func describe(v)
var t = type(v)
if (t == tInteger or t == tFloat) then
return "number"
elsif (t == tString) then
return "string"
elsif (t == tList) then
return "list"
end
return "something else"
end

println(describe(42)) // number
println(describe(2.5)) // number
println(describe("hello")) // string
println(describe([1, 2])) // list
println(describe(nil)) // something else
ConstantValueType
tBool0A boolean: true or false.
tNil1nil.
tInteger2An integer.
tFloat3A decimal.
tError4The error of a catch, or an error value from a function that failed.
tMethod6A method of an instance kept in a variable, such as var m = cat.meow.
tClass7A class.
tFunction9A function or a lambda.
tInstance10An instance of a class.
tNative11A VM function.
tString12A string.
tList13A list.
tMap14A map.
tArray15An array.
tFile16A file opened with File.open.
tBitmap17A bitmap, such as the one Bitmap.load returns.
tModule18A module, such as Display or Display.draw.
tAbstract20An object of a module: a sprite, a GridMap, a Bytes, an LED strip…
tEnumerator22An enum. Its values are integers: tInteger.
  • A struct gives 23, and the struct itself (its name, without creating anything) gives 24. They have no constant.
  • type is a reserved word: you cannot name a variable that way.

Random numbers​

randomize​

randomize(seed) seeds the random number generator with an integer. With the same seed, random() always gives the same sequence: it is useful to repeat a game or a test.

randomize(12345)  // Initialize with seed 12345

// Now random() will generate the same sequence each time
println(random(100)) // 67
Without randomize, always the same sequence

The generator always starts with the same seed: if you don't call randomize, random() gives the same sequence on every run. To make it change, seed it with a value that differs each time, such as randomize(clock()). Right at startup clock() barely changes from one run to the next, so call it after something that depends on the user, such as waiting for a key press. randomize only accepts integers.

random​

random gives a random number:

CallWhat it returns
random()Any 32-bit integer, negative ones too.
random(max)An integer from 0 to max, both included.
random(min, max)An integer from min to max, both included. The order does not matter: random(10, 1) is the same as random(1, 10).
random(min, max) with decimalsA decimal between min and max.
// An integer from 0 to 10
var a = random(10)

// An integer from 100 to 200
var b = random(100, 200)

// A decimal between 0.0 and 1.0
var c = random(0.0, 1.0)

// A decimal between -10.5 and 10.5
var d = random(-10.5, 10.5)
  • With two arguments, both must be of the same type: random(1, 2.5) throws ERR_TYPE_MISMATCH.
  • With a single decimal, random(5.0) does not give any decimal: it gives one without a decimal part, from 0 to 5. For a decimal, use random(0.0, 5.0).

Math​

The other math functions, such as Math.floor or Math.sin, are in the Math module.

abs​

abs(x) returns the absolute value of a number: the number without its sign. It returns an integer if x is an integer, and a decimal if it is a decimal.

println(abs(-5))    // 5
println(abs(8)) // 8
println(abs(-2.5)) // 2.5

round​

round(x) rounds to the nearest integer. If the number is exactly halfway, it is rounded away from zero: round(3.5) gives 4 and round(-2.5) gives -3. The result has the same type as the number: given a decimal it returns a decimal (round(3.5) is 4.0, even though println shows it as 4).

var number = 3.14159265
var rounded_number = round(number)
println(rounded_number) // 3

println(round(3.5)) // 4
println(round(3.49)) // 3
println(round(-2.5)) // -3

sqrt​

sqrt(x) returns the square root of a number, always as a decimal. With a negative number it throws no error: it returns NaN, the "not a number" value.

var x = 9
var result = sqrt(x)
println("The square root of ", x, " is ", result) // The square root of 9 is 3

println(sqrt(16)) // 4
println(sqrt(2)) // 1.4142135623730951

vlenght​

vlenght(x, y) calculates the length of a 2D vector from its components: √(x² + y²). It returns a decimal. It is spelled this way, vlenght.

var length = vlenght(3, 4)
println(length) // 5

// Useful for calculating distances
var distance = vlenght(10.5, 20.3)
println("Distance: ", distance) // Distance: 22.854758804240312

Collections​

len​

len(x) returns the length of a string, a list or a map: the bytes of the string, the elements of the list or the pairs of the map.

// With strings
var string = "Hello world"
println(len(string)) // 11

// With lists
var list = [1, 2, 3, 4, 5]
println(len(list)) // 5

// With maps
var map = {"a": 1, "b": 2, "c": 3}
println(len(map)) // 3
  • In a string it counts bytes: an accented letter counts as two. len("café") gives 5.
  • It does not accept arrays: with one it throws ERR_TYPE_MISMATCH. Use their size() method (see Lists, maps and arrays).

Colors​

rgb​

rgb(r, g, b) puts red, green and blue together, each from 0 to 255, into a color in the 0xRRGGBB format: the one used by draw.color and the other functions of Draw.

var orange = rgb(255, 128, 0)
println(orange) // 16744448
println(orange.toHex()) // FF8000
println(rgb(300, -5, 12.7) == rgb(255, 0, 12)) // true

A component above 255 stays at 255, a negative one at 0, and decimals are truncated.

System and memory​

memUse​

memUse() returns the bytes of memory the VM has reserved for the program at that moment.

var memory_used = memUse()
println("Memory used: ", memory_used, " bytes")

memFree​

memFree() returns the bytes of free memory. On Windows it always returns 0. On a board, it counts differently depending on the chip: see Platforms, and the memory of each board in Memory and limits.

var free_memory = memFree()
println("Free memory: ", free_memory, " bytes")

How the VM frees memory, in the GC module.

platform​

platform() returns an integer that says where the program runs:

ValuePlatformConstant
0Unknown platform—
1ESP32HW_ESP32
2ESP32-S3HW_ESP32S3
3Reserved—
4WindowsHW_WIN32
5ReservedHW_WEB
6ESP32-P4HW_ESP32P4
7ESP32-S31HW_ESP32S31

Rather than comparing against the number, use the constants: they read better.

var plat = platform()

if (plat == HW_ESP32 or plat == HW_ESP32S3 or plat == HW_ESP32P4 or plat == HW_ESP32S31) then
println("Running on an ESP32")
elsif (plat == HW_WIN32) then
println("Running on Windows")
else
println("Unknown platform")
end
Note

Value 3 is reserved. It belonged to the old RISC-V VM for the K210 (Kendryte/Maixduino), which was retired when that chip was discontinued. It will not be reused for any new platform, so no program can ever receive that value. The HW_RISCV constant that named it no longer exists: if your code used it, replace it with whichever check applies. The RISC-V platforms JARU supports today are the ESP32-P4 (HW_ESP32P4) and the ESP32-S31 (HW_ESP32S31).

Value 5, HW_WEB, belongs to a VM for the browser, which 0.9.7 does not have: no program receives it.

vmerror​

vmerror() should return the code of the last error, but it cannot tell you whether something failed.

vmerror() always returns 0

In 0.9.7, vmerror() returns 0 even when there have been errors. To detect an error, use try and catch: see Errors and exceptions.

Base64 encoding​

encode64​

The encode64 function encodes a text string to Base64 format. It's useful for transmitting binary data in text formats or for encoding credentials.

var text = "Hello World"
var encoded = encode64(text)
println(encoded) // SGVsbG8gV29ybGQ=

decode64​

The decode64 function decodes a Base64 string and returns the original text.

var encoded = "SGVsbG8gV29ybGQ="
var decoded = decode64(encoded)
println(decoded) // Hello World
Common usage

Base64 is very useful for sending data through protocols that only support text, such as HTTP or MQTT.

use MQTT

// Example: encode sensor data to send over MQTT
var data = "temperature:25.5,humidity:60"
var payload = encode64(data)
MQTT.publish("sensors/data", payload)

Constants​

The compiler knows them, and they can be used in any file without use:

ConstantsValueWhat for
HW_ESP32, HW_ESP32S3, HW_WIN32, HW_WEB, HW_ESP32P4, HW_ESP32S311, 2, 4, 5, 6 and 7What platform() returns.
tBool … tEnumeratorFrom 0 to 22The types of type().
ERR_UNKNOWN … ERR_TIME_OUTFrom 1 to 29The errors: see Errors and exceptions.
LOW, HIGH0 and 1The levels of a pin: see GPIO.
PIπ: println(PI) writes 3.141592653589793See Math.
SQRT2√2: println(SQRT2) writes 1.4142135623730951See Math.

Full example​

It rolls a die 600 times, counts how many times each face comes up and measures how long it takes:

// With the same seed, the rolls are always the same.
randomize(2026)
var times = [0, 0, 0, 0, 0, 0]
var start = clock()
for (var i = 0; i < 600; i = i + 1)
var face = random(1, 6)
times[face - 1] = times[face - 1] + 1
end

var expected = 600 div 6
for (var f = 1; f <= 6; f = f + 1)
var n = times[f - 1]
println("Face ", f, ": ", n, " times (", abs(n - expected), " off)")
end
println("It took ", clock() - start, " ms")
Face 1: 100 times (0 off)
Face 2: 112 times (12 off)
Face 3: 109 times (9 off)
Face 4: 87 times (13 off)
Face 5: 97 times (3 off)
Face 6: 95 times (5 off)
It took 2 ms

The last line changes from one run to the next.

Pitfalls and known issues​

  • Without randomize, random() always repeats the same sequence (see randomize).
  • println writes the digits the decimal has: 0.1 + 0.2 comes out as 0.30000000000000004, because it isn't exactly 0.3. To show it rounded, use toString() (see print / println).
  • int and float do not convert strings: use toInt() and toFloat().
  • len counts bytes in strings, and does not accept arrays.
  • readLine() gets nothing on the boards (see readLine).
  • ink and paper do nothing on Windows (see ink / paper).
  • time() with a % code that does not exist closes the VM on Windows (see time).
  • vmerror() always returns 0 (see vmerror).
  • type() with an error value leaves the VM's stack out of place (see type).

All the known issues of JARU, together, are in Known issues.