Runtime

How to run R code in a sandbox

Run R in an isolated microVM with a code interpreter that returns plots as PNG and data frames as tables, or install R and use Rscript.

On Runtime, R needs no setup at all: the code interpreter installs it the first time you run an R cell, then keeps your variables between cells. On 23 September 2026 that first install took about 90 seconds, once per sandbox, and an image with R skips it (code interpreter). Every sandbox is a Firecracker microVM with its own kernel, and a 2 vCPU, 4 GiB sandbox costs $0.03125 an hour while an analyst reads the last chart (pricing).

R as a notebook

TypeScriptimport { Sandbox } from "withruntime";await using sbx = await Sandbox.create({ timeoutSeconds: 1800 });await sbx.interpreter.run(  "df <- data.frame(dose = c(1, 2, 4, 8), response = c(3.1, 5.8, 9.6, 14.2))",  {    language: "r",    timeoutMs: 300_000, // the first R cell installs R  },);const fit = await sbx.interpreter.run("coef(lm(response ~ dose, data = df))", { language: "r" });console.log(fit.stdout, fit.results[0]?.data["text/plain"]);const plot = await sbx.interpreter.run("plot(df$dose, df$response, type = 'b')", { language: "r" });const png = plot.results.find((r) => r.data["image/png"]);console.log(png ? "got a chart" : "no chart");const table = await sbx.interpreter.run("df", { language: "r" });console.log(table.results[0]?.data["application/vnd.runtime.table+json"]);
Pythonimport base64from withruntime import Sandboxwith Sandbox.create(timeout_seconds=1800) as sbx:    sbx.interpreter.run("df <- data.frame(dose = c(1, 2, 4, 8), response = c(3.1, 5.8, 9.6, 14.2))",                        language="r", timeout_ms=300_000)  # the first R cell installs R    fit = sbx.interpreter.run("coef(lm(response ~ dose, data = df))", language="r")    print(fit["stdout"])    plot = sbx.interpreter.run("plot(df$dose, df$response, type = 'b')", language="r")    for result in plot["results"]:        if "image/png" in result["data"]:            with open("dose.png", "wb") as out:                out.write(base64.b64decode(result["data"]["image/png"]))    table = sbx.interpreter.run("df", language="r")    print(table["results"][0]["data"]["application/vnd.runtime.table+json"])
  • Plots come back as PNG images, base64 in image/png, with no png() or dev.off() in your code.
  • Data frames come back as tables your app can render.
  • Any file a cell hands to display (.png, .svg, .html, .csv) comes back as a result too.
  • The first R cell downloads R from Ubuntu's archive, so that sandbox needs the internet. After that, sbx.network.set({ internet: false }) cuts it off for the code that follows.

Which R to install

For scripts outside the interpreter, or for an image, install R yourself:

Source R version on 25 September 2026 Command
Ubuntu 24.04 archive (universe) 4.3.3 sudo apt-get install -y r-base-core
Ubuntu, with headers to build packages 4.3.3 sudo apt-get install -y r-base-dev
CRAN's Ubuntu repository 4.6 Add the noble-cran40 repository, then r-base

CRAN's own steps for Ubuntu add its signing key and the $(lsb_release -cs)-cran40 repository, then run sudo apt install --no-install-recommends r-base (CRAN). CRAN also points to r2u, which installs CRAN packages as Ubuntu binaries, so they need no compile.

Run an R script

TypeScriptimport { Sandbox } from "withruntime";const script = `x <- c(12, 15, 11, 19, 22, 17)cat(sprintf("mean %.2f, sd %.2f\\n", mean(x), sd(x)))`;await using sbx = await Sandbox.create({ timeoutSeconds: 900, onLeaseEnd: "stop" });await sbx.exec(  "sudo apt-get update -q && sudo apt-get install -y -q --no-install-recommends r-base-core",  {    check: true,    timeoutMs: 600_000,  },);await sbx.network.set({ internet: false });await sbx.files.write("/workspace/stats.R", script);const run = await sbx.exec(["Rscript", "stats.R"], { timeoutMs: 60_000 });console.log(run.stdout); // mean 16.00, sd 4.20
Pythonfrom withruntime import Sandboxscript = """x <- c(12, 15, 11, 19, 22, 17)cat(sprintf("mean %.2f, sd %.2f\\n", mean(x), sd(x)))"""with Sandbox.create(timeout_seconds=900, on_lease_end="stop") as sbx:    sbx.exec("sudo apt-get update -q && sudo apt-get install -y -q --no-install-recommends r-base-core",             check=True, timeout_ms=600_000)    sbx.network.set(internet=False)    sbx.files.write("/workspace/stats.R", script)    run = sbx.exec(["Rscript", "stats.R"], timeout_ms=60_000)    print(run.stdout)  # mean 16.00, sd 4.20

An array runs Rscript with no shell in between. A script that loops forever returns timedOut: true with the output so far.

R and your packages in every sandbox

Build a custom image with R and the packages your analyses use. The interpreter finds R already there and starts its first R cell with no install:

TypeScriptimport { Runtime } from "withruntime";const runtime = new Runtime();await runtime.images.build({  name: "r-data",  recipe: {    apt: ["r-base-dev"],    commands: [      `Rscript -e 'install.packages(c("data.table", "jsonlite"), repos = "https://cloud.r-project.org")'`,    ],  },});await using sbx = await runtime.sandboxes.create({ image: "r-data", network: { internet: false } });const cell = await sbx.interpreter.run("library(data.table); data.table(a = 1:3)[, sum(a)]", {  language: "r",});console.log(cell.results[0]?.data["text/plain"]);
Pythonfrom withruntime import Runtimeruntime = Runtime()runtime.images.build(name="r-data", recipe={    "apt": ["r-base-dev"],    "commands": ["""Rscript -e 'install.packages(c("data.table", "jsonlite"), repos = "https://cloud.r-project.org")'"""],})with runtime.sandboxes.create(image="r-data", network={"internet": False}) as sbx:    cell = sbx.interpreter.run("library(data.table); data.table(a = 1:3)[, sum(a)]", language="r")    print(cell["results"][0]["data"]["text/plain"])

install.packages compiles packages from source, which is why the recipe takes r-base-dev. The image build runs in its own microVM, and building is free; a stored image is charged on its size.

R next to Python

One sandbox can hold an R context and a Python context at once, each with its own variables, so an agent can clean data in pandas and fit a model in R without leaving the machine. Files in /workspace are shared by both.

New accounts get 50 free sandbox hours, no card:

Terminalnpx withruntime sandbox run --trial -- bash -c 'sudo apt-get update -q && sudo apt-get install -y -q r-base-core && R --version'

Sources

Facts on this page were checked on 25 September 2026.