Portable R for macOS

Run R from any directory without installing it. Signed, notarized, and ready to go.

r
macos
devops
portable
Author

James Balamuta

Published

April 2, 2026

Abstract

portable-r-macos provides relocatable R distributions for macOS built from official CRAN binaries. Download a tar.gz, extract it, and run R from anywhere on disk. All binaries are Developer ID signed and Apple notarized, so Gatekeeper stays quiet. Binary CRAN packages are automatically patched at install time via a hidden .portable R environment. Versions 4.3.0 through 4.5.3 are available for both Apple Silicon and Intel.

Making R portable on macOS

The companion Windows post covers why portable R matters and where it fits in the broader landscape of runtime distribution. On Windows, R has been relocatable since the R 2.x era, so the work there was mostly removing the installer from the equation. On macOS, the engineering goes deeper.

Community interest in making R portable on macOS goes back over a decade (Figure 1). A 2009 R-devel proposal suggested making bin/R infer its location at runtime. A 2013 discussion explored bundling R in an IDE, with Simon Urbanek mapping out the landscape of paths that get baked in at build time. A 2015 SuperUser question and a 2019 Posit Community thread each contributed techniques and deepened understanding. And projects like COVAIL’s Electron template, r-shiny-electron, shiny-electron-template-m1, and selkamand’s r-portable-mac each proved that portable R on macOS is achievable and in demand.

Timeline showing milestones: 2009 R-devel PR#14007, 2013 Simon Urbanek maps baked-in paths, 2017 COVAIL ships R 3.4 in Electron, 2019 Posit Community surveys the state of the art, 2023 selkamand publishes R 4.2.3 portable, 2026 portable-r-macos launches with R 4.3 through 4.5 signed and notarized.

Timeline showing milestones: 2009 R-devel PR#14007, 2013 Simon Urbanek maps baked-in paths, 2017 COVAIL ships R 3.4 in Electron, 2019 Posit Community surveys the state of the art, 2023 selkamand publishes R 4.2.3 portable, 2026 portable-r-macos launches with R 4.3 through 4.5 signed and notarized.

Figure 1: Community efforts toward relocatable R on macOS over the past decade.

portable-r-macos builds on all of this. The build script takes the official CRAN binary, rewrites every hardcoded framework path, codesigns with a Developer ID certificate, notarizes with Apple, and transparently patches CRAN binary packages at install time.

Getting started

Download a tar.gz from GitHub Releases and extract it. R.home() resolves to wherever you put the folder, packages install locally, and the Developer ID signature keeps Gatekeeper quiet (Figure 2):

macOS Terminal session showing curl downloading and extracting portable R to ~/Downloads, R.home() returning the Downloads path, install.packages reporting one patched shared library, and codesign confirming the Developer ID Application signature from HJJB, LLC.

macOS Terminal session showing curl downloading and extracting portable R to ~/Downloads, R.home() returning the Downloads path, install.packages reporting one patched shared library, and codesign confirming the Developer ID Application signature from HJJB, LLC.

Figure 2: Portable R running from ~/Downloads with local paths, package patching, and Developer ID signing.

Pick the archive for your Mac’s architecture (replace 4.5.3 with any version from 4.3.0 onward) and pipe it through tar. Releases for all versions are at github.com/portable-r/portable-r-macos/releases.

Apple Silicon (M1/M2/M3/M4)

curl -fSL https://github.com/portable-r/portable-r-macos/releases/download/v4.5.3/portable-r-4.5.3-macos-arm64.tar.gz | tar xz

Intel

curl -fSL https://github.com/portable-r/portable-r-macos/releases/download/v4.5.3/portable-r-4.5.3-macos-x86_64.tar.gz | tar xz

Once extracted, R.home() points to wherever the folder landed. Installing packages works normally, and the .portable environment patches CRAN binary .so files automatically:

~/Downloads $ ./portable-r-4.5.3-macos-arm64/bin/Rscript -e 'cat(R.home(), "\n")'
# /Users/you/Downloads/portable-r-4.5.3-macos-arm64

~/Downloads $ ./portable-r-4.5.3-macos-arm64/bin/Rscript -e '
  install.packages("jsonlite")
  library(jsonlite)
  cat(toJSON(list(portable = TRUE), auto_unbox = TRUE))
'
# Portable R: patched 1 shared library
# {"portable":true}

No sudo, no .pkg, no Gatekeeper warnings. Packages install to a local library/ directory inside the portable R folder.

Patching for portability

The CRAN macOS .pkg embeds absolute /Library/Frameworks/R.framework/... paths in Mach-O binaries, shell scripts, and config files. The build script rewrites all of these to relative references (Figure 3).

Side-by-side terminal output of otool -L on the R binary. The left panel shows the CRAN .pkg with absolute paths to /Library/Frameworks/R.framework. The right panel shows portable-r with relative @executable_path references.

Side-by-side terminal output of otool -L on the R binary. The left panel shows the CRAN .pkg with absolute paths to /Library/Frameworks/R.framework. The right panel shows portable-r with relative @executable_path references.

Figure 3: Dylib references before and after: hardcoded framework paths become relative @executable_path references.

This is the same Mach-O relocation approach used across the macOS ecosystem: Homebrew’s keg relocation (via ruby-macho), conda-build’s macOS relocator, and python-build-standalone’s build script all rewrite dylib load commands to @rpath and @loader_path references in the same way. The build also patches shell scripts and Makeconf with sed, wraps Rscript to set the RHOME environment variable it reads at startup, and codesigns everything with a Developer ID certificate and Apple notarization.

CRAN binary packages carry the same embedded framework paths in their .so files. A .portable R environment attaches to the search path at startup and wraps install.packages() to automatically patch these after installation:

> install.packages(c("jsonlite", "curl", "httr2"))
Portable R: patched 11 shared libraries

Full technical details are in build-details.md.

Looking ahead

With both Windows and macOS covered, portable R is available for every major desktop operating system, across 12 R versions and multiple architectures, from a predictable URL pattern (Figure 4).

Hub-and-spoke diagram with portable-r at the center, connected to five use cases: CI/CD pipelines, teaching labs, desktop Shiny apps via native or Electron or Tauri wrappers, auto-download on first launch using predictable URL patterns, and internal tools for reports, ETL, and automation.

Hub-and-spoke diagram with portable-r at the center, connected to five use cases: CI/CD pipelines, teaching labs, desktop Shiny apps via native or Electron or Tauri wrappers, auto-download on first launch using predictable URL patterns, and internal tools for reports, ETL, and automation.

Figure 4: Portable R as a building block for CI pipelines, desktop Shiny apps, auto-download workflows, teaching labs, and internal tooling.

The next step is tooling that builds on this: a Shiny app packaged as a native executable, a deployment script that provisions R on the fly, an Electron or Tauri wrapper that downloads the right portable R on first launch. Posit’s portable Linux binary packages are bringing the same portability thinking to the package level. Together, these efforts move the R ecosystem toward what Python already has with python-build-standalone and PyInstaller: runtimes and packages that can be provisioned and shipped without assuming anything about the host system.

Fin

portable-r-macos is open source and available now at github.com/portable-r/portable-r-macos, with releases for R 4.3.0 through 4.5.3 across arm64 and x86_64, Developer ID signed and Apple notarized. The Windows counterpart is at github.com/portable-r/portable-r-windows and covered in the companion post.

References