Auto-switching GitHub CLI Accounts per Directory

2026-06-19 hit count image

Tired of running gh auth switch every time you move between personal and work projects? Learn how to combine the GH_TOKEN environment variable with zsh's chpwd hook to automatically switch GitHub CLI accounts when you enter a directory.

environment

Introduction

If you work on both personal and work projects, you’ve probably run into the situation where you need to switch your GitHub CLI (gh) account depending on which project you’re in. An issue gets filed under the wrong account, or a PR is opened as the wrong user.

gh auth switch solves this, but remembering to run it every time you change directories gets old fast.

This post shows how to combine the GH_TOKEN environment variable with zsh’s chpwd hook so that your GitHub CLI account switches automatically the moment you enter a directory.

The Problem with gh auth switch

gh lets you switch the active account with:

gh auth switch --user <account-name>

The problem is that this changes global state. Switch accounts in terminal tab A and it affects tab B as well. When you have multiple projects open at once, it’s easy to lose track of which account is currently active.

Using the GH_TOKEN Environment Variable

When GH_TOKEN is set, gh uses that token instead of whichever account is stored in its config.

export GH_TOKEN=ghp_xxxxxxxxxxxx
gh pr list  # runs as the GH_TOKEN account

Environment variables are isolated per shell session. Terminal tab A and tab B can each hold a different GH_TOKEN, so there’s no global state conflict like with gh auth switch.

If you’re already logged in to an account with gh, you can retrieve its token without creating a new one:

gh auth token --user <personal-account>
gh auth token --user <work-account>

Auto-switching with the chpwd Hook

zsh’s chpwd hook runs a function every time the working directory changes. Register one with add-zsh-hook chpwd and it fires automatically on every cd.

Put the GH_TOKEN switching logic there and your account changes as soon as you enter a directory.

Full Configuration

Add the following to ~/.zshrc:

# GitHub CLI — auto-switch GH_TOKEN by directory
#   ~/personal/* → personal account
#   everywhere else → work account
_GH_TOKEN_PERSONAL=$(gh auth token --user <personal-account> 2>/dev/null)
_GH_TOKEN_WORK=$(gh auth token --user <work-account> 2>/dev/null)

_gh_pick_account() {
  case "$PWD/" in
    "$HOME/personal/"*)
      export GH_TOKEN="$_GH_TOKEN_PERSONAL" ;;
    *)
      export GH_TOKEN="$_GH_TOKEN_WORK" ;;
  esac
}
add-zsh-hook chpwd _gh_pick_account
_gh_pick_account

gh() {
  local label
  case "$PWD/" in
    "$HOME/personal/"*) label="personal" ;;
    *)                  label="work" ;;
  esac
  print -P "%F{cyan}▶ GitHub account: %B${label}%b%f"
  command gh "$@"
}

Apply it:

source ~/.zshrc

How It Works

1. Token caching at shell startup

_GH_TOKEN_PERSONAL=$(gh auth token --user <personal-account> 2>/dev/null)
_GH_TOKEN_WORK=$(gh auth token --user <work-account> 2>/dev/null)

gh auth token adds a small delay on each call. Caching the tokens in variables at startup means directory changes are instant — no extra latency.

2. chpwd hook swaps GH_TOKEN

_gh_pick_account() {
  case "$PWD/" in
    "$HOME/personal/"*)
      export GH_TOKEN="$_GH_TOKEN_PERSONAL" ;;
    *)
      export GH_TOKEN="$_GH_TOKEN_WORK" ;;
  esac
}
add-zsh-hook chpwd _gh_pick_account
_gh_pick_account  # also apply to the current directory on shell startup

Directories under $HOME/personal/ get the personal token; everything else gets the work token. The bare _gh_pick_account call at the end ensures the correct token is set as soon as a new terminal opens.

Showing the Active Account with a gh Wrapper

When accounts switch automatically it’s easy to forget which one is active. Wrapping the gh command to print the current account before every invocation prevents mistakes.

gh() {
  local label
  case "$PWD/" in
    "$HOME/personal/"*) label="personal" ;;
    *)                  label="work" ;;
  esac
  print -P "%F{cyan}▶ GitHub account: %B${label}%b%f"
  command gh "$@"
}

Every gh call now shows:

▶ GitHub account: personal

Summary

ApproachPer-session isolationAuto-switchExtra tool
gh auth switchX (global state)XX
direnv + GH_TOKENOORequired
chpwd + GH_TOKENOOX

The chpwd + GH_TOKEN combination needs no extra tools and switches accounts automatically just by changing directories. The same pattern works for any other CLI tool that supports token-based authentication via an environment variable.

Was my blog helpful? Please leave a comment at the bottom. it will be a great help to me!

App promotion

You can use the applications that are created by this blog writer Deku.
Deku created the applications with Flutter.

If you have interested, please try to download them for free.



SHARE
Twitter Facebook RSS