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

Manual

Getting Started with miniextendr

This guide walks you through creating your first R package with a Rust backend using miniextendr.

Manual

Architecture Overview

This document provides a high-level overview of miniextendr for evaluators, contributors, and users comparing approaches for Rust-R interop.

Manual

Type Conversions in miniextendr

This guide documents how miniextendr converts between R and Rust types, including NA handling, coercion rules, and edge cases.

Manual

Class Systems in miniextendr

miniextendr supports five R class systems. This guide helps you choose the right one for your use case.

Manual

Package 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.

Manual

ALTREP 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.

Manual

DESCRIPTION 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.

Manual

ExternalPtr

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.

Manual

Error Handling in miniextendr

This guide covers error handling patterns, panic safety, and best practices for robust R-Rust interop.

Manual

Thread Safety in miniextendr

This document explains how to safely call R APIs from threads other than the main R thread.

Manual

Feature 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.

Manual

Automatic Registration & Package Initialization

This document explains how miniextendr automatically registers R-callable functions and initializes the runtime when an R package loads.

Manual

Adapter 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.

Manual

Adapter Trait Cookbook

Practical recipes for exposing external Rust traits to R using the adapter pattern.

Manual

Arrow Integration

Zero-copy conversions between R vectors and Apache Arrow arrays.

Manual

Rayon 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.

Manual

Safety 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.

Manual

GC Protection Toolkit

This document covers miniextendr's RAII-based GC protection facilities.

Manual

FFI Guard and Panic Telemetry

How miniextendr catches panics at Rust-R boundaries and provides structured diagnostics.

Manual

Type 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.

Manual

Conversion 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).

Manual

Data 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.

Manual

Custom 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.

Manual

Expression Evaluation Helpers

Safe wrappers for building and evaluating R function calls from Rust.

Manual

Enums and Factors Guide

How to map Rust enums to R factors and character strings.

Manual

Dots and typed_list! Validation

This document describes miniextendr's support for R's ... (dots) arguments and the typed_list! macro for structured validation.

Manual

S3 Methods Guide

How to implement S3 generics (print, format, etc.) with #[miniextendr(s3)].

Manual

ALTREP Practical Examples

Real-world examples of ALTREP usage patterns in miniextendr.

Manual

ALTREP Quick Reference

One-page reference for miniextendr's ALTREP system.

Manual

ALTREP Guard Modes

Controls how panics and R errors are caught in ALTREP callback trampolines.

Manual

Receiving ALTREP Vectors from R

How miniextendr handles ALTREP vectors when R passes them to Rust functions.

Manual

Sparse 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.

Manual

RArray: N-Dimensional R Arrays

Compile-time dimensioned wrappers for R arrays, matrices, and vectors.

Manual

Raw Conversions

Convert Rust POD (Plain Old Data) types to and from R raw vectors using bytemuck.

Manual

serde_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.

Manual

vctrs 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.

Manual

RNG (Random Number Generation)

Safe access to R's random number generators from Rust.

Manual

Encoding and Locale

This document covers miniextendr's UTF-8 locale requirement and encoding probing utilities.

Manual

Lifecycle 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.

Manual

Strict 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.

Manual

Feature-Controlled Defaults

Project-wide defaults for #[miniextendr] options, controlled via Cargo features.

Manual

Non-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.

Manual

Extending miniextendr

This guide explains how to extend miniextendr with custom types, enabling them to be passed between Rust and R.

Manual

Trait 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.

Manual

miniextendr Trait-Based ABI Implementation Plan

This document describes the trait ABI system for cross-package trait dispatch.

Manual

Linking Strategy

This document explains how miniextendr links against R's shared library (libR) for both R packages and standalone Rust binaries.

Manual

R's Package Build System for Shared Libraries

How R builds packages with compiled code, and how miniextendr integrates with it.

Manual

Template 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.

Manual

Call 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.

Manual

Cargo.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.

Manual

ColumnarDataFrame: 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().

Manual

Condition 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.

Manual

CRAN compatibility and vendoring

How miniextendr keeps the CRAN install path working without polluting day-to-day development.

Manual

miniextendr-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.

Manual

GC-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).

Manual

jiff 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.

Manual

Calling 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.

Manual

Native-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.

Manual

OpenMP 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.

Manual

Release 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.

Manual

Visibility 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.

Manual

WebR / WASM support

Building miniextendr for webR — R compiled to WebAssembly via Emscripten.

Manual

How 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:

Manual

R-Backed Global Allocator

This document covers RAllocator, a Rust GlobalAlloc implementation backed by R's memory manager.

Manual

Cached 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.

Manual

Prefer* 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.

Manual

Proc-Macro and Lint Error Guide

This guide covers common error messages from #[miniextendr] proc macros and the miniextendr-lint static analysis tool.

Manual

Progress 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.

Manual

Environment Variables

All environment variables that affect miniextendr's build, configure, test, and lint processes.

Manual

Developer Workflow

Quick reference for common development tasks. See CLAUDE.md for complete build system documentation.

Manual

Maintainer Guide

This document covers maintenance tasks for the miniextendr project.

Manual

Benchmarks

Performance-investigation tooling for miniextendr: how to run the bench suite, how to capture a baseline, and what the published numbers actually mean.

Manual

Troubleshooting

Common issues and solutions when developing with miniextendr.

Manual

Smoke 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.

Manual

minirextendr: 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.

Manual

Orphan 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.

Manual

miniextendr: 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.

Manual

Feature Backlog

This document lists practical feature candidates for upcoming maintenance cycles. Items are scoped to be incremental and compatible with the current architecture.