R
GNU R 4.6.1 (interpreter + base/recommended + stats stack) as a single wasm module, callable from Lua.
Run
wippy run wippy-langs/rR
The R statistical language on the Wippy runtime. Call R from Lua and get native Lua values back — no external process, no network. R runs as a resident, warm instance inside the Wippy sandbox.
Under the hood it is real GNU R 4.6.1 — the interpreter, base and recommended packages, OpenBLAS (WASM SIMD kernels) under R's LAPACK, and a curated statistical stack (tidyverse, poLCA, glmnet, flexmix, MASS, Matrix, survival, …) — compiled to a single WebAssembly module. Results are bit-identical to CRAN R.
Quickstart
wippy add wippy-langs/r
wippy install
Declare the SDK in your entry's imports (r: r:sdk), then:
local r = require("r")
r.eval("mean(1:100)").result -- 50.5
r.eval("R.version.string").result -- "R version 4.6.1 (2026-06-24)"
-- named bindings: one string-keyed table binds each key as an R variable
r.eval("x + y", { x = 1, y = 3 }).result -- 4
-- positional args bind to the R list `argv` (never string-spliced)
r.eval("argv[[1]] + argv[[2]]", 3, 4).result -- 7
r.eval("paste(argv[[1]], toupper(argv[[2]]))", "hi", "there").result -- "hi THERE"
-- a real model
r.eval("round(coef(lm(dist ~ speed, cars)), 3)").result -- {-17.579, 3.932}
-- a real plot: PNG bytes, rendered headless (cairo + bundled fonts)
r.plot("plot(mtcars$wt, mtcars$mpg); abline(lm(mpg ~ wt, mtcars))",
{ width = 800, height = 600, dpi = 96 }).result
Every r.eval returns { stdout, stderr, error, result }. result is the value
of the last expression decoded to a native Lua object; error is nil, or the R
error message when R raised one; stderr carries warnings/messages (fd-2), with
the error message only in error.
What you get
- The whole language. Arithmetic, vectors/matrices,
data.frame, closures, S3/S4, the apply family, regex, dates — bit-identical to CRAN R 4.6.1. - Real statistics.
lm/glm, distributions (d/p/q/r*),prcomp, LAPACK linear algebra on OpenBLAS SIMD kernels, plus poLCA (latent-class), glmnet (elastic net), flexmix (finite mixtures), and the tidyverse. - Deterministic RNG.
set.seed()reproduces R's exact stream across the bridge — verified byte-identical to native R. - Plots as bytes.
r.plot(code, opts)renders through headless cairo (png/svg) orpdfand returns the image bytes to Lua;optstakeswidth,height,dpi, andformat. - Your files. A dedicated
/datamount (r:data) shared between Lua (fs.get) and R (read.csv("/data/...")). - Injection-safe args. Both binding forms serialize Lua values as R data literals: a hostile string stays a length-1 string, never code, and named bindings only accept plain R identifiers as variable names.
Documentation
The per-module wiki covers Installation, Usage, Architecture,
Performance, Limitations, and License:
https://hub.wippy.ai/wippy-langs/r/wiki/README.md.
License
GPL-3.0. R is distributed under GPL-2 | GPL-3, and this statically-combined module is a derivative work, so it ships under the GPL. See the License wiki page for the full third-party attribution.