Package management with CRAN, renv and Bioconductor
Install from the right source, keep project libraries isolated with renv, install from GitHub deliberately, and know what a licence check requires.
Installing from the right source
install.packages("dplyr", repos = "https://cloud.r-project.org")
# pak resolves dependencies faster and shows what it would do first
# install.packages("pak")
pak::pkg_install(c("dplyr", "ggplot2", "readr"))
pak::pkg_install("tidyverse/tidyverse") # a GitHub repository
# a pinned version from CRAN's archive, without leaving crantime travel to memory
pak::pkg_install("dplyr@1.1.0")
# Bioconductor needs its own repository and release matching your R version
if (!requireNamespace("BiocManager", quietly = TRUE)) install.packages("BiocManager")
BiocManager::install("DESeq2")
BiocManager::version()| Source | How | When |
|---|---|---|
| CRAN | install.packages | Default; reviewed and versioned |
| Bioconductor | BiocManager::install | Genomics and bioinformatics |
| GitHub | pak::pkg_install("user/repo") | Development versions, unreleased fixes |
| Local source | install.packages(path, repos = NULL, type = "source") | An internal package |
| Archive | pak::pkg_install("pkg@1.2.3") | Pinning an older release |
Project libraries with renv
renv::init() # project-local library plus renv.lock
renv::install("dplyr@1.1.0") # installs into the project, not the user library
renv::snapshot() # write current versions into the lockfile
renv::restore() # rebuild the library from the lockfile
renv::status()
renv::upgrade() # check for newer versions without installing
renv::status() # confirm the library matches the lockfile
renv::diagnostics() # when the two disagree and you need detail- The lockfile records the exact version, source and hash of every package, which is what makes a project restorable a year later.
renv::restore()installs binaries when available and only compiles from source when it must, so it is usually fast.- A shared library across projects fails the moment two projects need different versions of the same package. Separate libraries remove that class of problem.
renv is not version control for your own code; it pins what your code depends on. Commit the lockfile and the renv/activate.R script, and leave the library directory out of the repository.
Licences and provenance
# licences of everything installed
pkgs <- installed.packages()[, c("Package", "Version", "License")]
head(pkgs[order(pkgs$Package), ])
# the licence of one package, plus its dependencies
pak::pkg_deps("dplyr")[, c("package", "version", "needscompilation")]💡
Most CRAN packages use GPL variants or MIT, but
License: file LICENSE means you must read the file, and some packages restrict commercial use. A licence check is part of shipping software, not an afterthought — record the result next to the lockfile.FAQ
Is pak a replacement for install.packages?
It is a faster, more informative alternative that resolves dependencies in parallel and can pin versions directly.
install.packages remains the zero-dependency baseline that works in any R installation.How do I install an old version of a package?
Use
pak::pkg_install("pkg@1.2.3"), or install from the CRAN archive tarball with install.packages(url, repos = NULL, type = "source"). Compiling from source needs a working toolchain.Related
R Markdown and reproducible reports Installing R and RStudio: the environment
Last refreshed 2026-09-18.