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.
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:
- On the web, on the browser’s own WebAssembly engine, with no second virtual machine.
- Natively, as machine code compiled ahead of time where the platform allows it.
- On an interpreter, where a platform cannot generate machine code.
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.