Rhai Language Cheat Sheet 14. November 2025

Single-page reference for the Rhai scripting language. All snippets are valid Rhai code; most examples assume default engine settings.

What this page is for

  • Quick lookup of Rhai syntax and behavior
  • Discovering lesser-known language features
  • Comparing Rhai with other scripting languages

What this page is not

  • Full engine / embedding guide (see the Book)
  • Exhaustive standard-library reference
  • Advice on Rust-side integration
Font Ligatures (..=, =>) Night Mode 💡

Basics

Data & Collections

Control Flow

Functions & Modules

Advanced

Standard Functions

Hello, Rhaiurl

// Rhai scripts are plain text files evaluated by a host application.
// This is a minimal self-contained example.

let name = "world";
print(`Hello, ${name}!`);

Key ideas:

  • Execution is statement-based; the last statement of a block is also its value.
  • Types are inferred at runtime, but operations are strongly typed (no implicit casts).
  • The host (Rust) decides which functions/types are available to the script.

Values & Typesurl

Primitive value categories in Rhai (see book/src/language/values-and-types.md):

CategoryExamplestype_of() resultNotes
Integer0, -1, 42, 0xFF"i64" / "i32"Default integer type is INT (i64 by default, i32 with only_i32).
Float1.0, -3.14, 2e-3"f64" / "f32"Enabled unless compiled with no_float.
Decimaldecimal(1.23)"decimal"Requires the decimal feature; precise fixed-point.
Booltrue, false"bool"Logical operations use &&, ||, !.
Char'a', '#', '\u2764'"char"Unicode scalar value, single quotes.
String"hello""string"Immutable strings; backticks enable interpolation.
Array[1, 2, 3]"array"Heterogeneous, indexable via [i].
Object map#{ x: 1, y: 2 }"map"String-keyed map; #{ "x": 1 } also valid.
Blob (byte array)#[1, 2, 255], #[0xAA]"blob"u8 values; useful for binary protocols.
Timestampnow()"timestamp"Requires no_time disabled.
Function pointerFn("foo")"Fn"Callable via call / curry.
Dynamicany of the aboveactual type nameDynamic is the internal catch‑all value type.

Notes:

  • type_of(x) returns a string describing the runtime type.
  • to_string() and string interpolation use the display representation of a value.
  • Many feature flags (no_float, no_index, no_time, …) can disable parts of the language at engine compile time.

See also in the Rhai Book: Values and Types.

Variables & Constantsurl

let x = 42;          // mutable variable
let y;               // defaults to ()
const PI = 3.14159;  // compile-time constant
  • let declares a mutable variable in the current scope.
  • If no initial value is provided, the variable is created with value ().
  • const declares an immutable constant; the initializer must be constant‑foldable.
  • Names must:
    • contain only ASCII letters, digits, and _,
    • contain at least one ASCII letter,
    • not start with a digit once leading _ are skipped,
    • not be a keyword.

Shadowing:

let x = 1;
{
    let x = 2;   // shadows outer x within this block
    print(x);    // 2
}
print(x);        // 1

See also in the Rhai Book: Variables and Constants.

Comments & Doc Commentsurl

// Line comment
/* Block comment */
/// Doc comment for a function or variable
//! Doc comment for the enclosing module / script
  • // comments extend to the end of the line.
  • /* ... */ comments can span multiple lines.
  • /// attaches documentation to the following item (usually a function).
  • //! attaches documentation to the current module/file.

See also in the Rhai Book: Comments and Doc Comments.

Statements & Blocksurl

let x = 40 + 2;      // statement (terminated by `;`)

let y = {
    let tmp = 40;
    tmp + 2          // last statement: block value is 42
};                   // block used as an expression
  • Statements are normally terminated with ;.
  • Semicolons can be omitted:
    • for the last statement in a block, and
    • for statements that syntactically end with a block (if, while, for, loop, switch).
  • A block { ... } introduces a new scope:
    • variables/constants declared inside do not escape the block;
    • the block’s value is the value of its last statement (even if it ends with ;).
  • Blocks can appear inside expressions (“statement expressions”), which is helpful to compute a sub‑expression once and reuse it.

See also in the Rhai Book: Statements and Statement Expressions.

Keywordsurl

Selected active keywords (see book/src/language/keywords.md for the full list):

CategoryKeywords
Booleanstrue, false
Bindingslet, const, global
Control flowif, else, switch, do, while, loop, for, in, break, continue
Functionsfn, private, return, this, is_def_fn
Errorsthrow, try, catch
Modulesimport, export, as
Dynamictype_of, eval, is_def_var, is_shared
SpecialFn, call, curry, print, debug

Keywords cannot be used as variable or function names, even if a feature flag disables their behavior.

See also in the Rhai Book: Keywords.

Numbers & Operatorsurl

Numeric literalsurl

let a = 42;          // decimal
let b = 0b1010;      // binary
let c = 0o755;       // octal
let d = 0xFF;        // hexadecimal
let f = 1.23e-4;     // float (if enabled)
let big = 1_000_000; // `_` separators ignored

Arithmetic & comparisonurl

x + y;  x - y;  x * y;  x / y;  x % y;

x < y;  x <= y;  x > y;  x >= y;  x == y;  x != y;
  • Operators are strongly typed; incompatible types cause script errors.
  • Comparisons are defined only for certain type combinations.
  • Integer division truncates toward zero.

Assignment operatorsurl

let x = 1;
x += 2;   // 3
x -= 1;   // 2
x *= 2;   // 4
x /= 2;   // 2
x %= 2;   // 0

Bit operators (on integers):

x & y;   x | y;   x ^ y;
!x;      // bitwise NOT on integers
x << n;  x >> n;  // shifts

Logical operators (on booleans):

a && b;  a || b;  !a;

Short‑circuiting rules are the usual: && stops when the left side is false, || stops when the left side is true.

Null-coalescing ??url

let value = maybe() ?? 42;        // default 42 if maybe() returns ()

let x = map.foo ?? 0;             // default for missing property

for v in list {
    total += calculate(v) ?? break;   // stop loop when calculation yields ()
}
  • a ?? b returns a if it is not (), otherwise b.
  • The right-hand side is evaluated only if the left-hand side is (), so it short‑circuits.
  • After ?? you can also use break, continue, return or throw to short‑circuit loops or functions.

See also in the Rhai Book: Numbers, Numeric Operators, Numeric Functions, and Logic.

Strings & Interpolationurl

let s1 = "hello";              // basic string
let s2 = "hello\nworld";       // escapes: \n, \t, \uXXXX, ...
let name = "Rhai";
let s3 = `Hello, ${name}!`;    // interpolation with backticks
  • Double quotes "..." create normal strings with escapes.
  • Backticks `...` enable interpolation: ${expr} is replaced with the string value of expr.
  • Strings are immutable; methods return new strings.

Selected string methods (see book/src/language/string-fn.md):

ExampleDescription
"abc".lenLength in Unicode scalar values.
"abc" + "def"Concatenation.
"abc".pad(5, "_")Pad to width.
"abc".to_upper()Uppercase; also to_lower().
"hello".find("ll")Index of substring or -1.
"hello".substr(1, 3)Substring (start, length).
"hello".replace("l", "L")Replace occurrences.

Characters:

let ch = '❤';
let code = ch.to_int();   // numeric code point

See also in the Rhai Book: Strings and Characters, String Interpolation, and String Functions.

Arraysurl

let list = [1, 2, 3];
let mixed = [1, "two", true];

list[0];        // first element
list[-1];       // from the end
list.len;       // number of elements
list.push(4);   // append
  • Arrays are zero‑based; negative indices count from the end (-1 is the last element).
  • Out‑of‑bounds access raises an error by default (see arrays-oob.md).
  • Arrays can hold any mix of value types (they are arrays of Dynamic).
  • Common methods (see arrays.md):
ExampleDescription
list.lenLength.
list.push(x)Append element.
list.pop()Remove and return last element.
list.insert(i, x)Insert at index.
list.remove(i)Remove element at index.
list.clear()Remove all elements.
list += [4, 5]Concatenate arrays.

See also in the Rhai Book: Arrays and Array Out-of-Bounds Access.

Object Mapsurl

let point = #{ x: 1, "y": 2 };

point.x = 42;
let y = point["y"];

if "z" in point {
    print(point.z);
}
  • Object maps are string‑keyed maps.
  • Keys can be written as identifiers (x: 1) or quoted strings ("x": 1).
  • Access:
    • Dot syntax map.key is sugar for map["key"].
    • Indexing with map[key] uses the runtime value of key.
  • Missing properties can be handled explicitly (see object-maps-missing-prop.md):
    • Accessing a non‑existing property normally errors.
    • Engines can be configured to auto‑create properties instead.

Object maps can also be used in an OOP‑style (see object-maps-oop.md) where methods are attached via the host.

See also in the Rhai Book: Object Maps, Missing Properties, and Object Maps as Objects.

BLOBs & Binary Dataurl

let data = #[0xDE, 0xAD, 0xBE, 0xEF];
data.len;          // length in bytes
data[0] = 0xFF;    // mutate
  • BLOBs are arrays of u8 values; available when no_index is disabled.
  • Useful for binary protocols, hashing, cryptography, etc.
  • Many array operations work on BLOBs as well (length, indexing, loops).

See also in the Rhai Book: BLOBs.

JSON & Timestampsurl

// Host-provided helper (usually exposed from Engine::parse_json)
let obj = parse_json(`{ "x": 1, "y": 2 }`);
obj.x == 1;                     // object map: #{ x: 1, y: 2 }

let t = now();
let elapsed = elapsed_ms(t);
  • parse_json converts JSON text into Rhai values when the host exposes it:
    • objects → object maps,
    • arrays → arrays,
    • numbers / strings / booleans / null → matching Rhai primitives (null()).
  • Timestamps (see timestamps.md):
    • now() returns the current timestamp.
    • Helper functions can compute durations (depends on the host’s API registration).

See also in the Rhai Book: JSON and Timestamps.

Control Flowurl

if / elseurl

if condition {
    do_something();
} else if other {
    do_other();
} else {
    fallback();
}

let max = if x > y { x } else { y };
  • if conditions must be booleans.
  • if is an expression: the last statement of the taken branch is the value.

switchurl

switch x {
    0          => print("zero"),
    1 | 2      => print("small"),
    3..=10     => print("medium"),
    _          => print("other"),
}
  • Patterns can be literals, ranges, or _ (catch‑all).
  • Multiple patterns can be combined with |.
  • switch is also an expression; the chosen branch’s last statement is the value.

Loopsurl

while cond {
    work();
}

loop {
    if done { break; }
}

do { work(); } while cond;   // run‑at‑least‑once
  • while checks the condition before each iteration.
  • do { ... } while cond checks after the first run.
  • loop { ... } is an infinite loop; exit with break or return.
  • break exits the current loop; continue jumps to the next iteration.

for loops and inurl

for x in 0..10 {
    print(x);
}

for item in array {
    print(item);
}

for key in map {
    print(key);          // iterates keys
}
  • The right side of in must be iterable:
    • ranges, arrays, BLOBs, strings, object maps (keys), and any type with an iterator registered.
  • Loop variable is created fresh for each iteration; assignments to it do not affect the original collection element unless the engine is configured for shared values.

See also in the Rhai Book: If, Switch, Switch as Expression, Loop, While, Do-While, For, In, Iterators, and Ranges.

Error Handlingurl

throw "something went wrong";

let result = try {
    risky();
} catch (err) {
    print(`Error: ${err}`);
    "default"
};
  • throw expr aborts the current script with an error value.
  • try { ... } catch (err) { ... } evaluates the block and catches throw‑n values:
    • on success, the try block value is returned;
    • on error, the catch block runs with the error bound to err.
  • Error values are typically strings but can be any type.

See also in the Rhai Book: Try / Catch and Throw.

Functions & Methodsurl

fn add(x, y) {
    x + y          // last statement is the return value
}

fn abs(x) {
    if x < 0 { -x } else { x }
}

let z = add(1, 2);        // 3
  • fn defines a script function.
  • Parameters are dynamically typed; default arguments are not supported directly but can be simulated with ().
  • return expr; can be used to exit early from a function; without return the last statement is the result.
  • Functions are visible in their module; mark them private to hide from module exports.

Method calls:

fn length(s) { s.len }

let n = "hello".length();     // calls length("hello")
  • value.method(args...) is sugar for method(value, args...) when such a function exists.
  • Inside a method defined with a this parameter, this refers to the receiver:
fn inc(this) { this + 1 }
let x = 1.inc();              // 2

See also in the Rhai Book: Functions, Methods, and Function Metadata.

Closures & Anonymous Functionsurl

let times_two = |x| x * 2;

let base = 10;
let add_base = |x| x + base;   // captures `base`

let result = add_base(5);      // 15
  • Anonymous functions/closures can be created with |params| expr syntax (see fn-closure.md and fn-anon.md).
  • Captured variables are shared via reference‑counted Dynamic values.
  • Closures can be stored in variables, passed to other functions, or converted into function pointers.

See also in the Rhai Book: Closures and Anonymous Functions.

Function Pointers & Curryingurl

let f = Fn("add");        // pointer to function `add`
let r = f.call(1, 2);     // call via pointer

let plus_one = f.curry(1);  // partial application
let three = plus_one.call(2);
  • Fn(name) creates a function pointer referring to a global function.
  • fp.call(args...) invokes the function.
  • fp.curry(fixed_args...) creates a new function pointer with arguments pre‑applied.

See also in the Rhai Book: Function Pointers and Currying.

Modules & Globalsurl

import "math" as math;

let x = math::sqrt(2);

export fn helper(x) { x * 2 }

global my_global = 42;
  • import "path" as name; loads a module, making its exported functions/variables available under name::.
  • export in a script marks functions/variables to be visible when that script is used as a module.
  • global promotes a module into a global namespace, making its exports available without a prefix (depends on engine configuration).
  • Module creation and registration is done on the host side; from Rhai scripts you only use import/export/global.

See also in the Rhai Book: Modules, Import, Export, and Global Modules.

Dynamic Typingurl

let x = 1;
x = "now a string";

let t = type_of(x);   // "string"
  • Variables can hold values of any type; a variable’s type can change over time.
  • type_of(value) returns the current runtime type as a string.
  • Many APIs take or return Dynamic, which is Rhai’s internal “any” type.

Shared values (see dynamic.md and dynamic-tag.md):

  • Closures capture variables by reference into shared Dynamic values.
  • is_shared(value) tests whether a value is shared.

See also in the Rhai Book: Dynamic Values, Dynamic and Rust, and Dynamic Tagging.

Shadowing & Scopeurl

let x = 1;

if true {
    let x = 2;    // shadows outer `x`
    const PI = 3.14;
}

print(x);         // 1
// PI is not visible here
  • Each block ({ ... }) creates a new scope.
  • Variables/constants defined inside are destroyed at the end of the block.
  • Shadowing is allowed and common, especially in loops or narrow scopes.

See also in the Rhai Book: Shadowing and Global.

Debugging & Introspectionurl

print("hello");          // user-facing output
debug(some_value);       // debug representation

let t = type_of(some_value);
print(`type: ${t}`);
  • print(value) writes a human‑readable representation (destination controlled by the host).
  • debug(value) writes a more verbose/debug‑oriented representation.
  • type_of(value) returns a string describing the runtime type.

When things go wrong:

  • Use try / catch around suspicious code to surface error values.
  • Add temporary print/debug calls in branches and loops.

See also in the Rhai Book: Print and Debug, Type Of, and Eval.

Standard Functionsurl

Most of Rhai’s “standard library” lives in built-in packages (e.g. BasicMathPackage, MoreStringPackage). These functions are available unless you use a raw Engine or disable the corresponding package/feature.

Numericurl

CategoryFunctionsNotes
Integer predicatesis_odd, is_even, is_zeroOdd/even/zero tests (also as methods/properties).
Sign & absabs, signsign returns −1, 0, or +1.
Min/maxmin, maxSmaller/larger of two numbers (ints, floats, decimals).
Trigonometrysin, cos, tan, sinh, cosh, tanh, asin, acos, atan(v), atan(x, y), asinh, acosh, atanhAngles in radians.
Root & expsqrt, expSquare root and exp(e).
Logsln, log(x), log(x, base)Natural, base‑10, and arbitrary‑base logs.
Roundingfloor, ceiling, round([digits]), int, fractionExtra decimal-only variants: round_up, round_down, round_half_up, round_half_down.
Conversionsto_int, to_float, to_decimal, to_degrees, to_radiansBetween numeric types and degrees/radians.
Float testsis_nan, is_finite, is_infiniteMethods/properties on floats/decimals.
Parsingparse_int([radix]), parse_float, parse_decimalFrom string to numbers.
Formattingto_binary, to_octal, to_hexFrom integer to formatted string.
ConstantsPI, EReturn π and e.

Stringsurl

CategoryFunctionsNotes
Length & emptinesslen, bytes, is_emptyCharacter vs byte length.
Caseto_upper, to_lower, make_upper, make_lowerto_* returns new string; make_* mutates.
TrimmingtrimStrip leading and trailing whitespace.
Searchcontains, starts_with, ends_with, index_of(needle[, start])index_of returns index or −1.
Substringssub_string(start, len), sub_string(range), crop(start[, len]), crop(range)Extract portions of a string.
Splittingsplit(delim[, max]), split_rev(delim[, max])Split into an array of segments.
Building & editpad, append, remove, pop, clear, truncate, replaceBuild and mutate strings.
Conversionto_blob, to_charsTo BLOB or array of characters.
Iterationchars(start[, len])Iterate over characters (also takes a range).
Comparisonmin, maxLexicographic min/max of two characters/strings.

Arraysurl

CategoryFunctionsNotes
Index & updateget, set, insert, removeBy index; negative indices count from the end.
Sizelen, is_emptyNumber of elements / emptiness.
Add/removepush, pop, shift, chop, clearAppend, remove last/first, trim head/tail, empty array.
Concatenateappend, +, +=Join arrays or append single elements.
Slicingextract(start[, len]), extract(range), split, pad, truncateSlice or resize arrays.
Searchcontains, index_of, find, find_mapMembership tests and searches (often via closures).
Dedup & zipdedup, zipRemove consecutive duplicates; zip two arrays.
Higher-orderfor_each, map, filter, some, all, reduce, reduce_revFunctional-style processing with closures.
Sortingsort(), sort(cmp)Sort homogeneous arrays or via a comparison closure.

The in operator on arrays is based on contains and the == operator for the element type.

BLOBsurl

CategoryFunctionsNotes
Constructionblob(len?, value?)Create a BLOB, optionally with initial length and fill value.
Conversionto_array, as_stringTo array of bytes or UTF‑8 string.
Index & updateget, set, insert, removeIndex and modify bytes; negative indices count from the end.
Size & clearlen, is_empty, clear, truncateSize/emptiness and length changes.
Add/concatpush, append, +, +=Append bytes, BLOBs, or strings; concatenate.
Slicingextract(start[, len]), extract(range), split, drain, retain, spliceVarious ways to cut or replace slices.
Compare==, !=Compare two BLOBs.
Parsingparse_le_int, parse_be_int, parse_le_float, parse_be_floatParse integers/floats from byte ranges.
Writingwrite_le, write_be, write_utf8, write_asciiWrite integers/floats or strings into a BLOB.

Object Mapsurl

CategoryFunctionsNotes
Index & updateget, set, removeGet/set/remove properties (missing keys return ()).
Size & clearlen(), is_empty, clearNumber of properties / emptiness.
Merge/mix+=, mixin, +, fill_withCombine maps; fill missing keys from another map.
Compare==, !=Compare maps element‑wise using ==.
Membershipcontains, inCheck if a property exists.
Keys & valueskeys, valuesArrays of property names/values (order not guaranteed).
Filteringdrain, retain, filterKeep/remove entries based on predicate functions.
JSONto_jsonConvert map to JSON string (when supported by host).

Ranges & Bit-fieldsurl

CategoryFunctionsNotes
Rangesstart, end, contains, is_empty, is_inclusive, is_exclusiveMethods/properties on numeric ranges.
Range ctorrange(start, end[, step])Build numeric ranges (also for floats).
Bit-fieldget_bit, set_bit, get_bits, set_bits, bits(start[, len]), bits(range)Inspect and manipulate bits of an integer.

Timeurl

CategoryFunctionsNotes
Timetimestamp()Current timestamp value.
Elapsedts.elapsedSeconds since timestamp.
Mathts + seconds, ts - seconds, ts += seconds, ts -= seconds, later_ts - earlier_tsAdd/subtract time or compute differences.
Sleepsleep(seconds)Block current thread for given seconds.

Function pointers & metadataurl

CategoryFunctionsNotes
PointerFn("name")Create a function pointer by name.
Inspectfp.type_of(), fp.name, fp.is_anonymousType is "Fn"; inspect target name.
Callfp.call(args...)Invoke the referenced function.
Metadataget_fn_metadata_list([name[, params]])Array of maps describing script functions.

Misc & introspectionurl

CategoryFunctionsNotes
Printingprint(value), debug(value)User‑facing vs debug output.
Type infotype_of(value)Runtime type as string.
Stringifyto_string(value), to_debug(value)Convert value to display/debug strings.
Evaluationeval(script)Evaluate Rhai source inside current scope (use with care).
Dynamic/sharedis_shared(value)Test whether a value is shared (e.g. captured by a closure).