Language Overview

Risor pairs a familiar, JavaScript-like syntax with a distinctive philosophy: no loops, functional iteration, and security by default. If you've written JavaScript or Python, most of this will feel familiar.

Key Characteristics

  • JavaScript-like syntax. Arrow functions, template strings, destructuring, and optional chaining.
  • No loops. No for, no while. Iteration happens through map, filter, each, reduce, and recursion.
  • Secure by default. Scripts start with an empty environment. They can only access what you explicitly provide.
  • Bytecode compiled. Source compiles to bytecode that runs on a lightweight VM.
  • Concurrent safe. Compiled bytecode is immutable and reusable across goroutines without synchronization.

Execution Pipeline

Every script flows through four stages:

  1. Lexing. Source code becomes a stream of tokens.
  2. Parsing. Tokens become an abstract syntax tree (AST).
  3. Compilation. The AST becomes bytecode instructions.
  4. Execution. Bytecode runs on the Risor virtual machine.

Compilation and execution are separate phases, so you can compile once and run many times, even concurrently across goroutines.

A Taste of Risor

let items = ["apple", "banana", "cherry"]
 
let upper = items.map(s => s.to_upper())
 
let greeting = `Found ${len(items)} items`
 
let result = items
    .filter(s => s.has_prefix("b"))
    |> sorted
 
let status = if (result != nil) { "found" } else { "not found" }

What Makes Risor Different

Most scripting languages lean on imperative loops. Risor deliberately goes another way: all iteration flows through functional methods and the iterator protocol. The result is code that's composable and free of off-by-one bugs.

The pipe operator (|>) takes this further, encouraging a data-flow style where values transform through a readable chain of operations:

let evens = range(20) |> filter(x => x % 2 == 0) |> list
evens.map(x => x * x)

The other thing worth knowing: a Risor script starts with zero capabilities -- no filesystem, no network, no environment variables. The host Go application opts into every function and variable it exposes.


Risor © 2026 Deep Noodle