Getting Started with courieR

courieR syncs installed R packages between R versions on the same machine. You can migrate from an old version to a new one, keep two versions in parity, or selectively push packages in either direction — all from a point-and-click dashboard or from the R console.

Installation

Install courieR on any R version you want to work from (it does not need to be installed on every version it manages):

remotes::install_github("lennon-li/courieR")

Step 1 — Discover Your R Installations

find_routes() scans the system and returns a data frame of every R version it can find:

library(courieR)

routes <- find_routes()
routes[, c("version", "rscript_path", "is_current")]
#>   version                                           rscript_path is_current
#> 1   4.6.0         C:/Program Files/R/R-4.6.0/bin/x64/Rscript.exe       TRUE
#> 2   4.5.2         C:/Program Files/R/R-4.5.2/bin/x64/Rscript.exe      FALSE
#> 3   4.5.2  C:/Users/you/AppData/Local/Programs/R/R-4.5.2/bin/...      FALSE
#> 4   4.5.1  C:/Users/you/AppData/Local/Programs/R/R-4.5.1/bin/...      FALSE
#> 5   4.1.1              C:/Users/you/Documents/R/R-4.1.1/bin/...      FALSE

is_current = TRUE marks the R you are running right now.

What gets detected

On Windows, find_routes() checks the HKLM registry (admin installs), the HKCU registry (non-admin installs via the standard CRAN installer), %ProgramFiles%\R, %LOCALAPPDATA%\Programs\R, %USERPROFILE%\Documents\R, and any versions managed by rig.

On macOS, it checks the system R framework (/Library/Frameworks/R.framework), the user framework (~/Library/Frameworks/R.framework), Homebrew (/opt/homebrew/opt/r and /usr/local/opt/r), and rig-managed versions.

On Linux, it checks /opt/R (rig system-wide), ~/.local/share/rig/R (rig user-local), conda environments, and the system Rscript on $PATH.

To include a non-standard path, pass it explicitly:

routes <- find_routes(search_paths = "/opt/custom-r/bin/Rscript")

Step 2b — Use the CLI

Prefer code? ship() does the same thing programmatically:

# always do a dry run first
result <- ship(
  source_path = routes$rscript_path[2],   # old R
  target_path = routes$rscript_path[1],   # new R (current)
  dry_run = TRUE
)
print(result$plan)

When you are happy with the plan, run for real. Pass upgrade = TRUE to also update packages that are present but at an older version (this is what the Sync tab does automatically):

result <- ship(
  source_path = routes$rscript_path[2],
  target_path = routes$rscript_path[1],
  upgrade = TRUE
)

# check for any errors
result$results[result$results$status == "error", ]

Inspecting Libraries Manually

manifest() lists packages for any R version. inventory() compares two manifests:

a_pkgs <- manifest(rscript_path = routes$rscript_path[1])
b_pkgs <- manifest(rscript_path = routes$rscript_path[2])

comp <- inventory(a_pkgs, b_pkgs)
nrow(comp$missing)    # packages in A but not in B
nrow(comp$outdated)   # packages where A has a newer version than B

Tips