extendr - extending R with Rust 🦀
Build blazingly fast R packages 📦 with ease. The extendr ecosystem is developer-friendly and CRAN-ready. extendr let’s you write ergonomic and idomatic Rust without having to worry about R’s internals (much 😅).
Getting Started
- Don’t have Rust installed yet? Start here.
- Familiar with Rust and want to get your hands dirty? Follow along with a complete example.
The ecosystem
Rust crates 🦀 :
extendr-api
—ergonomic, opinionated, and safe interface between R and Rustextendr-engine
—embed and use R in Rustextendr-ffi
—hand-crafted bindings to R’s C-API
R packages 📦 :
{rextendr}
—A{usethis}
-like package that scaffolds extendr-powered R packages
Quickstart
We recommend using the development version of {rextendr}
from GitHub.
# Install from CRAN
install.packages("rextendr")
# Development version
::install_github("extendr/rextendr")
remotes
# create a new R package
::create_package("helloextendr")
usethis
# Use extendr
::use_extendr()
rextendr
# Document and build the package
::document()
rextendr
# run hello_world()
hello_world()
#> [1] "Hello, world!"
Example: calling structs from R
use extendr_api::prelude::*;
#[extendr]
#[derive(Debug)]
struct Person {
pub name: String,
}
#[extendr]
impl Person {
fn new() -> Self {
Self { name: "".to_string() }
}
fn set_name(&mut self, name: &str) {
self.name = name.to_string();
}
fn name(&self) -> &str {
self.name.as_str()
}
}
#[extendr]
fn my_function() { }
// Macro to generate exports
extendr_module! {
mod classes;
impl Person;
fn my_function;
}
The #[extendr]
attribute causes the compiler to generate wrapper and registration functions for R which are called when the package is loaded, thus allowing one to access Rust functions and structures in an R session:
# call function
my_function()
# create Person object
<- Person$new()
p $set_name("foo")
p$name() # "foo" is returned p
This, of course, is just the tip of the iceberg, for there are many ways to use extendr in R:
In an interactive R session one may use
rextendr::rust_function
and friends to quickly prototype Rust code.In an R package context, one may use
rextendr::use_extendr()
to setup a Rust powered R-package. See also the vignette on R-packages.It is also possible to inline Rust code in
Quarto
documents, see vignette on extendrknitr-engine
.