Skip to content

Runtime usage

Scripts run via rodeo run (or via the client’s runCode) have a small standard library mounted at @rodeo/*:

local fs = require("@rodeo/fs")
local io = require("@rodeo/io")
local process = require("@rodeo/process")
local stream = require("@rodeo/stream")
local roblox = require("@rodeo/roblox")

These modules let your in-Studio code touch the host machine: read/write files, run shell commands, pipe to stdout, load .rbxm fixtures. Full reference is in @rodeo runtime; the examples below show common patterns.

fs.open returns a StreamHandle; pair it with stream.read / stream.write / stream.close:

local fs = require("@rodeo/fs")
local stream = require("@rodeo/stream")
-- Write
local f = fs.open("notes.txt", "w")
stream.write(f, "line one\n")
stream.write(f, "line two\n")
stream.close(f)
-- Read
local f2 = fs.open("notes.txt", "r")
local contents = stream.read(f2)
stream.close(f2)
print(contents) --> "line one\nline two\n"
local fs = require("@rodeo/fs")
local stream = require("@rodeo/stream")
local HttpService = game:GetService("HttpService")
local f = fs.open("config.json", "r")
local raw = stream.read(f)
stream.close(f)
local config = HttpService:JSONDecode(raw)
print(config.gameName, config.version)
local fs = require("@rodeo/fs")
for _, entry in fs.listdir(".") do
print(entry.name, entry.type) -- type: "file" | "dir"
end

fs.exists, fs.stat, fs.mkdir, fs.remove, fs.rmdir, fs.copy, and fs.type round out the surface — see the fs reference.

For non-text data, use stream.readBytes / stream.writeBytes instead of the string-based versions. They return / accept a Luau buffer:

local fs = require("@rodeo/fs")
local stream = require("@rodeo/stream")
local r = fs.open("sprite.png", "r")
local data = stream.readBytes(r) -- buffer
stream.close(r)
print(buffer.len(data), "bytes")
local w = fs.open("copy.png", "w")
stream.writeBytes(w, data)
stream.close(w)

io.stdout (and io.stderr) are stream handles. Writing to them feeds the terminal that ran rodeo run, so your script becomes pipeable:

local io = require("@rodeo/io")
local stream = require("@rodeo/stream")
for i = 1, 10 do
stream.write(io.stdout, `value-{i}\n`)
end
Terminal window
rodeo run gen.luau | sort -u | head -5

For interactive prompts, stream.read(io.stdin) blocks until the user types a line:

local io = require("@rodeo/io")
local stream = require("@rodeo/stream")
stream.write(io.stdout, "name? ")
local name = stream.read(io.stdin)
stream.write(io.stdout, `hello, {name}\n`)

Anything after -- (CLI) or in scriptArgs (client) shows up in process.args:

local process = require("@rodeo/process")
if #process.args == 0 then
error("usage: rodeo run script.luau -- <name>")
end
print("hello,", process.args[1])
Terminal window
rodeo run greet.luau -- frank

process.env, process.cwd(), process.homedir(), and process.execpath() round out the host-introspection set.

process.run blocks and captures output:

local process = require("@rodeo/process")
local result = process.run({ "git", "rev-parse", "--abbrev-ref", "HEAD" }, {
stdio = "piped",
})
local branch = string.gsub(result.stdout, "%s+$", "")
print("on branch", branch)

process.system takes a shell command string instead of an argv list:

local result = process.system("ls -la | head -5", { stdio = "piped" })
print(result.stdout)

process.create spawns without blocking — use it for long-running children you want to talk to via stream handles. The process reference covers the full options table (cwd, env, per-stream stdio overrides).

roblox.import reads a model file from disk and returns its root Instances:

local roblox = require("@rodeo/roblox")
local roots = roblox.import("fixtures/test-rig.rbxm")
for _, inst in roots do
inst.Parent = workspace
end

roblox.export writes Instances back out as a .rbxm (binary) or .rbxmx (XML) model file. Extension picks the format:

local roblox = require("@rodeo/roblox")
local folder = Instance.new("Folder")
folder.Name = "Snapshot"
-- ...populate folder...
roblox.export("out/snapshot.rbxm", { folder })
roblox.export("out/snapshot.rbxmx", { folder })

Useful for staging test fixtures, snapshotting Studio state, or moving subtrees between sessions.

  • @rodeo runtime — full API reference for fs, io, process, stream, roblox
  • Client usage — same APIs callable from outside Studio via rodeo-client-lune