renv: Project Environments for R
This article is originally published at https://www.rstudio.com/blog/
We’re excited to announce that
renv is now available on CRAN! You can install
renv is an R dependency manager. Use
renv to make your projects more:
Isolated: Each project gets its own library of R packages, so you can feel free to upgrade and change package versions in one project without worrying about breaking your other projects.
renvcaptures the state of your R packages within a lockfile, you can more easily share and collaborate on projects with others, and ensure that everyone is working from a common base.
renv::snapshot()to save the state of your R library to the lockfile
renv.lock. You can later use
renv::restore()to restore your R library exactly as specified in the lockfile.
If you’ve used Packrat before, this may all feel familiar. User feedback has made it clear that a number of the decisions we made during Packrat’s development ultimately made it frustrating to use, and led to a sub-optimal user experience. The goal then is for
renv to be a robust, stable replacement for the Packrat package, with fewer surprises and better default behaviors. While we will continue maintaining Packrat, all new development will focus on
In addition, we’ve built
renv to work well with R projects using Python through
renv, you can also create project-local Python environments, and instruct
reticulate to automatically bind to, manage, and use these environments.
The core essence of the
renv workflow is fairly simple:
renv::init()to initialize a project.
renvwill discover the R packages used in your project, and install those packages into a private project library.
Work in your project as usual, installing and upgrading R packages as required as your project evolves.
renv::snapshot()to save the state of your project library. The project state will be serialized into a file called
renv::restore()to restore your project library from the state of your previously-created lockfile
In short: use
renv::init() to initialize your project library, and use
renv::restore() to save and load the state of your library.
After your project has been initialized, you can work within the project as before, but without fear that installing or upgrading packages could affect other projects on your system.
When you want to share a project with other collaborators, you may want to ensure everyone is working with the same environment – otherwise, code in the project may unexpectedly fail to run because of changes in behavior between different versions of the packages in use. You can use
renv to help make this possible.
renv, the packages used in your project will be recorded into a lockfile,
renv.lock records the exact versions of R packages used within a project, if you share that file with your collaborators, they will be able to use
renv::restore() to install exactly those packages into their own library. This implies the following workflow for collaboration:
Make sure your project is initialized with
renv::snapshot()as needed, to generate and update
Share your project sources, alongside the generated lockfile
After your collaborators have received your
renv.lock lockfile – for example, by cloning the project repository – they can then also execute
renv::init() to automatically install the packages declared in that lockfile into their own private project library. By doing this, they will now be able to work within your project using the exact same R packages that you were when
renv.lock was generated.
On some occasions, you might find that you’ve made a change to
renv.lock that you’d like to roll back. If you’re using Git for version control with your project (and we strongly encourage you to!),
renv has a couple helper functions that make it easy to find and use previously-committed versions of the lockfile.
renv::history()to view past versions of
renv.lockthat have been committed to your repository, and find the commit hash associated with that particular revision of
renv::revert()to pull out an old version of
renv.lockbased on the previously-discovered commit, and then use
renv::restore()to restore your library from that state.
If you have an alternate version control system you’d like to see us support, please let us know!
Integration with Python
renv also makes it easy to set up a project-local Python environment to use with your R projects. This can be especially useful if you’re using the
reticulate package, or other packages depending on reticulate such as
keras. Just call:
and a project-local Python environment will be set up and used by
renv's Python integration is active, a couple extra features will activate:
reticulateto load your project-local version of Python by default, avoiding some of the challenges with finding and selecting an appropriate version of Python on the system.
reticulate::py_install()will install packages into the project’s Python environment by default.
renv::snapshot()is called, your project’s Python library will also be captured into
requirements.txt(for virtual environments) /
environment.yml(for Conda environments).
renv::restore()will also attempt to restore your Python environment, as encoded in
environment.ymlfrom a previous snapshot.
If you’ve used Packrat before, you’re likely interested to learn what’s changed in
renv. We’ll try to summarize the most poignant changes:
packrat::init() would, by default, attempt to retrieve package sources from CRAN under the assumption that you might want to rebuild packages from sources in the future (e.g. in an offline environment). This assumption was rarely true, and still often was unhelpful as many packages are difficult to build from sources.
To alleviate this,
renv::init() no longer downloads package sources, and also attempts to copy and reuse packages already installed in your R libraries. This makes initializing new projects a breeze – you no longer have to sit around and wait as your project’s multitude of dependencies get reinstalled; instead, the copies already available on your system will be copied and re-used.
Snapshots and Dependencies
packrat::snapshot() would, in addition to capturing the state of your project library, also attempt to discover the R packages used in your project by crawling your
.Rmd files for dependencies. Unfortunately, this system was fairly unreliable and caused a number of issues, especially when the machinery itself emitted warnings or errors that could not be easily diagnosed.
The dependency discovery machinery in
renv has been rewritten from the ground up, and should now be much more reliable. However, if you discover that this still causes issues for you, you can disable this altogether by changing the type of snapshot performed in your project. Use
renv::settings$snapshot.type("simple") to use “simple” snapshots in your project, where the state of your library is captured as-is without any extra filtering to limit which of your installed packages enter the lockfile.
renv comes with a couple extra tools out-of-the-box to help with common development workflows:
Install packages from a wide variety of sources with
renv::install()understands a subset of the remotes specification, and so can be used for simple, dependency-free package installation in your projects. Currently, you can install packages from CRAN, GitHub, Gitlab, and Bitbucket. In addition,
renvis also compatible with other tools commonly used to install packages, such as
renv::dependencies()to enumerate the R dependencies in your project. If necessary, use
.renvignorefiles to tell
renvwhich files and folders should not be scanned during dependency discovery.
Finally, if you have a Packrat project that you’d like to try porting to
renv, you can use
renv::migrate() to migrate the project infrastructure over to
Please check out the
renv Getting started guide to learn more. If you are looking for strategies to manage reproducible environments, or don’t know if
renv is the right fit, check out https://environments.rstudio.com. If you have questions or comments, please get in touch with us on the RStudio community forums.
Please visit source website for post related comments.