knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = FALSE )
The renv
package is a new effort to bring project-local R dependency
management to your projects. The goal is for renv
to be a robust, stable
replacement for the Packrat package, with
fewer surprises and better default behaviors.
Underlying the philosophy of renv
is that any of your existing workflows
should just work as they did before -- renv
helps manage library paths (and
other project-specific state) to help isolate your project's R dependencies,
and the existing tools you've used for managing R packages (e.g.
install.packages()
, remove.packages()
) should work as before.
The general workflow when working with renv
is:
Call renv::init()
to initialize a new project-local environment with a
private R library,
Work in the project as normal, installing and removing new R packages as they are needed in the project,
Call renv::snapshot()
to save the state of the project library to the
lockfile (called renv.lock
),
Continue working on your project, installing and updating R packages as needed.
Call renv::snapshot()
again to save the state of your project library if
your attempts to update R packages were successful, or call renv::restore()
to revert to the previous state as encoded in the lockfile if your attempts
to update packages introduced some new problems.
The renv::init()
function attempts to ensure the newly-created project
library includes all R packages currently used by the project. It does this
by crawling any R files within the project for dependencies with the
renv::dependencies()
function. The discovered packages are then installed
into the project library with the renv::hydrate()
function, which will also
attempt to save time by copying packages from your user library (rather than
re-installing from CRAN) as appropriate.
Calling renv::init()
will also write out the infrastructure necessary to
automatically load and use the private library for new R sessions launched
from the project root directory. This is accomplished by creating (or amending)
a project-local .Rprofile
with the necessary code to load the project when
the R session is started.
With Packrat, one can save and restore the state of the private library with
packrat::snapshot()
and packrat::restore()
. The same model is used here:
Call renv::snapshot()
to save the state of your project to a lockfile; and
Call renv::restore()
to restore the state of your project from a lockfile.
Be aware that renv::restore()
may fail if a package was originally installed
through a CRAN-available binary, but that binary is no longer available. renv
will attempt to install the package from sources in this situation, but attempts
to install from source can (and often do) fail due to missing system
prerequisites for compilation of a package. On Windows, the renv::equip()
function may be useful -- it will download external software commonly used when
compiling R packages from sources, and instruct R to use that software during
compilation.
By default, renv
will maintain and use a global cache of packages during
renv::restore()
, so (at least on the same machine) if that cache is maintained
old projects will be restored by copying or linking from an installation
discovered in the cache.
The following files are written to and used by projects using renv
:
| File | Usage |
| ----------------- | ----------------------------------------------------------------------------------- |
| .Rprofile
| Used to activate renv
for new R sessions launched in the project. |
| renv.lock
| The lockfile, describing the state of your project's library at some point in time. |
| renv/activate.R
| The activation script run by the project .Rprofile
. |
| renv/library
| The private project library. |
In particular, renv/activate.R
ensures that the project library is made
active for newly launched R sessions. This effectively ensures that any
new R processes launched within the project directory are isolated.
For development and collaboration, the .Rprofile
, renv.lock
and
renv/activate.R
files should be committed to your version control system; the
renv/library
directory should normally be ignored. Note that renv::init()
will attempt to write the requisite ignore statements to the project
.gitignore
.
After initializing a project with renv
, that project will then be 'bound'
to the particular version of renv
that was used to initialize the project.
If you need to upgrade (or otherwise change) the version of renv
associated
with a project, you can use renv::upgrade()
. Currently, this will (by default)
install the latest version of renv
available from GitHub; once CRAN releases
of renv
are available, we will likely prefer installation of the latest CRAN
release.
With each commit of renv
, we bump the package version and also tag the
commit with the associated package version. This implies that you can call
(for example) renv::upgrade(version = "0.3.0-17")
to request the installation
of that particular version of renv
if so required.
One of renv
's primary features is the use of a global package cache, which
is shared across all projects using renv
. The cache works as follows:
renv::init()
, package depencencies in the project are discovered.renv
cache.This allows a single package installation to be shared across multiple projects, while allowing these projects to still remain isolated from one another. Because each project uses its own project library, packages can be upgraded as needed without risk of affecting any other projects still using the previous version of the package.
By default, renv
generates its cache in the following folders:
| Platform | Location |
| ------------ | ------------------------------------ |
| Linux | ~/.local/share/renv
|
| macOS | ~/Library/Application Support/renv
|
| Windows | %APPDATA%/renv
|
If you'd like to share the package cache across multiple users, you can do so by
setting the RENV_PATHS_CACHE
environment variable as required. This variable
can be set in an R startup file to make it apply to all R sessions. For example,
it could be set within:
.Renviron
;.Renviron
;$(R RHOME)/etc/Renviron.site
.While we recommend enabling the cache by default, if you're having trouble with
renv
when the cache is enabled, it can be disabled by setting the R option
options(renv.config.use.cache = FALSE)
. Doing this will ensure that packages
are then installed into your project library directly, without attempting to
link and use packages from the renv
cache.
If you find a problematic package has entered the cache (for example, an
installed package has become corrupted), that package can be removed with the
renv::purge()
function.
In the end, renv
still needs to install R packages -- either from binaries
available from CRAN, or from sources when binaries are not available.
Installation from source can be challenging for a few reasons:
Your system will need to have a compatible compiler toolchain available. In some cases, R packages may depend on C / C++ features that aren't available in an older system toolchain, especially in some older Linux enterprise environments.
Your system will need requisite system libraries, as many R packages contain compiled C / C++ code that depend on and link to these packages.
To help you take advantage of the package cache, renv
places a couple of
shims on the search path:
| Function | Shim |
| -------------------- | ----------------- |
| install.packages()
| renv::install()
|
| remove.packages()
| renv::remove()
|
| update.packages()
| renv::update()
|
This can be useful when installing packages which have already been cached.
For example, if you use renv::install("dplyr")
, and renv
detects that
the latest version on CRAN has already been cached, then renv
will just
install using the copy available in the cache -- thereby skipping some of
the installation overhead.
If you'd prefer not to use the renv
shims, they can be disabled by setting
the option options(renv.shims = FALSE)
.
If you're using a version control system with your project, then as you call
renv::snapshot()
and later commit new lockfiles to your repository, you may
find it necessary later to recover older versions of your lockfiles. renv
provides the functions renv::history()
to list previous revisions of your
lockfile, and renv::revert()
to recover these older lockfiles.
Currently, only Git repositories are supported by renv::history()
and
renv::revert()
.
renv
differs from Packrat in the following ways:
renv
no longer attempts to explicitly download and track R package sources
within your project. This was a frustrating default that operated under the
assumption that you might later want to be able to restore a project's private
library without access to a CRAN repository; in practice this is almost never
the case, and the time spent downloading + storing the package sources
seemed to outweigh the potential reproducibility benefits.
Packrat tried to maintain the distinction between so-called 'stale' packages;
those being R packages which were installed by Packrat but are not recorded
in the lockfile for some reason. This distinction was (1) overall not useful,
and (2) confusing. renv
no longer makes this distinction:
snapshot()
saves the state of your project library to renv.lock
,
restore()
loads the state of your project library from renv.lock
, and
that's all.
In renv
, the global package cache is enabled by default. This should
reduce overall disk-space usage as packages can effectively be shared
across each project using renv
.
The renv::migrate()
function makes it possible to migrate projects from
Packrat to renv
. See the ?migrate
documentation for more details. In
essence, calling renv::migrate("<project path>")
will be enough to
migrate the Packrat library and lockfile such that they can then be
used by renv
.
renv
, like Packrat, is designed to work standalone without the need to
depend on any non-base R packages. However, the following (future) integrations
are planned:
Use pak for parallel package installation,
Use sysreqsdb to validate and install system dependencies as required before attempting to install the associated packages.
These integrations will be optional (so that renv
can always work standalone)
but we hope that they will further improve the speed and reliability of renv
.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.