usethis can help you with many of the Git and GitHub tasks that arise when managing R projects and packages. Under the hood, two lower-level packages are critical to this:

  • gert, for Git operations, like git init, git commit, and git push (
  • gh, for GitHub API operations, like creating a repo, forking a repo, and opening a pull request (

Both packages need access to credentials in order to act on your behalf:

  • gert interacts with GitHub as a Git server, using either the HTTPS or SSH protocol
  • gh interacts with GitHub via its REST API

This article describes our recommendations for how to set up your Git and GitHub credentials. Our goal is a setup that works well for usethis and for other tools you may be using, such as command line Git and Git clients (including, but not limited to, RStudio).

This is a good time to check that you have up-to-date versions of the packages we’re talking about here. In particular, you want gh >= v1.2.1, which knows about the new token format GitHub announced and adopted in March 2021.

TL;DR: Use HTTPS, 2FA, and a GitHub Personal Access Token

Our main recommendations are:

  1. Adopt HTTPS as your Git transport protocol
  2. Turn on two-factor authentication for your GitHub account
  3. Use a personal access token (PAT) for all Git remote operations from the command line or from R
  4. Allow tools to store and retrieve your credentials from the Git credential store. If you have previously set your GitHub PAT in .Renviron, stop doing that.

Next we provide some context and a rationale for these recommendations. In the following section, we explain how to actually implement this.


Instead of HTTPS, you could use SSH. Many people have valid reasons for preferring SSH and they should carry on. Our recommendation for HTTPS is because it’s easier than SSH for newcomers to set up correctly, especially on Windows. GitHub has also long recommended HTTPS to new users. Finally, using HTTPS with a PAT kills two birds with one stone: this single credential can be used to authenticate to GitHub as a regular Git server and for its REST API. If you authenticate via SSH for “regular” Git work, you still have to set up a PAT for work that uses the REST API.

Two-factor authentication and your PAT

Turning on two-factor authentication for important online accounts is just a good idea, in general. For example, we make 2FA a hard requirement for all members of the tidyverse and r-lib GitHub organizations. With 2FA activated, GitHub will no longer let you send “username + password” as the credentials for an operation like git push1. Instead, you must send “username + PAT”2. By turning on 2FA and using a PAT, you’re following better security practices and future-proofing your workflow.

Git credential helpers

It’s awkward to provide your credentials for every single Git transaction, so it’s customary to let your system remember your credentials. Git uses so-called credential helpers for this and, happily, they tend to “just work” these days (especially, on macOS and Windows) 3. Git credential helpers take advantage of official OS-provided credential stores, where possible, such as macOS Keychain and Windows Credential Manager.

Recent innovations in gert and gh mean that Git/GitHub operations from R can also store and discover credentials using these same official Git credential helpers. This means we can stop storing GitHub PATs in plain text in a startup file, like .Renviron 4. This, in turn, reduces the risk of accidentally leaking your credentials.

Practical instructions

How do you actually implement these recommendations? Many functions in usethis recommend calling usethis::gh_token_help(), which displays similar advice and links here.


Make sure to use HTTPS URLs, not SSH, when cloning repos or adding new remotes:

  • HTTPS URLs look like this:<OWNER>/<REPO>.git
  • SSH URLs look like this:<OWNER>/<REPO>.git

usethis defaults to HTTPS in functions like create_from_github() and use_github(), as of v2.0.05.

It’s fine to adopt HTTPS for new work, even if some of your pre-existing repos use SSH.
It’s fine to use HTTPS for one remote in a repo and SSH for another.
It’s fine to use HTTPS remotes for one repo and SSH remotes for another.
It’s fine to interact with a GitHub repo via HTTPS from one computer and via SSH from another.
This is not an all-or-nothing or irreversible decision.
As long as the relevant tools can obtain the necessary credentials from a cache or you, you are good to go.

Turn on two-factor authentication

See GitHub’s most current instructions here:

Securing your account with two-factor authentication (2FA)

If you don’t already use a password manager such as 1Password or LastPass, this is a great time to start! Among other benefits, these apps can serve as an authenticator for 2FA.

Turning on 2FA is recommended but optional.
You can still get and use a PAT, even if you have not turned 2FA on.
The difference is that, once you’ve activated 2FA, you absolutely must use a PAT as your HTTPS credential.

Get a personal access token (PAT)

Assuming you’re signed into GitHub, create_github_token() takes you to a pre-filled form to create a new PAT. You can get to the same page in the browser by clicking on “Generate new token” from The advantage of create_github_token() is that we have pre-selected some recommended scopes, which you can look over and adjust before clicking “Generate token”.

It is a very good idea to give the token a descriptive name, because one day you might have multiple PATs, e.g., one that’s configured on your main work computer and another that you use from a secondary computer or VM. Eventually, you’ll need to “spring clean” your PATs and this is much less nerve-wracking if you know which PAT is being used where and for what.

You must store this token somewhere, because you’ll never be able to see it again, once you leave this browser window. If you somehow goof this up, just generate a new PAT and, so you don’t confuse yourself, delete the lost token.

In the moment, we usually copy the PAT to the clipboard, anticipating what we’ll do next: trigger a prompt that lets us store the PAT in the Git credential store. If you use a password management app, such as 1Password or LastPass (highly recommended!), this is a great time to add your PAT to the entry for GitHub. Storing your PAT in the Git credential store is a semi-persistent convenience, sort of like a browser cache or “remember me” on a website, but it’s quite possible you will need to re-enter your PAT in the future.

At this point, we assume you’ve created a PAT and have it available on your clipboard.

Put your PAT into the Git credential store

If you have previously made your GitHub PAT available by setting the GITHUB_PAT environment variable in .Renviron, you need to actively stop doing that.6

How to insert your PAT in the Git credential store?


You will have the gitcreds package installed, as of usethis v2.0.0, because usethis uses gh, and gh uses gitcreds. Call gitcreds::gitcreds_set().

If you don’t have a PAT stored already, it will prompt you to enter your PAT. Paste!

If you do already have a stored credential, gitcreds::gitcreds_set() reveals this and will even let you inspect it. This helps you decide whether to keep the existing credential or replace it. When in doubt, embrace a new, known-to-be-good credential over an old one, of uncertain origins.

Here are two great ways to check that all is well:



Both of these functions reveal whether a GitHub PAT is discovered and provide information about the associated user, the PAT’s scopes, etc.

This step is something you do once. Or, rather, once per machine, per PAT. From this point on, usethis and its dependencies should be able to automatically retrieve and use this PAT.

Sidebar: the gitcreds package plays the same role for gh as the credentials package does for gert. Both gitcreds and credentials provide an R interface to the Git credential store, but are targeting slightly different use cases. The gitcreds and credentials packages are evolving convergently and may, in fact, merge into one. But in the meantime, there is some chance that they use a different “key”, in the “key-value” sense, when storing or retrieving your PAT. Therefore, it is conceivable that gert/credentials may also prompt you once for your PAT, in which case you should just provide it again. To explicitly check if credentials can discover your PAT, call credentials::set_github_pat(). If it cannot, this will lead to a prompt where you can enter it.

Additional resources

Most users should be ready to work with Git and GitHub from R now, specifically with gert, gh, and usethis. In this section, we cover more specialized topics that only apply to certain users.

GitHub Enterprise

As of v2.0.0, usethis should fully support GitHub Enterprise deployments. If you find this is not true, please open an issue.

There are a few usethis functions that support an explicit host argument, but in general, usethis honors the GitHub host implicit in URLs, e.g., the locally configured Git remotes, or inherits the default behaviour of gh. The gh package honors the GITHUB_API_URL environment variable which, when unset, falls back to

In general, usethis, gh, and gitcreds should all work with GitHub Enterprise, as long as the intended GitHub host is discoverable or specified. For example, you can store a PAT for a GitHub Enterprise deployment like so:


At the time of writing, credentials::set_github_pat() is hard-wired to “”, but this may be generalized in the future.

What about .Renviron?

In the past, the most common way to make a GitHub PAT available in R was to define it as the GITHUB_PAT environment variable in the .Renviron startup file. This still works, since gitcreds+gh and credentials+gert check environment variables before they consult the Git credential store. However, this also means that the presence of a legacy GITHUB_PAT in your .Renviron can get in the way of your adoption of the new approach!7

Why do gitcreds+gh and credentials+gert even check environment variables? Once they retrieve a PAT from the store, they temporarily cache it in an environment variable, which persists for the duration of the current R session. This allows a discovered PAT to be reused, potentially by multiple packages, repeatedly over the course of an R session.

Using .Renviron as your primary PAT store is less secure and, if you can, it is safer to keep your PAT in the Git credential store and let packages that need it to discover it there upon first need.

If you still want to use the less secure .Renviron method, usethis::edit_r_environ() opens that file for editing.


Add a line like this, but substitute your PAT:


Make sure this file ends in a newline! Lack of a newline can lead to silent failure to load startup files, which can be tricky to debug. Take care that this file is not accidentally pushed to the cloud, e.g. Google Drive or GitHub.

Restart R for changes in .Renviron to take effect.

Continuous integration

On a headless system, such as on a CI/CD platform like GitHub Actions, you won’t be able to interactively store a PAT with gitcreds::gitcreds_set() or credentials::set_github_pat(). In the case of GitHub Actions, an access token is automatically available to the workflow and can be exposed to R as the GITHUB_PAT environment variable like so:

  GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}

If this automatic token doesn’t have sufficient permissions, you’ll need to create a suitable token and store it as a repository secret.

This is also the general approach for CI/CD platforms other than GitHub Actions:

  • Provide the PAT as a secure GITHUB_PAT environment variable.
  • Use regular environment variables to store less sensitive settings, such as the API host.

Take care not to expose your PAT by, e.g., printing environment variables to a log file.

How to learn more

gh and gitcreds

gert and credentials

  1. Password authentication is being deprecated at GitHub anyway, so you might as well face the music now.↩︎

  2. In fact, when you send a PAT as the password, the email or username doesn’t actually matter, but you might as well send your username.↩︎

  3. If you’re trying to follow the advice in this article and things don’t work the way we say they do, consider that you may need to update Git. Credential helpers are absolutely an area of Git that has improved rapidly in recent years and the gitcreds and credentials package work best with recent versions of Git.↩︎

  4. An even more dangerous practice is to hard-code a PAT in an R script, which is never a good idea.↩︎

  5. As always, the usethis.protocol option can be configured to customize your own default.↩︎

  6. If you have any doubt about your previous practices, open .Renviron, look for any line setting the GITHUB_PAT environment variable, and delete it. usethis::edit_r_environ() can be helpful for getting .Renviron open for editing. Don’t forget to restart R for this change to take effect.↩︎

  7. If you have any doubt about your previous practices, open .Renviron, look for any line setting the GITHUB_PAT environment variable, and delete it. usethis::edit_r_environ() can be helpful for getting .Renviron open for editing. Don’t forget to restart R for this change to take effect.↩︎