User Manual
Comprehensive guides to miniextendr runtime behavior, build tooling, macros, and subsystem details.
The manual is the exhaustive reference for miniextendr’s runtime, build system, derive macros, and platform-specific behavior.
Use it when you need the exact rules for a conversion, the details of an ALTREP implementation, or the packaging steps required for CRAN-compatible releases.
Pages
Getting Started with miniextendr
This guide walks you through creating your first R package with a Rust backend using miniextendr.
ManualArchitecture Overview
This document provides a high-level overview of miniextendr for evaluators, contributors, and users comparing approaches for Rust-R interop.
ManualType Conversions in miniextendr
This guide documents how miniextendr converts between R and Rust types, including NA handling, coercion rules, and edge cases.
ManualClass Systems in miniextendr
miniextendr supports five R class systems. This guide helps you choose the right one for your use case.
ManualPackage Map
This page explains every package-like component in the repository: the core Rust crates, the excluded support tools, the R packages, and the fixture packages used to test cross-package behavior.
ManualALTREP in miniextendr
ALTREP (Alternative Representations) is R's system for creating custom vector implementations. miniextendr provides a powerful, safe abstraction for creating ALTREP vectors from Rust.
ManualDESCRIPTION Fields for miniextendr Packages
When you inspect rpkg/DESCRIPTION or a scaffolded package such as tests/model_project/DESCRIPTION, some lines are ordinary R-package metadata and some are there specifically to support the miniextendr build flow.
ManualExternalPtr
ExternalPtr<T> is a Box-like owned pointer that wraps R's EXTPTRSXP. It lets you hand ownership of Rust-allocated data to R and let R's garbage collector decide when to drop it.
ManualError Handling in miniextendr
This guide covers error handling patterns, panic safety, and best practices for robust R-Rust interop.
ManualThread Safety in miniextendr
This document explains how to safely call R APIs from threads other than the main R thread.
ManualFeature Flags Reference
miniextendr-api uses Cargo feature flags to enable optional integrations. Only default features are enabled automatically.
Manual`#[miniextendr]` Attribute Reference
Complete reference for #[miniextendr] on every Rust item type.
ManualAutomatic Registration & Package Initialization
This document explains how miniextendr automatically registers R-callable functions and initializes the runtime when an R package loads.
ManualAdapter Traits: Exporting External Traits to R
This guide explains how to expose Rust traits you don't own (from external crates) to R via miniextendr's trait ABI.
ManualAdapter Trait Cookbook
Practical recipes for exposing external Rust traits to R using the adapter pattern.
ManualArrow Integration
Zero-copy conversions between R vectors and Apache Arrow arrays.
ManualRayon Integration Guide
Miniextendr provides seamless integration with Rayon for parallel computation in R packages. This enables writing high-performance parallel code while maintaining R's safety guarantees.
ManualSafety Documentation
This document explains the thread safety invariants and FFI safety requirements for miniextendr. Read this before contributing unsafe code or modifying the worker, thread, or unwind_protect modules.
ManualGC Protection Toolkit
This document covers miniextendr's RAII-based GC protection facilities.
ManualFFI Guard and Panic Telemetry
How miniextendr catches panics at Rust-R boundaries and provides structured diagnostics.
ManualType Coercion in miniextendr
This document describes the Coerce<R> trait system for converting Rust types to R's native scalar types.
Manual`as.<class>()` Coercion Methods
This document describes how to implement R's as.<class>() coercion generics for Rust types using the #[miniextendr(as = "...")] attribute.
ManualConversion Behavior Matrix
This document describes how miniextendr converts between R types and Rust types. Conversions are governed by three modes (normal, coerce, strict) and apply to both directions: R-to-Rust (TryFromSexp) and Rust-to-R (IntoR).
ManualData Frame Conversion in miniextendr
miniextendr provides comprehensive support for converting between Rust types and R data frames, with three complementary approaches offering different trade-offs between ergonomics and flexibility.
ManualCustom R Connections
R connections are the standard abstraction for I/O in R -- readLines(), writeLines(), readBin(), writeBin(), scan(), and many other functions all operate on connections. miniextendr lets you create custom R connections backed by Rust types, enabling you to expose any Rust I/O source or sink to R's connection infrastructure.
ManualExpression Evaluation Helpers
Safe wrappers for building and evaluating R function calls from Rust.
ManualEnums and Factors Guide
How to map Rust enums to R factors and character strings.
ManualDots and typed_list! Validation
This document describes miniextendr's support for R's ... (dots) arguments and the typed_list! macro for structured validation.
ManualS3 Methods Guide
How to implement S3 generics (print, format, etc.) with #[miniextendr(s3)].
ManualALTREP Practical Examples
Real-world examples of ALTREP usage patterns in miniextendr.
ManualALTREP Quick Reference
One-page reference for miniextendr's ALTREP system.
ManualALTREP Guard Modes
Controls how panics and R errors are caught in ALTREP callback trampolines.
ManualReceiving ALTREP Vectors from R
How miniextendr handles ALTREP vectors when R passes them to Rust functions.
ManualSparse Iterator ALTREP Guide
Sparse iterator ALTREP vectors use Iterator::nth() to skip directly to requested indices, caching only the elements that are actually accessed. This makes them ideal for large vectors where only a few elements are needed.
ManualRArray: N-Dimensional R Arrays
Compile-time dimensioned wrappers for R arrays, matrices, and vectors.
ManualRaw Conversions
Convert Rust POD (Plain Old Data) types to and from R raw vectors using bytemuck.
Manualserde_r: Direct Rust-R Serialization
The serde_r feature provides direct serialization between Rust types and native R objects without going through an intermediate format like JSON. This enables efficient, type-preserving conversions that respect R's native data structures.
Manualvctrs Integration with `#[derive(Vctrs)]`
miniextendr provides the #[derive(Vctrs)] macro to create vctrs-compatible S3 vector classes from Rust structs. These types integrate seamlessly with the tidyverse ecosystem.
ManualRNG (Random Number Generation)
Safe access to R's random number generators from Rust.
ManualEncoding and Locale
This document covers miniextendr's UTF-8 locale requirement and encoding probing utilities.
ManualLifecycle Integration
miniextendr integrates with the lifecycle R package to mark functions as experimental, deprecated, or defunct. The proc macro generates lifecycle badges, runtime warnings, and roxygen tags automatically.
ManualStrict Mode
Strict mode rejects lossy type conversions that would silently widen or truncate values. When enabled, out-of-range values panic instead of being coerced.
ManualFeature-Controlled Defaults
Project-wide defaults for #[miniextendr] options, controlled via Cargo features.
ManualNon-API R Functions Tracking
This document tracks usage of non-API R functions in miniextendr. Non-API functions are detected by R CMD check via tools:::.checksosymbols.
ManualExtending miniextendr
This guide explains how to extend miniextendr with custom types, enabling them to be passed between Rust and R.
ManualTrait ABI
The trait ABI lets R (and other packages) call Rust trait methods without knowing the concrete Rust type at compile time. It does this by storing a tiny "header + vtable" next to the object and using R external pointers to carry it around.
Manualminiextendr Trait-Based ABI Implementation Plan
This document describes the trait ABI system for cross-package trait dispatch.
ManualLinking Strategy
This document explains how miniextendr links against R's shared library (libR) for both R packages and standalone Rust binaries.
ManualR's Package Build System for Shared Libraries
How R builds packages with compiled code, and how miniextendr integrates with it.
ManualTemplate System
The minirextendr package provides scaffolding templates for creating new R packages with Rust backends. This document explains how the template system works and how to keep templates in sync with the reference implementation.
ManualCall Attribution and `match.call()`
Generated R wrappers pass .call = match.call() into every .Call() so that errors raised from Rust are attributed to the user's call frame, with formal parameters matched by name. This page shows the difference using a real, runnable fixture.
ManualCargo.lock shape: why it's not just a Cargo.lock
The committed Cargo.lock in a miniextendr-based R package is not a vanilla Cargo.lock. It's in a specific shape — tarball-shape — that the offline install path needs. Every R package built with miniextendr (the example rpkg/ in this repo, and any package scaffolded via minirextendr) ships its src/rust/Cargo.lock in this shape.
ManualColumnarDataFrame: all-None Option columns
ColumnarDataFrame::from_rows discovers column types by probing runtime values. When every row has None for an Option<T> field the probe never sees a Some, the column stays ColumnBuffer::Generic, and R received list(NULL, NULL, …) instead of an atomic vector with NA. Tibble and dplyr treat list(NULL, …) as a list-column — it cannot be compared to scalars, does not coerce cleanly, and appears as <list> rather than <lgl>/<int>/<dbl>/<chr> in str().
ManualCondition system: error!, warning!, message!, condition!
miniextendr provides four macros for raising structured R conditions from Rust. They all require errorinr mode — the default for every #[miniextendr] function.
ManualCRAN compatibility and vendoring
How miniextendr keeps the CRAN install path working without polluting day-to-day development.
Manualminiextendr-engine: why it exists (and why it changed)
This file documents the rationale for the recent refactor that moved R linking and embedded-R initialization into miniextendr-engine, and made the benchmark crate (miniextendr-bench) depend on it.
ManualGC-torture testing — surfacing latent SEXP-protection bugs
R provides gctorture(TRUE) and gctorture2(step, wait, inhibit_release) to make every allocation trigger a full GC. Any SEXP that's reachable through Rust state but not rooted in R's protect mechanism gets collected on the next allocation, surfacing use-after-free that would otherwise hide for thousands of test runs (or only manifest under stricter allocators like glibc R 4.6 release on CI).
Manualjiff Integration
Enable with features = ["jiff"]. Bundles the IANA timezone database (tzdb-bundle-always) — no system tzdata required. Coexists with the time feature.
Manual`NATIVE_PKG_CPPFLAGS` and `CLI_INCLUDE`
How miniextendr R packages pull headers from other R packages (anything listed in LinkingTo:) into the C-shim compilation step.
ManualCalling R Package C APIs from Rust via bindgen
This document explains how to use C headers from installed R packages in a miniextendr Rust crate. The technique uses bindgen to generate Rust FFI bindings at development time, and R's standard build system to compile the required C shim files.
ManualNative-SEXP ALTREP Storage Guide
This guide explains the native-SEXP storage pattern for custom ALTREP vectors — where the backing data lives directly in the ALTREP data1 slot as a plain R vector, rather than being wrapped in an ExternalPtr.
ManualOpenMP Runtime Loading
This document explains why packages that use OpenMP can install or load on Linux but fail on macOS, and what to check in a miniextendr-backed R package.
ManualRelease Workflow: Platform Gotchas
Every miniextendr consumer eventually writes an r-release.yml GitHub Actions workflow that builds and checks their package on multiple platforms. AlmaLinux 8 containers and macOS runners surface six reproducible gotchas that downstream maintainers hit independently. The first four are locale / auth issues uncovered in issue #448; the last two align the macOS Rust toolchain ABI with CRAN's binary distribution. This document explains each one, gives the canonical fix, and explains why miniextendr's own locale check exists — so you know not to file a bug upstream.
ManualVisibility and Export Control
#[miniextendr] functions exist at three scopes: the Rust binary (C symbol), the package namespace (callable inside the package), and the public API (importable by other packages). Rust pub and the #[miniextendr] export attributes control which scope each function occupies. This document explains the mapping.
ManualWebR / WASM support
Building miniextendr for webR — R compiled to WebAssembly via Emscripten.
ManualHow R's Build System Invokes Rtools (and How to Replicate It)
Open the MSYS2 UCRT64 shell that ships with Rtools45. On a default install this is:
ManualR-Backed Global Allocator
This document covers RAllocator, a Rust GlobalAlloc implementation backed by R's memory manager.
ManualCached SEXPs
R strings (CHARSXPs), symbols, and class vectors are immutable once created. Cache values that are needed repeatedly, especially on hot paths like vectorized conversions, and reuse the pointer.
ManualPrefer* Derives Guide
How to control which R representation a Rust type uses when returned from #[miniextendr] functions.
Manual`#[track_caller]` in miniextendr
The #[miniextendr] macro automatically adds #[track_caller] to Rust functions for better panic location reporting.
ManualProc-Macro and Lint Error Guide
This guide covers common error messages from #[miniextendr] proc macros and the miniextendr-lint static analysis tool.
ManualProgress Bars in R via indicatif
miniextendr provides an adapter that routes indicatif progress bar output through R's console, so progress bars render correctly in R terminals, RStudio, and other R frontends.
ManualEnvironment Variables
All environment variables that affect miniextendr's build, configure, test, and lint processes.
ManualDeveloper Workflow
Quick reference for common development tasks. See CLAUDE.md for complete build system documentation.
ManualMaintainer Guide
This document covers maintenance tasks for the miniextendr project.
ManualBenchmarks
Performance-investigation tooling for miniextendr: how to run the bench suite, how to capture a baseline, and what the published numbers actually mean.
ManualTroubleshooting
Common issues and solutions when developing with miniextendr.
ManualSmoke Test Process
This document describes the smoke test process for the miniextendr project. It covers the full "demanding" smoke lane -- the most thorough validation pass, intended for release gates and nightly CI runs.
Manualminirextendr: Scaffolding and 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.
ManualOrphan Rule Challenges: Feature Crate Extraction
We explored extracting miniextendr-api's optional features (ndarray, nalgebra, serde, rayon, etc.) into separate miniextendr-<name> crates. The goal was to reduce miniextendr-api's surface area and let users depend only on what they need.
Manualminiextendr: Known Gaps and Limitations
This document catalogs known gaps, limitations, and undocumented behaviors in miniextendr. It serves as both user documentation and a roadmap for future improvements.
ManualFeature Backlog
This document lists practical feature candidates for upcoming maintenance cycles. Items are scoped to be incremental and compatible with the current architecture.