Upgrade R!

And how you should do it in my opinion.

Author

Sebastian Carl

Published

June 27, 2025

Introduction

Sooner or later, every R user comes to the point where it is time to upgrade R. Quite a few are reluctant to perform such updates because they are afraid that their packages or scripts may no longer work as expected afterwards. Or because - depending on the version jump - they may lose their library.

Let’s first briefly talk about the versioning of R and the typical update cycle (information on this can be found on the R Developer Page).

R Versioning

R is semantically versioned in the form {major}.{minor}.{patch}. The update plan intends that there will be a {minor} release every spring. This {minor} release is then followed by {patch} releases on an as-needed basis. The last {patch} release comes in spring shortly before the jump to the next {minor} version.

Why am I explaining this here? It is relevant because as a user you can “lose” your library during {minor} or {major} version jumps. You’ve probably experienced this before, right? After the R upgrade, only the core packages are installed. All other packages that you normally use are no longer “there”. This is because there is a new directory for each {minor} release in which your library lives. So your library is not actually “gone”, but it is in the folder of the previous version. The same applies to {major} jumps, of course.

Here we have an important lesson: {patch} releases are completely “harmless” for you as a user because there are no new folders for them and your library is preserved with every patch. So you should always happily install patches!

Note

Patch releases preserve your library!

There are recommendations and packages circulating that tell you to simply move your library to the new folder after an upgrade. Core developers advise against this.

#rstats folks: If you have a habit of updating your library after an R upgrade by copying the old one and run update.packages(). --> DON'T DO THAT <-- Especially not with 4.5.0. You will overwrite base packages with ones from a previous version and as these are not on CRAN, things go bad.

— Peter Dalgaard (@pdalgd.bsky.social) April 24, 2025 at 7:29 PM

I will explain below how I restore my library after a {minor} jump.

How to Install or Upgrade R

Before I explain how I restore my library after an R upgrade, let me briefly discuss how to actually install or upgrade R.

You are free to simply go to https://cran.r-project.org/ and download R for your platform. At this point, however, I would strongly recommend that you use the command line tool rig. It helps you to install, remove, and configure R versions on macOS, Windows, or Linux.

After installing rig, an R upgrade is as simple as

rig add release

rig will do the rest for you.

Restore Library after an R Upgrade

Now to the question of how we can restore our library as quickly as possible after a {minor} or {major} R version jump.

Before you do this, you should ask yourself the following questions:

  • Do I really need all the packages that were in my previous library?

  • Should I perhaps use the fresh start and only install what I realize is missing when I run my scripts?

Saving a large library from one release to the next may not always be wise. So only follow the next steps if you really feel like it.

BEFORE Upgrade

In order to restore our library, we must first determine which packages are in our library. Pak can create a list for us that we can save locally on the computer. Of course you have to remember the storage location, because we will need the file again AFTER the R upgrade.

mypkgs <- pak::pkg_list()
saveRDS(mypkgs, "mypkgs.rds")

Now Upgrade R

As described in Section 3.

AFTER Upgrade

You are reading this section because your library is no longer available in a new R version. You saved the list with your packages BEFORE the upgrade, so we want to work through this list now.

Two things are important to me here:

  1. We install the packages in a background job so that the session is not blocked. There could be a lot of downloads.

  2. We try to install only binary packages so that it is as fast as possible.

Linux Binaries

Regular CRAN mirrors only provide binaries for Windows and MacOS. If you are working on a Linux OS, these CRAN mirrors will not provide you with binaries. You can then either use Dirk Eddelbüttel’s r2u if you are working with ubuntu. Or - and this is the method of choice for many - you can use the Posit Public Package Manager P3M.

Setting up R on your Linux OS for the installation of binaries via the P3M comes down to

Install CRAN Packages

We first install as many CRAN packages as possible in a background job. The type argument in install.packages() is set to “binary” so that R does not start compiling sources.

# install job so we can use it to install the other packages
install.packages("job")

# that's the file you have saved before the R upograde
mypkgs <- readRDS("mypkgs.rds")

# We focus on CRAN packages first
inst <- mypkgs$package[mypkgs$repository == "CRAN"]

# This will launch a job installing a possibly huge number of packages
job::empty(
  {install.packages(inst, type = "binary")},
  import = c(inst),
  title = "Re-Installing Your Package(s) from CRAN..."
)

Most packages should be back let’s check what we have now (make sure to restart your session after the above job has finished!)

now <- pak::pkg_list()

Are there packages missing (because they weren’t installed from CRAN)?

missing <- mypkgs[!mypkgs$package %in% now$package, ]

Install GitHub Packages

If pkgs were installed from GitHub, we can create the name/repo vector with

gh <- missing[missing$remotetype == "github" & !is.na(missing$remotetype), ] 
add <- paste0(gh$remoteusername, "/", gh$remoterepo)

and again run a job to install those packages

job::empty(
  {pak::pak(add)},
  import = c(add),
  title = "Re-Installing Your Package(s) from Github..."
)

After GitHub installation there shouldn’t be much left (most likely packages that were installed locally from source or from other repositories such as r-universe). Check what is missing and figure out how to install them (again, restart your session after the above job has finished)

now <- pak::pkg_list() 
missing <- mypkgs[!mypkgs$package %in% now$package, ]

That’s it. Your library is restored and you can forget all of this for another year until the next {minor} R upgrade is released.