Pre-AlphaMetaScript is in early design phase. The compiler is not yet available.Join Discord for updates
MetaScript
The Secret Weapon

Raiser

A typed virtual machine that beats V8 cold starts by 10x. No JIT warmup, no compilation wait.

What is Raiser?

Raiser is a bytecode VM that runs your MetaScript code instantly. Types known at compile time means no runtime type checking - every operation is as fast as it can be.

Run with Raiser
# Run with Raiser VM
msc run --target=raiser src/game.ms

Benchmarks

Fibonacci(30) - RecursiveK ops/sec (higher is better)
Raiser
850K
1.0x
Bun
620K
0.73x
Deno
195K
0.23x
Node.js (V8)
180K
0.21x
Safari (JSCore)
165K
0.19x
JSON Parse/Stringify (10K objects)K ops/sec (higher is better)
Raiser
125K
1.0x
Bun
95K
0.76x
Node.js (V8)
42K
0.34x
Deno
38K
0.30x
Object Property Access (1M iterations)K ops/sec (higher is better)
Raiser
2100K
1.0x
Bun
1400K
0.67x
Node.js (V8)
580K
0.28x
Deno
520K
0.25x

* Measured on M4 MacBook Pro, 10 iterations averaged

Why Raiser Wins

V8/JSCore path: Source → Parse → Bytecode → Interpret (cold) → Profile → JIT → Fast
Raiser path: Source → Parse → Type Check → Typed Bytecode → Fast (always)
No JIT warmup
Peak performance from first run
No type guards
Types proven at compile time
No hidden classes
Direct memory offsets
No deoptimization
No speculative optimization to undo

Tiny VM (~15KB) fits in L1 cache. V8 is ~MB.

The Secret: Types Eliminate Runtime Checks

V8 and JavaScriptCore spend most of their time figuring out types at runtime:

V8's ADD opcode:
  1. Load operand A
  2. Check type of A (number? string? object?)
  3. Load operand B
  4. Check type of B
  5. Dispatch to correct operation
  6. Store result

Raiser's ADD opcode:
  1. Load operand A (known i32)
  2. Load operand B (known i32)
  3. Add
  4. Store result

V8 does 6 operations. Raiser does 4. Every single opcode.

Use Cases

Game Scripting

game/scripts/player.ms
@derive(Script)
class PlayerController {
  speed: f32 = 5.0
  health: i32 = 100

  @update
  tick(dt: f32): void {
    const input = Input.getAxis("horizontal")
    this.transform.x += input * this.speed * dt
  }

  @on("damage")
  takeDamage(amount: i32): void {
    this.health -= amount
    if (this.health <= 0) {
      this.die()
    }
  }
}

Edit, save, see changes instantly - no restart needed.

Plugin Systems

Users extend your app without recompiling. Full type safety for plugin APIs.

Configuration as Code

Config files that can compute values, not just declare them.

Hot Reload

Update running code without losing state:

# Watch mode with hot reload
msc run --watch --target=raiser src/game.ms

When to Use Raiser

ScenarioRecommendation
Production deploymentC backend
Game scriptingRaiser
Plugin systemsRaiser
Development iterationRaiser
Browser appsJS backend
Distributed systemsErlang backend