Open source · MIT licensed

A Ruby-like language for your app.

Let users and AI agents add features with scripts. You choose which data and functions they can use, and how much work each script can do.

Hundreds of examples to run in your browser

delivery_update.vibe Rust edition
def delivery_update(phone: string, order_id: string) -> { body: string, status: string, to: string }
  body = "Order #{order_id} is on its way."
  sms.send(phone, body)
end

def run -> { body: string, status: string, to: string }
  delivery_update("+12025550123", "1042")
end

SMS and email calls return previews. No messages are sent.

Language

If you know Ruby, much of this will look familiar.

Write functions, work with collections, and check types before running. Vibescript also has money, durations, and enums built in.

Small on purpose.

Functions have names, and blocks run during the call that receives them. Changing an array or hash leaves other copies alone. Hash keys are strings, and records declare the keys they contain.

small_surface.vibe
module Scoring
  BONUS = 10

  def self.with_bonus(score: int) -> int
    score + BONUS
  end
end

type Order = { status: string }

def approve(order: Order) -> { original: Order, updated: Order, same_key: bool, score: int }
  original = order
  order["status"] = "approved"

  { original: original, updated: order,
    same_key: order["status"] == order["status"],
    score: Scoring.with_bonus(80) }
end

Add your own services.

Give a script an SMS service, an email client, or your own API through a host capability. You write the adapter. The script calls it like any other method. Here's how to connect one.

notifications.vibe host side
def run -> { to: string, body: string, status: string }
  sms.send("+15555550123", "Your order is ready.")
end

Set hard limits for each script.

Set a budget for execution steps, memory, and call depth. If a script reaches a limit, the engine stops it and returns an error.

untrusted.vibe · sandboxed
$ cat untrusted.vibe
def run
  balance = 0
  while true
    balance = balance + 1
  end
end

$ vibes run --function run untrusted.vibe
RuntimeError: step quota exceeded
✓ stopped at 1,000,000, page stays responsive

Built-in money, duration, and enum types.

Write 3.days for a duration. Use money values for exact decimal arithmetic. Define enums for choices such as shipping speeds or order states.

primitives.vibe
enum ShippingSpeed
  Economy
  Priority
  Overnight
end

def transit_time(speed: ShippingSpeed) -> duration
  if speed == ShippingSpeed::Overnight
    6.hours
  else
    5.days
  end
end

def net_after_fee(cents: int) -> money
  gross = money_cents(cents, "USD")
  gross - money("1.75 USD")
end

In your app

Give scripts access to your app's services.

Put pricing rules, approval steps, or notification schedules in scripts that users can change without rebuilding your app.

Your app handles I/O and scheduling. Scripts use the functions and data you provide to calculate a price, choose the next reviewer, or plan a reminder.

Add services through host capabilities. A script can then call sms.send(...) or email.send(...). Try the message previews and edit the scripts behind them.

Try it

Run a few examples.

Pick an example, read the code, and run it. You don't need to install anything.