# Technical Documentation: rhaiscript/rhai

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/rhaiscript/rhai)

### Overview (`README.md`)

Rhai - Embedded Scripting for Rust
==================================


[](https://github.com/rhaiscript/rhai/actions)
[](https://github.com/rhaiscript/rhai)
[](https://github.com/license/rhaiscript/rhai)
[](https://crates.io/crates/rhai/)
[](https://crates.io/crates/rhai/)
[](https://docs.rs/rhai/)
[](https://marketplace.visualstudio.com/items?itemName=rhaiscript.vscode-rhai)
[](https://plugins.jetbrains.com/plugin/30068-rhai-language-support)
[](https://packagecontrol.io/packages/Rhai)
[](https://discord.gg/HquqbYFcZ9)
[](https://www.reddit.com/r/Rhai)

[](https://rhai.rs)

Rhai is an embedded scripting language and evaluation engine for Rust that gives a safe and easy way
to add scripting to any application.


Targets and builds
------------------

* All CPU and O/S targets supported by Rust, including:
  * WebAssembly (WASM)
  * `no-std`
* Minimum Rust version 1.66.0


Standard features
-----------------

* Simple language similar to JavaScript+Rust with [dynamic](https://rhai.rs/book/language/dynamic.html) typing.
* Fairly efficient evaluation - 1 million iterations in 0.14 sec on a single-core 2.6 GHz Linux VM running [this script](https://github.com/rhaiscript/rhai/blob/main/scripts/speed_test.rhai) by the standard AST walker.
* [Rhai Grain](https://rhai.rs/book/grain/index.html) bytecodes compiler and VM for even faster evaluation (around 1.8-2x). Enable with the `grain` feature.
* Tight integration with native Rust [functions](https://rhai.rs/book/rust/functions.html) and [types](https://rhai.rs/book/rust/custom-types.html), including [getters/setters](https://rhai.rs/book/rust/getters-setters.html), [methods](https://rhai.rs/book/rust/methods.html) and [indexers](https://rhai.rs/book/rust/indexers.html).
* Freely pass Rust values into a script as [variables](https://rhai.rs/book/language/variables.html)/[constants](https://rhai.rs/book/language/constants.html) via an external [`Scope`](https://rhai.rs/book/engine/scope.html) - all clonable Rust types are supported; no need to implement any special trait. Or tap directly into the [variable resolution process](https://rhai.rs/book/engine/var.html).
* Built-in support for most common [data types](https://rhai.rs/book/language/values-and-types.html) including booleans, [integers](https://rhai.rs/book/language/numbers.html), [floating-point numbers](https://rhai.rs/book/language/numbers.html) (including [`Decimal`](https://crates.io/crates/rust_decimal)), [strings](https://rhai.rs/book/language/strings-chars.html), [Unicode characters](https://rhai.rs/book/language/strings-chars.html), [arrays](https://rhai.rs/book/language/arrays.html) (including packed [byte arrays](https://rhai.rs/book/language/blobs.html)) and [object maps](https://rhai.rs/book/language/object-maps.html).
* Easily [call a script-defined function](https://rhai.rs/book/engine/call-fn.html) from Rust.
* Relatively little `unsafe` code (yes there are some for performance reasons).
* Few dependencies - currently only [`smallvec`](https://crates.io/crates/smallvec), [`thin-vec`](https://crates.io/crates/thin-vec), [`num-traits`](https://crates.io/crates/num-traits), [`once_cell`](https://crates.io/crates/once_cell), [`ahash`](https://crates.io/crates/ahash), [`bitflags`](https://crates.io/crates/bitflags) and [`smartstring`](https://crates.io/crates/smartstring).
* Re-entrant scripting engine can be made `Send + Sync` (via the `sync` feature).
* Compile once to [AST](https://rhai.rs/book/engine/compile.html) form for repeated evaluations.
* Scripts are [optimized](https://rhai.rs/book/engine/optimize) (useful for template-based machine-generated scripts).
* Easy custom API development via [plugins](https://rhai.rs/book/plugins) system powered by procedural macros.
* [Function overloading](https://rhai.rs/book/language/overload.html) and [operator overloading](https://rhai.rs/book/rust/operators.html).
* Dynamic dispatch via [function pointers](https://rhai.rs/book/language/fn-ptr.html) with additional support for [currying](https://rhai.rs/book/language/fn-curry.html).
* [Closures](https://rhai.rs/book/language/fn-closure.html) (anonymous functions) that can capture shared values.
* Some syntactic support for [object-oriented programming (OOP)](https://rhai.rs/book/patterns/oop.html).
* Organize code base with dynamically-loadable [modules](https://rhai.rs/book/language/modules), optionally [overriding the resolution process](https://rhai.rs/book/rust/modules/resolvers.html).
* Serialization/deserialization support via [serde](https://crates.io/crates/serde) (requires the `serde` feature).
* Support for [minimal builds](https://rhai.rs/book/start/builds/minimal.html) by excluding unneeded language [features](https://rhai.rs/book/start/features.html).
* A [debugging](https://rhai.rs/book/engine/debugging) interface.


Protected against attacks
-------------------------

* [_Don't Panic_](https://rhai.rs/book/safety/index.html#dont-panic-guarantee--any-panic-is-a-bug) guarantee - Any panic is a bug. Rhai subscribes to the motto that a library should never panic the host system, and is coded with this in mind.
* [Sand-boxed](https://rhai.rs/book/safety/sandbox.html) - the scripting engine, if declared immutable, cannot mutate the containing environment unless [explicitly permitted](https://rhai.rs/book/patterns/control.html).
* Rugged - protected against malicious attacks (such as [stack-overflow](https://rhai.rs/book/safety/max-call-stack.html), [over-sized data](https://rhai.rs/book/safety/max-string-size.html), and [runaway scripts](https://rhai.rs/book/safety/max-operations.html) etc.) that may come from untrusted third-party user-land scripts.
* Track script evaluation [progress](https://rhai.rs/book/safety/progress.html) and manually terminate a script run.
* Passes Miri.


For those who actually want their own language
----------------------------------------------

* Use as a [DSL](https://rhai.rs/book/engine/dsl.html).
* Disable certain [language features](https://rhai.rs/book/engine/options.html#language-features) such as [looping](https://rhai.rs/book/engine/disable-looping.html).
* Further restrict the language by surgically [disabling keywords and operators](https://rhai.rs/book/engine/disable-keywords.html).
* Define [custom operators](https://rhai.rs/book/engine/custom-op.html).
* Extend the language with [custom syntax](https://rhai.rs/book/engine/custom-syntax.html).


Example
-------

The [`scripts`](https://github.com/rhaiscript/rhai/tree/master/scripts) subdirectory contains sample Rhai scripts.

Below is the standard _Fibonacci_ example for scripting languages:

```ts
// This Rhai script calculates the n-th Fibonacci number using a
// really dumb algorithm to test the speed of the scripting engine.

const TARGET = 28;
const REPEAT = 5;
const ANSWER = 317_811;

fn fib(n) {
    if n < 2 {
        n
    } else {
        fib(n-1) + fib(n-2)
    }
}

print(`Running Fibonacci(${TARGET}) x ${REPEAT} times...`);
print("Ready... Go!");

let result;
let now = timestamp();

for n in 0..REPEAT {
    result = fib(TARGET);
}

print(`Finished. Run time = ${now.elapsed} seconds.`);

print(`Fibonacci number #${TARGET} = ${result}`);

if result != ANSWER {
    print(`The answer is WRONG! Should be ${ANSWER}!`);
}
```

Project Site
------------

[`rhai.rs`](https://rhai.rs)


Documentation
-------------

See [_The Rhai Book_](https://rhai.rs/book) for details on the Rhai scripting engine and language.


Playground
----------

An [_Online Playground_](https://rhai.rs/playground) is available with syntax-highlighting editor,
powered by WebAssembly.

Scripts can be evaluated directly from the editor.


License
-------

Licensed under either of the following, at your choice:

* [Apache License, Version 2.0](https://github.com/rhaiscript/rhai/blob/master/LICENSE-APACHE.txt), or
* [MIT license](https://github.com/rhaiscript/rhai/blob/master/LICENSE-MIT.txt)

Unless explicitly stated otherwise, any contribution intentionally submitted
for inclusion in this crate, as defined in the Apache-2.0 license, shall
be dual-licensed as above, without any additional terms or conditions.

---

### Overview (`benches/README.md`)

Micro Benchmarks
================

Micro benchmarks to measure the speed of Rhai.

As with all micro benchmarks, take these with a grain of salt.


How to Run
----------

```bash
cargo +nightly bench
```

---

### Overview (`codegen/README.md`)

Procedural Macros for Plugins
=============================



This crate holds procedural macros for code generation, supporting the plugins system
for [Rhai](https://github.com/rhaiscript/rhai).

This crate is automatically referenced by the [Rhai crate](https://crates.io/crates/rhai).
Normally it should not be used directly.

---

### Overview (`examples/README.md`)

# Sample Applications

## Standard Examples

| Example                                                   | Description                                                                                                                                         |
| --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`arrays_and_structs`](arrays_and_structs.rs)             | shows how to register a Rust type and using it with arrays                                                                                          |
| [`callback`](callback.rs)                                 | shows how to store a Rhai closure and call it later within Rust                                                                                     |
| [`custom_types_and_methods`](custom_types_and_methods.rs) | shows how to register a Rust type and methods/getters/setters for it                                                                                |
| [`custom_types`](custom_types.rs)                         | shows how to register a Rust type and methods/getters/setters using the `CustomType` trait.                                                         |
| [`definitions`](./definitions)                            | shows how to generate definition files for use with the [Rhai Language Server](https://github.com/rhaiscript/lsp) (requires the `metadata` feature) |
| [`grain_bench`](grain_bench.rs)                           | comparison benchmarks for Rhai Grain bytecodes VM                                                                                                   |
| [`hello`](hello.rs)                                       | simple example that evaluates an expression and prints the result                                                                                   |
| [`lazy_bench`](lazy_bench.rs)                             | comparison benchmarks for lazy-loading                                                                                                              |
| [`pause_and_resume`](pause_and_resume.rs)                 | shows how to pause/resume/stop an `Engine` running in a separate thread via an MPSC channel                                                         |
| [`reuse_scope`](reuse_scope.rs)                           | evaluates two pieces of code in separate runs, but using a common `Scope`                                                                           |
| [`serde`](serde.rs)                                       | example to serialize and deserialize Rust types with [`serde`](https://crates.io/crates/serde) (requires the `serde` feature)                       |
| [`simple_fn`](simple_fn.rs)                               | shows how to register a simple Rust function                                                                                                        |
| [`strings`](strings.rs)                                   | shows different ways to register Rust functions taking string arguments                                                                             |
| [`threading`](threading.rs)                               | shows how to communicate in duplex with an `Engine` running in a separate thread via a pair of MPSC channels                                        |

## Scriptable Event Handler With State Examples

Because of its popularity, included are sample implementations for the pattern
[_Scriptable Event Handler With State_](https://rhai.rs/book/patterns/events.html) in different styles.

| Example                                    | Handler Script                                                     |                         Description                         |
| ------------------------------------------ | ------------------------------------------------------------------ | :---------------------------------------------------------: |
| [`event_handler_main`](event_handler_main) | [`event_handler_main/script.rhai`](event_handler_main/script.rhai) | [_Main Style_](https://rhai.rs/book/patterns/events-1.html) |
| [`event_handler_js`](event_handler_js)     | [`event_handler_js/script.rhai`](event_handler_js/script.rhai)     |  [_JS Style_](https://rhai.rs/book/patterns/events-2.html)  |
| [`event_handler_map`](event_handler_map)   | [`event_handler_map/script.rhai`](event_handler_map/script.rhai)   | [_Map Style_](https://rhai.rs/book/patterns/events-3.html)  |

## Running Examples

Examples can be run with the following command:

```sh
cargo run --example {example_name}
```

---

### Overview (`scripts/README.md`)

Testing Scripts
===============

Testing scripts written in Rhai.


Install `rhai-run` Tool
-----------------------

Use the following command to install the `rhai-run` tool:

```sh
cargo install --path . --bin rhai-run
```


How to Run
----------

Run scripts using the `rhai-run` tool:

```sh
rhai-run ./scripts/test_script_to_run.rhai
```

or

```sh
cargo run --bin rhai-run ./scripts/test_script_to_run.rhai
```

---

### Overview (`src/README.md`)

Source Structure
================

Root Sources
------------

| Source file    | Description                                                                     |
| -------------- | ------------------------------------------------------------------------------- |
| `lib.rs`       | Crate root                                                                      |
| `engine.rs`    | The scripting engine, defines the `Engine` type                                 |
| `tokenizer.rs` | Script tokenizer/lexer                                                          |
| `parser.rs`    | Script parser                                                                   |
| `optimizer.rs` | Script optimizer                                                                |
| `defer.rs`     | Utilities for deferred clean-up of resources                                    |
| `reify.rs`     | Utilities for making generic types concrete                                     |
| `tests.rs`     | Unit tests (not integration tests, which are in the main `tests` sub-directory) |


Sub-Directories
---------------

| Sub-directory | Description                                                        |
| ------------- | ------------------------------------------------------------------ |
| `config`      | Configuration                                                      |
| `types`       | Common data types (e.g. `Dynamic`, errors)                         |
| `api`         | Public API for the scripting engine                                |
| `ast`         | AST definition                                                     |
| `module`      | Support for modules                                                |
| `packages`    | Pre-defined packages                                               |
| `func`        | Registering and calling functions (native Rust and script-defined) |
| `eval`        | AST evaluation                                                     |
| `serde`       | Support for [`serde`](https://crates.io/crates/serde) and metadata |
| `grain`       | The Rhai Grain bytecodes compiler and VM                           |
| `bin`         | Pre-built CLI binaries                                             |

---

### Overview (`tests/README.md`)

Tests
=====

Rhai engine tests.


How to Run
----------

```bash
cargo test --features bin-features
```

---

### Overview (`tools/README.md`)

Build Tools
===========

This directory contains input files for various build tools required for building Rhai.

| File           | Build tool  | Description                                                        |
| -------------- | :---------: | ------------------------------------------------------------------ |
| `keywords.txt` | GNU `gperf` | Input file for the tokenizer &ndash; keywords recognition.         |
| `reserved.txt` | GNU `gperf` | Input file for the tokenizer &ndash; reserved symbols recognition. |

---

### Overview (`no_std/no_std_test/README.md`)

`no-std` Test Sample
====================

This sample application is a bare-bones `no-std` build for testing.

[`wee_alloc`](https://crates.io/crates/wee_alloc) is used as the allocator.


To Build
--------

The nightly compiler is required:

```bash
cargo +nightly build --release
```

A specific profile can also be used:

```bash
cargo +nightly build --profile unix
```

Three profiles are defined: `unix`, `windows` and `macos`.

The release build is optimized for size.  It can be changed to optimize on speed instead.

---

### Overview (`src/bin/README.md`)

Rhai Tools
==========

Tools for working with Rhai scripts.

| Tool                                                                                     | Required feature(s) | Description                                                                                                 |
| ---------------------------------------------------------------------------------------- | :-----------------: | ----------------------------------------------------------------------------------------------------------- |
| [`rhai-run`](https://github.com/rhaiscript/rhai/blob/main/src/bin/rhai-run.rs)           |                     | runs each filename passed to it as a Rhai script, or as Rhai Grain bytecodes (requires the `grain` feature) |
| [`rhai-repl`](https://github.com/rhaiscript/rhai/blob/main/src/bin/rhai-repl.rs)         |     `rustyline`     | a simple REPL that interactively evaluates statements                                                       |
| [`rhai-dbg`](https://github.com/rhaiscript/rhai/blob/main/src/bin/rhai-dbg.rs)           |     `debugging`     | the _Rhai Debugger_                                                                                         |
| [`grain-compile`](https://github.com/rhaiscript/rhai/blob/main/src/bin/grain-compile.rs) |       `grain`       | compile a Rhai script to Rhai Grain bytecodes                                                               |
| [`grain-dump`](https://github.com/rhaiscript/rhai/blob/main/src/bin/grain-dump.rs)       |       `grain`       | print the disassembly of a Rhai Grain bytecodes program                                                     |

For convenience, a feature named `bin-features` is available which is a combination of the following:

* `decimal` &ndash; support for decimal numbers
* `metadata` &ndash; access functions metadata
* `serde` &ndash; export functions metadata to JSON
* `debugging` &ndash; required by `rhai-dbg`
* `rustyline` &ndash; required by `rhai-repl`


How to Run
----------

```sh
cargo run --features bin-features --bin sample_app_to_run
```


How to Install
--------------

To install these all tools (with full features), use the following command:

```sh
cargo install --path . --bins  --features bin-features
```

or specifically:

```sh
cargo install --path . --bin sample_app_to_run  --features bin-features
```

---

--- METRICS ---
- Files Extracted: 10
- Estimated Token Budget: ~4980 tokens
- Canonical Reference: https://codewiki.google/github.com/rhaiscript/rhai
