Reference page
minirextendr β Scaffolding & Workflow Helper
minirextendr is a pure-R companion package that scaffolds, builds, and maintains R packages using the miniextendr Rust-R framework. Think of it as usethis for miniextendr projects.
minirextendr is a pure-R companion package that scaffolds, builds, and maintains
R packages using the miniextendr Rust-R framework. Think of it as usethis for
miniextendr projects.
Location: minirextendr/ in the monorepo.
πInstallation
# From the monorepo:
just minirextendr-install
# Or directly:
R CMD INSTALL minirextendrπCreating Projects
πStandalone R Package
library(minirextendr)
create_miniextendr_package("mypackage")
Creates a complete R package with Rust backend:
mypackage/
βββ DESCRIPTION # Config/build/bootstrap: TRUE
βββ NAMESPACE
βββ R/
βββ configure.ac # Autoconf source
βββ configure # Generated by autoconf
βββ src/
β βββ rust/
β β βββ Cargo.toml # Rust dependencies
β β βββ lib.rs # Your Rust code
β β βββ build.rs # Build-time lint
β βββ stub.c # Minimal C stub for R linker
β βββ Makevars.in
β βββ win.def.in
βββ vendor/ # Vendored miniextendr crates
βββ tools/ # config.guess, config.subπMonorepo (Workspace)
create_miniextendr_monorepo("myproject",
package = "mypkg",
crate_name = "mypkg-rs"
)
Creates a Cargo workspace with a separate Rust crate alongside the R package:
myproject/
βββ Cargo.toml # Workspace root
βββ mypkg-rs/ # Main Rust crate
β βββ Cargo.toml
β βββ src/lib.rs
βββ mypkg/ # Generated R package
β βββ src/rust/ # R-facing Rust bindings
β βββ vendor/
βββ tools/ # Version management scripts
β βββ bump-version.R
βββ justfile
To vendor from a specific GitHub tag instead of the default ("main"):
create_miniextendr_monorepo("myproject",
miniextendr_version = "v0.1.0"
)πBuild Workflow
πRecommended: devtools (one-step)
devtools::document() handles the entire pipeline automatically:
devtools::document("mypackage") # Compiles Rust + generates R wrappers + runs roxygen2
devtools::install("mypackage") # Install the final package
How it works: devtools::document() calls pkgload::load_all(), which detects
Config/build/bootstrap: TRUE in DESCRIPTION and runs bootstrap.R. That triggers
./configure β make β cargo build β document binary β R wrappers β roxygen2, all
in a single invocation. No manual ./configure or two-pass install needed.
πManual: step-by-step functions
For fine-grained control or when not using devtools:
miniextendr_autoconf(path = "mypackage") # autoconf β generate configure
miniextendr_configure(path = "mypackage") # ./configure β generate Makevars
miniextendr_build(path = "mypackage") # R CMD INSTALL
miniextendr_document(path = "mypackage") # devtools::document (regenerate wrappers)πOne-Shot Sync
miniextendr_sync() detects staleness and rebuilds only whatβs needed:
miniextendr_sync(path = ".", mode = "if_stale", stage = "install")
Modes: "if_stale" (default), "always", "never".
Stages: "install" (default), "wrappers", "build".
πInline Rust Compilation
Compile Rust code on the fly without an existing package (like Rcppβs sourceCpp()):
# Single function β auto-wraps with imports and module block
rust_function('
#[miniextendr]
pub fn add_one(x: i32) -> i32 { x + 1 }
')
add_one(41L)
#> [1] 42
# Vectors work too
rust_function('
#[miniextendr]
pub fn double_vec(x: Vec<f64>) -> Vec<f64> {
x.into_iter().map(|v| v * 2.0).collect()
}
')
double_vec(c(1.0, 2.5, 3.0))
#> [1] 2.0 5.0 6.0
# Full source with multiple functions
rust_source(code = '
use miniextendr_api::miniextendr;
#[miniextendr]
pub fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
#[miniextendr]
pub fn add(a: f64, b: f64) -> f64 { a + b }
// Registration is automatic via #[miniextendr].
')
greet("world")
#> [1] "Hello, world!"
add(1.5, 2.5)
#> [1] 4πCaching
Results are MD5-cached: same code + features = instant reload. Calling the same
rust_function() or rust_source() a second time skips compilation entirely.
# First call: compiles (~10-20s)
rust_function('#[miniextendr] pub fn sq(x: f64) -> f64 { x * x }')
# Second call: instant (cache hit)
rust_function('#[miniextendr] pub fn sq(x: f64) -> f64 { x * x }')
# Clear all cached compilations
rust_source_clean()πCargo Wrappers
Thin wrappers around cargo that target the packageβs src/rust/ directory:
| Function | Cargo command |
|---|---|
cargo_build() | cargo build |
cargo_check() | cargo check |
cargo_test() | cargo test |
cargo_clippy() | cargo clippy |
cargo_fmt() | cargo fmt |
cargo_doc() | cargo doc |
cargo_add("serde") | cargo add serde |
cargo_rm("serde") | cargo rm serde |
cargo_deps() | cargo tree |
cargo_search("regex") | cargo search regex |
cargo_update() | cargo update |
All accept path (default ".") and ... for extra arguments.
Note: cargo_fmt("--check") may report formatting diffs in vendored crates.
This is expected β vendored code isnβt subject to local formatting rules.
πFeature Scaffolding
Add optional miniextendr features with proper Cargo.toml and R-side setup:
use_rayon() # Parallel iteration
use_serde() # Serde-based R β Rust serialization
use_vctrs() # vctrs integration
use_r6() # R6 class system
use_s4() # S4 class system
use_s7() # S7 class system
use_feature_detection() # Conditional compilation via feature flags
use_vendor_lib() # Vendor external Rust library for monorepo use
Each use_*() function:
- Adds the Cargo feature to
src/rust/Cargo.toml - Sets up any needed R-side dependencies (e.g., R6, S7 packages)
- Updates
miniextendr.ymlconfiguration
πFeature Detection
use_feature_detection() sets up conditional compilation via R-detected feature flags:
# Initial setup β creates detect-features.R and wires it into configure.ac
use_feature_detection()
# After adding new features to miniextendr.yml, regenerate the detection script
update_feature_detection()
Features are detected at ./configure time and passed as --cfg flags to rustc.
πVendoring
# Vendor miniextendr crates from local monorepo
vendor_miniextendr(local_path = "/path/to/miniextendr")
# Vendor miniextendr crates from GitHub release
vendor_miniextendr(version = "0.1.0")
# Vendor external crates from crates.io
vendor_crates_io(path = "mypackage")
# Check vendor freshness
vendor_sync(path = "mypackage")
# List available versions
miniextendr_available_versions()πDiagnostics
has_miniextendr("mypackage") # TRUE/FALSE β is this a miniextendr package?
miniextendr_status(path = ".") # Show file status (present, stale, missing)
miniextendr_validate(path = ".") # Validate project consistency
miniextendr_doctor(path = ".") # Comprehensive health check
miniextendr_check_rust() # Verify Rust toolchain is available
miniextendr_status() reports each build artifactβs state (present, stale, or missing).
miniextendr_validate() checks structural consistency (DESCRIPTION fields, module
declarations, etc.). miniextendr_doctor() runs the full suite including Rust
toolchain checks.
Note: In monorepo mode, miniextendr_doctor() may report false-positive vendor
warnings because vendored crates are resolved differently via [patch] in the workspace.
πConfiguration
miniextendr.yml in the package root for project-level settings:
mx_config(path = ".") # Read current config (returns named list)
mx_config_defaults() # Show all defaults with descriptions
mx_config() merges project-level miniextendr.yml with built-in defaults.
Settings include feature flags, class system choices, and build options.
mx_config_defaults() lists every available setting with its default value.
πknitr / Rmarkdown / Quarto Integration
πPackage Mode (in a package vignette)
# In a setup chunk:
miniextendr_knitr_setup() # Syncs and registers {miniextendr} engine
Then use {miniextendr} chunks that evaluate as R code (the package is already built).
πInline Mode (self-contained vignettes)
# In a setup chunk:
miniextendr_knitr_setup(path = NULL)
Each {miniextendr} chunk compiles Rust code via rust_source() and loads functions
into the knitr environment. No existing package required.
πRender Helpers
Custom output formats that auto-sync before rendering:
# In YAML front matter:
output: minirextendr::miniextendr_html_document
output: minirextendr::miniextendr_pdf_document
output: minirextendr::miniextendr_word_document
For Quarto, use as a pre-render script:
# In _quarto.yml:
pre-render: Rscript -e "minirextendr::miniextendr_quarto_pre_render()"πUpgrading Existing Packages
upgrade_miniextendr_package(path = "mypackage")
Updates templates, vendored crates, and configure.ac to match the latest minirextendr version.
πCaching
miniextendr_cache_info() # Show cache location and size
miniextendr_clear_cache() # Clear all caches
Cache location: rappdirs::user_cache_dir("minirextendr").
πExported Functions Reference
| Category | Functions |
|---|---|
| Project creation | create_miniextendr_package, create_miniextendr_monorepo |
| Build workflow | miniextendr_autoconf, miniextendr_configure, miniextendr_build, miniextendr_document, miniextendr_sync |
| Inline compilation | rust_source, rust_function, rust_source_clean |
| Cargo wrappers | cargo_add, cargo_rm, cargo_build, cargo_check, cargo_test, cargo_clippy, cargo_fmt, cargo_doc, cargo_search, cargo_deps, cargo_update, cargo_init, cargo_new |
| Feature scaffolding | use_miniextendr, use_rayon, use_serde, use_vctrs, use_r6, use_s4, use_s7, use_feature_detection, update_feature_detection, use_vendor_lib |
| Vendoring | vendor_miniextendr, vendor_crates_io, vendor_sync, miniextendr_vendor, miniextendr_available_versions |
| Diagnostics | has_miniextendr, miniextendr_status, miniextendr_validate, miniextendr_doctor, miniextendr_check_rust |
| Configuration | mx_config, mx_config_defaults |
| knitr/render | miniextendr_knitr_setup, miniextendr_html_document, miniextendr_pdf_document, miniextendr_word_document, miniextendr_quarto_pre_render, use_miniextendr_knitr, use_miniextendr_rmarkdown, use_miniextendr_quarto |
| Cache | miniextendr_cache_info, miniextendr_clear_cache |
| Upgrade | upgrade_miniextendr_package |
| Dev helpers | miniextendr_check, miniextendr_dev_link, miniextendr_check_rust, use_miniextendr_build_rs |