Guide
Package Runtime
How miniR finds packages, loads namespaces, sources R files, and attaches exports
miniR treats package loading as a runtime subsystem, not as a thin wrapper around source(). The package loader is responsible for finding packages, building namespace environments, importing symbols, loading native code, sourcing R/ files, indexing help, and attaching exports onto the search path.
The Loading Sequence
The core loader lives in src/interpreter/packages/loader.rs. The rough order is:
- Find the package directory on
.libPaths() - Parse
DESCRIPTION - Parse
NAMESPACE - Create a namespace environment with the base environment as parent
- Populate imports from already-loaded packages
- Load native code declared by
useDynLib()before sourcing R code - Load
R/sysdata.rdaif present - Source
R/*.Rfiles, respectingCollate - Build a filtered exports environment
- Register
S3method()entries - Run
.onLoad() - If the caller used
library()orrequire(), attach the exports environment and then run.onAttach()
That is why package compatibility work in miniR is usually about runtime semantics, not only parser coverage.
Where Packages Are Found
Library paths are built from interpreter-local environment state:
R_LIBSR_LIBS_USER- miniR's default library directory under the user data dir
This logic is in Interpreter::get_lib_paths(). The paths are resolved against the interpreter's working directory and environment variables, both of which are also stored on the interpreter instance.
Namespace Versus Search Path
miniR keeps these distinct:
| Concept | What it is |
|---|---|
| Namespace environment | All package code and internal objects |
| Exports environment | The user-visible subset of the namespace |
| Search path entry | An attached exports environment inserted between .GlobalEnv and base |
load_namespace() builds the namespace. attach_package() inserts the exports environment into the parent chain and records it in the interpreter's search-path list.
Built-In Base Packages
Packages such as base, stats, utils, methods, graphics, grDevices, and grid are treated specially. miniR registers synthetic namespaces for them instead of expecting installable package directories.
That means calls like library(base) and loadNamespace("stats") can still work even though those packages are backed by builtin code and interpreter state.
DESCRIPTION And NAMESPACE Matter
The package runtime does real metadata work:
DESCRIPTIONdrives package identity, dependencies, imports, and collate order.NAMESPACEdrives exports, imports,importFrom(),S3method(), anduseDynLib().man/directories are indexed into the Rd help store.
If a package fails because a symbol is missing or a method is not visible, the problem is often in this metadata path rather than in the parser.
The dedicated Help And Documentation page covers the man/ and builtin-help side of that runtime path.
R File Sourcing
miniR sources package R/ files in collate order when DESCRIPTION provides one. Files not listed in Collate are sourced afterwards in alphabetical order.
There is one pragmatic divergence here: top-level expression failures while sourcing a file are logged and the loader continues with later expressions. That keeps packages usable when one top-level helper fails but later definitions, hooks, or methods still need to exist.
Imports, Exports, And Hooks
The package loader:
- copies imported symbols into the namespace environment
- builds a filtered exports environment from
export()andexportPattern() - registers S3 methods declared in
NAMESPACE - calls
.onLoad()after the namespace is ready - calls
.onAttach()only when the package is attached to the search path
This split matches how packages expect to behave in real R sessions.
Native Code Is Part Of Package Loading
When NAMESPACE includes useDynLib(), miniR loads package native code before sourcing R/ files. That allows package R code to refer to .Call targets during load.
This is one reason package compatibility and native-runtime work are tightly coupled in miniR.
Where To Work When Package Loading Fails
| Symptom | Start here |
|---|---|
| Package not found | packages/loader.rs, .libPaths() logic |
| Wrong exports/imports | packages/namespace.rs, build_exports(), populate_imports() |
| Hook or load-order issue | packages/loader.rs, Collate, .onLoad(), .onAttach() |
| Missing S3 method | packages/namespace.rs, register_s3_methods(), s3.rs |
| Native symbol not available during load | packages/loader.rs, native/dll.rs, native/runtime.rs |
In practice, package runtime bugs are often environment-chain or metadata bugs. Treat them that way and the fixes stay coherent.