Install, Update, Load Packages from CRAN, 'GitHub', and 'Bioconductor' in One Step

Automatically install, update, and load 'CRAN', 'GitHub', and 'Bioconductor' packages in a single function call. By accepting bare unquoted names for packages, it's easy to add or remove packages from the list.

CRAN_Status_Badge Download Stats

librarian::shelf(dplyr, DesiQuintans/desiderata, phyloseq)
                   ↑        ↑                      ↑
                  CRAN     GitHub                 Bioconductor
# All downloaded, installed, and attached.

librarian lets you quickly install, update, and attach packages from CRAN, GitHub, and Bioconductor in one function call. It has these advantages over base R and other library management packages like pacman:

Advantage 1: Librarian installs and attaches in one function call

shelf(dplyr, DesiQuintans/desiderata, phyloseq)

Is a lot nicer than:


Advantage 2: Librarian has a consistent interface

It bothered me that install.packages() can install many packages, but library() can only attach one at a time. It bothered me that install.packages() needs a character vector, but library() can accept either a character vector or a bare name.

Core librarian functions (shelf, reshelf, unshelf) always accept a list of one or more bare names.

Advantage 3: Librarian's package lists are easy to read and easy to maintain

Using bare names instead of strings frees you from typing quotes all the time. Having all of your packages in one shelf() call means that the reader can get an overview of your package dependencies at a glance.

Rather we want the imports to be a concise statement about which packages we collaborate with.

--- Robert C. Martin, Clean Code


You can install librarian from CRAN or from GitHub. The GitHub version is under constant development, but it has more features and it is stable for use (it's the one I personally use, after all).

Features that are currently MISSING from the CRAN release: None, we're up to date! The last CRAN release was v1.6.0 on 2019-02-22.

# From CRAN:
# From GitHub:

Once it's installed, you can get librarian to automatically load at the start of every R session:

librarian::lib_startup(librarian, global = TRUE)

And you can also specify a library folder to install new packages into by default:

librarian::lib_startup(librarian, lib = "C:/Dropbox/My R Library", global = TRUE)

Or if you don't want to do that, you can attach it with library(librarian) or access the functions directly with :: notation:


Quick tour of librarian

The metaphor behind function names is one of a very large public library that has more books than public shelf space. The librarian needs to decide what books are useful enough to warrant display, and which books should stay in storage for now. You take packages out of storage and put them on the shelf() (the search path) when you need them, and then unshelf() them when you don't need them.

More in-depth documentation for each function is in the Examples section below.

Function Example Description
shelf() shelf(cowsay, DesiQuintans/desiderata) Attach packages to the search path, installing them from CRAN, Bioconductor, or GitHub if needed. They will be installed to the first folder in lib_paths().
unshelf() unshelf(cowsay, desiderata) Detach packages from the search path. You can also detach their dependencies.
reshelf() reshelf(desiderata) Detach and then reattach packages, helpful for refreshing a personal package.
lib_paths() lib_paths("C:/new_lib_folder") View and edit the folders where R will install and search for packages.
lib_startup() lib_startup(librarian, forcats) Automatically attach libraries and packages at the start of every R session.
browse_cran() browse_cran("linear regression") Discover CRAN packages by keyword search or regular expression.



shelf() attaches packages to the search path, first installing them from CRAN, GitHub, or Bioconductor if needed.

The order of package names is the order they will be attached to the current R session.

For CRAN packages, provide the package name as normal. For Bioconductor packages, provide the package name as normal and make sure that Bioconductor's Biobase package is installed. For GitHub packages, provide the username and package name separated by /.

shelf(cowsay, DesiQuintans/desiderata, zlibbioc)

The default installation folder is always the first folder in lib_paths(). To change the installation folder, set the lib argument.

If lib doesn't already exist, shelf() can create it for you. By default, you will be asked for permission before the folder is created. To create the folder silently, set ask = FALSE.

shelf(cowsay, DesiQuintans/desiderata, lib = "C:/new_lib_folder", ask = TRUE)

You can download from a specific CRAN mirror by setting cran_repo. The default value of cran_repo is the value set in getOption("repos"). You can set this in RStudio using Options > Packages > Default CRAN Mirror. If you are not in RStudio this option may not be correctly set. In all cases where cran_repo is not a valid URL, it defaults to

You can also set a Bioconductor repo using the bioc_repo argument, although it perhaps better to use the built-in utils::chooseBioCmirror() function.

shelf(dplyr, cran_repo = "")

To force all of the named packages to re-download and re-install, use update_all = TRUE.

Note that this only updates the named packages and not their dependencies. To update dependencies also, run devtools::update_packages(c("pkg1", "pkg2", ...)). As usual, be careful when updating packages; your old scripts might need to be updated if packages have changed their function behaviours.

If you specify a new lib and use the argument update_all = TRUE to force an already-installed package to reinstall, a new copy of that package will be made in lib and then loaded from there. This means that you can potentially have several copies of the same package across many folders on your machine, each a different version. This allows you to maintain a different library folder for different projects, so that updated packages in Project B will not affect the package versions you rely on for Project A.

shelf(dplyr, DesiQuintans/desiderata, purrr, update_all = TRUE)

The quiet = TRUE flag can suppress many of the messages that are routinely printed by the base install/attach functions.

shelf(dplyr, DesiQuintans/desiderata, purrr, quiet = TRUE)

shelf invisibly returns a named vector of the packages that were requested and whether they are now attached.

shelf(janitor, DesiQuintans/desiderata, purrr)
#>   janitor      purrr desiderata 
#>      TRUE       TRUE       TRUE


When detaching GitHub packages with unshelf(), you can provide the package names only, or you can provide the full username/package identifier as you did with shelf().

unshelf() invisibly returns a named vector of the packages that were requested and whether they are now detached.

If you want to refresh a package by detaching and then reattaching it, use reshelf().

# These are the same:
unshelf(janitor, desiderata, purrr)
unshelf(janitor, DesiQuintans/desiderata, purrr)

You can use the everything = TRUE argument to detach all packages except for the default ones that load when R starts up.

unshelf(everything = TRUE)
#> librarian testthat
#> TRUE      TRUE

The also_depends = TRUE argument will also detach the dependencies of the packages you've requested in .... If safe = TRUE, packages won't be detached if they're still needed by other packages that aren't in ....

shelf(tidyverse, janitor)  
#> [1] "janitor"   "forcats"   "stringr"   "dplyr"     "purrr"     "readr"     "tidyr"     "tibble"   
#> [9] "ggplot2"   "tidyverse" "librarian" "stats"     "graphics"  "grDevices" "utils"     "datasets" 
#> [17] "methods"   "base"     
# Tidyverse loads dplyr and purrr, which Janitor depends on. The safe = TRUE argument 
# will stop them from being detached even though Tidyverse is being detached 
# with also_depends = TRUE.
unshelf(tidyverse, also_depends = TRUE, safe = TRUE, quiet = FALSE)
#> Some packages were not detached because other packages still need them:
#>     dplyr  purrr  tidyr
#> To force them to detach, use the 'safe = FALSE' argument.
#> [1] "janitor"   "dplyr"     "purrr"     "tidyr"     "librarian" "stats"     "graphics"  "grDevices"
#> [9] "utils"     "datasets"  "methods"   "base"     
unshelf(tidyverse, also_depends = TRUE, safe = FALSE, quiet = FALSE)
#> [1] "janitor"   "librarian" "stats"     "graphics"  "grDevices" "utils"     "datasets"  "methods"  
#> [9] "base"

In the example above, setting quiet = TRUE will suppress the "some packages were not detached" message.


reshelf() detaches and then reattaches packages. This is useful when you have a personal package, because you'll often find yourself adding a function to it and rebuilding it in one instance of RStudio, and then reloading the new build in a different RStudio instance that contains your actual work. Its return value is identical to shelf().

# is identical to
unshelf(DesiQuintans/desiderata, safe = FALSE, warn = FALSE))


lib_paths() lets you view and edit the list of folders that R will look inside when trying to find a package (the package search path). You can also add an existing folder, create and add a new folder, or shuffle a folder to the front of the list so that it is used as the default installation location for new packages in the current session.

When called without arguments, returns a vector of the folders where R will search for and install packages.

#> [1] "D:/R/R-3.5.0/library"

You can offer a path to a folder to add it to the package search path. If this folder doesn't exist, lib_paths() can create it if you set make_path = TRUE.

lib_paths(file.path(tempdir(), "newlibraryfolder"), make_path = TRUE)
   #> The requested library folder does not exist:
   #> C:/Users/.../Temp/Rtmp0Qbvgo/newlibraryfolder
   #> Create it?
   #> y/N/c
# y
#> [1] "C:/Users/.../Temp/Rtmp0Qbvgo/newlibraryfolder"
#> [2] "D:/R/R-3.5.0/library"

If you don't want to be prompted, you can set ask = FALSE to allow the folder to be created silently.

lib_paths(file.path(tempdir(), "another_folder"), make_path = TRUE, ask = FALSE)
#> [1] "C:/Users/.../Temp/Rtmp0Qbvgo/another_folder"
#> [2] "C:/Users/.../Temp/Rtmp0Qbvgo/newlibraryfolder"
#> [3] "D:/R/R-3.5.0/library"

Notice that folders are always prepended to the front of the search path. Adding an existing folder moves it to the front.

lib_paths(file.path(tempdir(), "newlibraryfolder"))
#> [1] "C:/Users/.../Temp/Rtmp0Qbvgo/newlibraryfolder"
#> [2] "C:/Users/.../Temp/Rtmp0Qbvgo/another_folder"
#> [3] "D:/R/R-3.5.0/library"


lib_startup() tells R to attach packages and library folders automatically at the start of every session.

Note that this messes with the reproducibility of your scripts; other people won't have your .Rprofile script, so they won't know what packages are being attached behind-the-scenes. This is really just a convenience for you. You should still explicitly load the packages that you need in your analysis scripts.

You can provide a list of packages that you would like to start with every R session. lib_startup() will add your current library folders as well as your current library paths (by default) to a file called .Rprofile.

If global = TRUE, then .Rprofile will be created in your home folder and will be applied to every session. If global = FALSE, then .Rprofile will be created in the project folder (i.e. the current working directory) and the global .Rprofile will be ignored for this project.

lib_startup(librarian, magrittr, global = TRUE)
#> Added library paths and startup packages to:
#>   C:/Users/.../Documents/.Rprofile
#> Library paths:
#>   'D:/Dropbox/Apps/R library', 'D:/R/R-3.5.1/library'
#> Startup packages:
#>   'datasets', 'utils', 'grDevices', 'graphics', 'stats', 'methods', 'librarian', 'magrittr'

Notice that your packages are loaded after R's default packages. If the environmental variable R_DEFAULT_PACKAGES is set then it will use those packages, otherwise it will use R's own list of defaults: datasets, utils, grDevices, graphics, stats, and methods.

If you want to load only the default packages, just run lib_startup() without specifying any packages.

#> Added library paths and startup packages to:
#>   C:/Users/.../Documents/.Rprofile
#> Library paths:
#>   'D:/Dropbox/Apps/R library', 'D:/R/R-3.5.1/library'
#> Startup packages:
#>   'datasets', 'utils', 'grDevices', 'graphics', 'stats', 'methods'


browse_cran() lets you discover CRAN packages from your terminal. The first time you run browse_cran() in a session, it will take about 6–12 seconds to download and cache CRAN data. This only happens once per session; subsequent calls will use the cached copy.


#> RColorBrewer 
#>     Provides color schemes for maps (and other graphics) designed by Cynthia 
#>     Brewer as described at 
#> Redmonder 
#>     Provide color schemes for maps (and other graphics) based on the color 
#>     palettes of several Microsoft(r) products. Forked from 'RColorBrewer' 
#>     v1.1-2.

You can search with keywords or with regular expressions.

browse_cran("zero-inflat.*?abund", fuzzy = FALSE)

#> hurdlr 
#>     When considering count data, it is often the case that many more zero 
#>     counts than would be expected of some given distribution are observed. It 
#>     is well established that data such as this can be reliab[...] 

You can also do fuzzy orderless matching, it's a little slow but it will get you results on tricky searches:

browse_cran("network.*?api.*?twitter", fuzzy = FALSE)

#> No CRAN packages matched query: 'network.*?api.*?twitter'.

browse_cran("network twitter api", fuzzy = TRUE)

#> RKlout 
#>     An interface of R to Klout API v2. It fetches Klout Score for a Twitter 
#>     Username/handle in real time. Klout is a website and mobile app that uses 
#>     social media analytics to rank its users according to [...] 

Project participants

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.


librarian 1.7.0 (2019-03-13)

  • FIX - You can now detach everything except R's default packages by using safe = FALSE in unshelf(). If safe = TRUE, the packages that you've set as default ones in your .RProfile (via lib_startup() for example) will not be detached. Fixes #17.
  • ADD - check_attached() and check_installed(), which lets you check the status of packages. If you run the functions with no packages named, they will return a list of all packages that are attached and installed.
  • MOD - shelf(), unshelf(), reshelf(), check_attached(), and check_installed() can now accept four different input methods:
    1. A comma-separated list of bare names. shelf(package, name, here)
    2. A comma-separated list of strings. shelf("package", "name", "here")
    3. A comma-separated list of names and strings. shelf("package", name, "here")
    4. A character vector of package names, as long as it is the only item passed in .... shelf(c("package", "name", "here"))
    • These changes were made to accomodate the advanced input methods of remotes. They also make it possible to use these functions inside scripts, like passing package lists around.
  • ADD - Many new unit tests, with more stringent testing methods.
  • MOD - Major refactoring. The biggest change is that user-facing stuff like messages have been extracted from the functions so that the logic of the function is easier to maintain.

librarian 1.6.1 (2019-03-09)

  • FIX - unshelf() with everything = TRUE arg now detaches all non-default packages if safe = FALSE is also set. In the past, it would leave behind the packages that you had added to your .Rprofile using lib_startup(). This is still the default behaviour.
  • ADD - Various behind-the-scenes helper functions in preparation for a code refactor.

librarian 1.6.0 (2019-02-19)

  • MOD - biocLite has been replaced with BiocManager for installing BioConductor packages. BiocManager has been added as a dependency.
  • FIX - Various spelling errors in preparation for CRAN submission.
  • ADD - Vignette for CRAN
  • ADD - browse_cran() for searching CRAN package titles and descriptions by keyword or regular expression.

librarian 1.5.5 (2019-02-18)

  • FIX - nse_dots() used to insert spaces in names that included - because it was formatting them nicely as if they were expressions with the minus operator. The function now removes any spaces that were created in the process of converting from a symbol to a string. Closes #13.
  • MOD - remotes replaces devtools. Closes #11.
  • REM - The backports package is no longer needed.

librarian 1.5.4 (2019-02-15)

  • FIX - The regular expression used in librarian:::check_installed() failed if the package name had a . inside it, so those packages were installable but not attachable with librarian. Closes #12.

librarian 1.5.3 (2019-01-24)

  • MOD - Less alarming and more informative message (not a warning) for when the cran_repo argument in shelf() contains the default R value @[email protected]. Closes Issue #10. Thanks, Jim Hunter!

librarian 1.5.2 (2018-11-19)

  • FIX - The code comment that lib_startup() uses to mark the lines it edited previously indicated an old function name.

librarian 1.5.1 (2018-11-15)

  • MOD - check_installed() now works much faster, so librarian in general should work much faster because check_installed() was called in every function.

librarian 1.5.0 (2018-11-02)

  • ADD - lib_startup() lets you set library search paths and packages that will be loaded globally at the start of every R session, or on a per-project basis.

librarian 1.4.0

  • ADD - shelf() now supports installing Bioconductor packages via biocLite(). Bioconductor's Biobase package needs to be installed before librarian will attempt to install Bioconductor packages.

librarian 1.3.2

  • REVERT - R dependency back to => 3.4.0.

librarian 1.3.1

  • FIX - librarian was written for R 3.5.0 but only asked for 3.4.0 as a dependency. The R dependency is now 3.5.0.
  • MOD - I have added a dependency for backports so that users of R < 3.5.0 do not have to update their R installation for only one important function that librarian needs (...length()). Closes issue #4.
  • FIX - Sometimes the CRAN URL check would return a vector of length >1, raising a warning message.

librarian 1.3.0

  • ADD - lib_paths() is a wrapper for .libPaths() with folder creation built-in. It lets you name and create folders where new packages will be installed, view the folders that are on the package search path, and reshuffle their order.
  • ADD - lib argument for shelf() lets you specify the folder where new packages will be installed. The ask argument controls whether R asks for permission before creating this folder; set ask = FALSE to create the folder automatically.
    • If the packages are already installed, they will be loaded from their current location and not re-installed.
    • If you set update_all = TRUE, a new copy of the package will be installed to lib. This means that you can potentially have several copies of the same package across many folders on your machine, each a different version. I felt that this was reasonable so that you could maintain a different library folder for different projects, and updates that you made in Project B would not affect the package versions you rely on for Project A.
  • FIX - The cran_repo warning raised by shelf() now shows the original string.
  • FIX - Unexported functions are now properly documented.
  • FIX - unshelf() raises an error when you haven't told it to detach anything.

librarian 1.2.0

  • FIX - shelf() now sets a default CRAN repo properly on the command line.
    • REM - The custom_repo argument in shelf() has been renamed to cran_repo.
    • cran_repo arg checks that its value is a valid URL. I previously supported custom_repo = NULL because the base install.packages() uses NULL to signal installation from a local file, but the point of librarian is to install CRAN and GitHub packages from the net, so cran_repo does not keep this functionality.
  • MOD - Improved the documentation following CRAN feedback.
  • ADD - shelf(), unshelf(), and reshelf() now invisibly return named vectors describing the packages that were operated on and whether they were successfully attached or detached.
  • ADD - Unit tests to make sure that my fixes don't break stuff.
  • ADD - unshelf(everything = TRUE) argument detaches all packages except for the default ones.
  • ADD - unshelf(safe = TRUE) argument checks if packages are still needed by others before detaching them.
  • ADD - unshelf(warn = TRUE) argument will print a Message if packages were not detached (because safe = TRUE and the packages were still needed).
  • ADD - unshelf(..., also_depends = TRUE) argument detaches packages named in ... as well as their dependencies.
    • With the safe and quiet arguments defaulting to TRUE, the default behaviour is to leave packages behind if other packages in the search path still need them, but not to interrupt the user with a message about it. unshelf() still invisibly returns the success/failure for each package it attempted to detached.
    • Looking through the search path is pretty slow, I don't recommend it for sessions with lots of packages!
  • MOD - The new dependency-checking code needs the tools package, but it's distributed with R.

librarian 1.1.0

  • ADD - reshelf() for refreshing a package. Useful for loading new builds of your personal package.

librarian 1.0.3

  • ADD - unshelf() can handle the Github Username/packagename format now, instead of requiring the user to provide only the package name. The biggest effect of this change is that if you want to unload your packages, you can now just change your shelf() to unshelf() and run it.
  • ADD - shelf() and unshelf() check for duplicates in the package list you provide.

librarian 1.0.2

  • FIX - Many documentation changes for CRAN submission.
  • FIX - Import utils (a default package) for base R's package-handling functions. Omitting this caused warnings in R CMD CHECK.
  • FIX - Bug in unshelf() that made it try to unload packages even if they were not loaded.
  • ADD - custom_repo argument for shelf(), which defaults to R's default behaviour.

librarian 1.0.1

  • REM - No longer imports rlang. Only imports devtools now.
  • ADD - shelf() now returns devtools::session_info() invisibly so that you can print it.
  • ADD - file to track changes to the package.
  • ADD - info re. updating package dependencies.

librarian 1.0.0

  • Initial release. Includes shelf() and unshelf() in feature-complete form.

Reference manual

It appears you don't have a PDF plugin for this browser. You can click here to download the reference manual.


1.8.1 by Desi Quintans, 6 months ago

Report a bug at

Browse source code at

Authors: Desi Quintans [aut, cre]

Documentation:   PDF Manual  

GPL-3 license

Imports BiocManager, remotes, tools, utils

Suggests testthat, knitr, rmarkdown

Imported by upstartr.

See at CRAN