start

Introduction

AnimaScript is Rive’s TypeScript syntax language for fast scripts. It compiles to WebAssembly and runs on every Rive runtime.

The language is TypeScript syntax over WebAssembly types. It began as AssemblyScript and extends it with what Rive content needs: closures, structs, SIMD, threads and real time audio. There is no Node toolchain, no npm install and no bundler. The rive command line tool carries the compiler and compiles a project’s .as files as you save.

fib.as
export function fib(n: i32): i32 {
    let a = 0, b = 1;
    for (let i = 0; i < n; i++) {
        let t = a + b;
        a = b;
        b = t;
    }
    return a;
}

Sources use the .as extension.

From a WebAssembly perspective

Like upstream AssemblyScript, AnimaScript gives you WebAssembly’s type system directly: i32, i64, f32, f64, and with SIMD enabled, v128. Numeric code compiles to the instructions you would write by hand — an f32 stays in a wasm local, register-resident end to end. This is the structural reason AnimaScript code is fast: there is no tagged value, no interpreter register file in linear memory, no boxing between your arithmetic and the hardware.

From a JavaScript perspective

You also get a familiar standard library — Array<T>, String, Map<K,V>, StaticArray<T>, typed arrays, Math — over a garbage-collected heap that Rive collects between frames. AnimaScript goes further than upstream here: functions capture enclosing locals (real closures, upstream’s oldest open request), and struct declarations give you C-struct semantics inside the TypeScript syntax you already know.

Where it runs

A compiled module is plain WebAssembly. Rive runs it the way each platform allows, from the same module:

See Where Scripts Run for the details and the measurements.

Frequently asked questions

Is AnimaScript a fork of AssemblyScript?

AnimaScript began as AssemblyScript and stays compatible with it, so most AssemblyScript code and knowledge carries over. Our compiler is a new implementation in C++, not a patched copy of the Node compiler. Owning the whole compiler is what made closures, structs and threads practical to add.

How is this different from TypeScript?

Same syntax, different discipline. Types are real: an i32 is a 32-bit integer, not a number that hopes. There is no any, no runtime type juggling, no DOM. Code that type-checks compiles to static wasm with no interpreter underneath.

How is this different from Luau scripting in Rive?

Luau is Rive’s older, dynamic scripting language, and it is deprecated. Luau scripts keep running on every Rive runtime, but new scripting features land in AnimaScript, which is compiled and statically typed, and threads and audio processors exist only there. We recommend AnimaScript for every new script. Both implement the same protocols, Layout, Node, Converter and the rest, so a script keeps its shape when it moves. A project picks one: scripting: wasm in rive.yaml selects AnimaScript. The home page compares the two.

Can I bring existing C or C++ code?

Porting is the intended path, and it is pleasant: the Draco and Box2D ports mirror their C sources closely — value classes were designed so the free-function C style lands 1:1 — and both were checked bit for bit against the original libraries.

Why "AnimaScript"?

Anima is Latin for soul and the root of animate. The language outgrew AssemblyScript, so it took a name of its own and kept the .as extension.