renv for ReproducibilityMarch 3, 2026
renv?renv is an R package that helps make R projects reproduciblerenv manages packagesrenv::paths$cache()renv/library/):
This design saves disk space and ensures isolation between projects.
renvIn the following we assume the renv package is installed. If not, run install.packages("renv")
We first cover two scenarios to start using renv
We then explain how to use renv for routine package management. If the goal is to reproduce a study, this step is not required.
renv functionsrenv offers a wide set of function calls, but we will use only 4 functions to achieve all tasks:
renv::init()renv::restore()renv::install()renv::snapshot()renv in a projectrenv::init(). It
.R, .Rmd, .qmd, .Rnw) for required packages and their dependenciesrenv/library/ and installs packages (or links) into the project libraryrenv.lock, which contains R and R package metadata recording the state of the project library (and used to reproduce project library by others or future self).Rprofile and renv/activate.Rrenv.lock to gitKey idea: renv.lock is the single source of truth
renv.lockrenv::restore(). It
renv/library/ and installs packages (or links) recorded in renv.lock into the project library. This step may take a long time..Rprofile and renv/activate.R (overwrites if files already exist)Note: when you start R in a folder or start a project in RStudio, if the folder/project already contains .Rprofile and renv/activate.R, it will automatically start installing packages (or links) recorded in renv.lock into the project library. This step may take a long time.
renv for routine package managementWhen a project folder contains .Rprofile and renv/activate.R, R configures the session to use renv/library on startup. This ensures that the right versions of packages are used
To install or update new packages from either CRAN (pkg1) or GitHub (user/pkg2), run
renv::install("pkg1"); renv::install("user/pkg2") orrenv::install(c("pkg1", "user/pkg2"))To update renv.lock with package version info, run renv::snapshot()
If a collaborator updates renv.lock, call renv::restore() to sync your project library with the new renv.lock
Notes:
base::install.packages(), remotes::install_github() or other methods to install packages may have undesirable effects and is not recommendedrenv::install() can also install specific versions of packages, e.g., renv::install("https://cran.r-project.org/src/contrib/Archive/kyotil/kyotil_2024.7-31.tar.gz")renv.lock as the working directory to avoid certain errors.Rprofile, renv.lock, and renv/curl: (22), the requested URL returned error: 403 rate limit exceeded, the solution is to first authenticate with your GitHub personal access token by Sys.setenv(GITHUB_PAT = "xxxxxxxxxxxxx")renvrenv records the R version but does not install R for youIn the following we will cover some more advanced topics related to renv.
.renvignoreIf project includes R code that should or can be ignored by renv, add respective files/folders to .renvignore at the top level
dev/ to ignore the folder dev and all its contentrenv.lock at different levels of code hierarchyThe repo CoVPN/correlates_reporting2 contains multiple modules (e.g., cor_coxph, cor_threshold) for multiple types of analyses. We recommend either using module-level project library (e.g., cor_coxph/renv.lock) or project-level library (e.g., cor_threshold/sanofi_stage2/renv.lock)
To use module-level project library, some changes are needed so that rendering Rmd reports uses module-level library instead of root-level library. Take cor_coxph as an example
cor_coxph for example)index_cor.Rmd and book.bib from repo root to cor_coxph/_bookdown_cor_coxph.yml from repo root to cor_coxph/res = knitr::knit_child(c(here::here('cor_coxph', 'additional_model.Rmd'))) becomesres = knitr::knit_child(c(here::here('.', 'additional_model.Rmd')))