npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@solaqua/gji

v0.1.0

Published

Git worktree CLI for fast context switching.

Downloads

879

Readme

gji

Context switching without the mess.

gji is a Git worktree CLI for people who jump between tasks all day. It gives each branch or PR its own directory, so you stop doing stash, pop, reinstall cycles, and fragile branch juggling.

Why

Standard branch switching gets annoying when you are:

  • fixing one bug while reviewing another branch
  • hopping between feature work and PR checks
  • using multiple terminals, editors, or AI agents at the same time

gji keeps those contexts isolated in separate worktrees with deterministic paths.

Install

Current source install:

git clone https://github.com/sjquant/gji.git
cd gji
pnpm install
pnpm build
npm install -g .

Confirm the CLI is available:

gji --version
gji --help

Quick start

Inside a Git repository:

gji new feature/login-form
gji status

That creates a linked worktree at a deterministic path:

../worktrees/<repo>/<branch>

Shell setup

gji new, gji go, gji root, and gji remove/gji rm can only change your current directory when shell integration is installed. Without shell integration, the raw CLI prints the target path so it stays script-friendly.

For zsh:

echo 'eval "$(gji init zsh)"' >> ~/.zshrc
source ~/.zshrc

After that:

gji new feature/login-form
gji go feature/login-form
gji root
gji rm feature/login-form

changes your shell directory directly.

If you reinstall or upgrade gji, refresh the shell function:

eval "$(gji init zsh)"

For scripts or explicit piping:

gji new feature/login-form
gji go --print feature/login-form
gji root --print

gji new and gji remove print their destination paths in raw CLI mode, but in a shell-integrated session they change directory directly.

Daily workflow

Start a task:

gji new feature/refactor-auth

Start a detached scratch worktree:

gji new --detached

Check what is active:

gji status
gji ls

Pull a PR into its own worktree:

gji pr 123
gji pr #123
gji pr https://github.com/owner/repo/pull/123

Sync the current worktree with the latest default branch:

gji sync

Sync every worktree in the repository:

gji sync --all

Clean up stale linked worktrees interactively:

gji clean

Finish a single worktree explicitly:

gji remove feature/refactor-auth
# or
gji rm feature/refactor-auth

After removal, the shell-integrated command returns you to the repository root.

Commands

  • gji --version prints the installed CLI version
  • gji init [shell] prints shell integration for zsh, bash, or fish
  • gji new [branch] [--detached] creates a branch and linked worktree; with shell integration it moves into the new worktree, and --detached creates a detached worktree instead
  • gji pr <ref> accepts 123, #123, or a full PR/MR URL, extracts the numeric ID, then fetches origin/pull/<number>/head and creates a linked pr/<number> worktree
  • gji go [branch] [--print] jumps to an existing worktree when shell integration is installed, or prints the matching worktree path otherwise
  • gji root [--print] jumps to the main repository root when shell integration is installed, or prints it otherwise
  • gji status [--json] prints repository metadata, worktree health, and upstream divergence
  • gji sync [--all] fetches from the configured remote and rebases or fast-forwards worktrees onto the configured default branch
  • gji ls [--json] lists active worktrees in a table or JSON
  • gji clean interactively prunes one or more linked worktrees, including detached entries, while excluding the current worktree
  • gji remove [branch] and gji rm [branch] remove a linked worktree and delete its branch when present; with shell integration they return to the repository root
  • gji config reads or updates global defaults

Configuration

gji is usable without setup, but it supports defaults through:

  • global config at ~/.config/gji/config.json
  • repo-local config at .gji.json

Repo-local values override global defaults.

Supported keys:

  • branchPrefix
  • syncRemote
  • syncDefaultBranch
  • hooks

Example:

{
  "branchPrefix": "feature/",
  "syncRemote": "upstream",
  "syncDefaultBranch": "main"
}

Behavior:

  • if syncRemote is unset, gji sync defaults to origin
  • if syncDefaultBranch is unset, gji sync resolves the remote default branch from HEAD

Hooks

hooks runs shell commands at key points in the worktree lifecycle. Configure it in .gji.json or ~/.config/gji/config.json:

{
  "hooks": {
    "afterCreate": "pnpm install",
    "afterEnter": "echo switched to {{branch}}",
    "beforeRemove": "pnpm run cleanup"
  }
}

Hook keys:

  • afterCreate — runs after a new worktree is created, whether via gji new or gji pr
  • afterEnter — runs after switching to a worktree via gji go
  • beforeRemove — runs before a worktree is removed via gji remove

Each hook receives context in two ways:

Template variables (substituted into the command string):

| Variable | Value | |---|---| | {{branch}} | branch name, or empty string for detached worktrees | | {{path}} | absolute path to the worktree | | {{repo}} | repository directory name |

Environment variables (available to the hook process):

| Variable | Value | |---|---| | GJI_BRANCH | branch name, or empty string for detached worktrees | | GJI_PATH | absolute path to the worktree | | GJI_REPO | repository directory name |

Hooks run inside the worktree directory. A non-zero exit emits a warning but does not abort the command.

Global and project-level hooks are merged per key — project values override global values for the same key, while keys only present in the global config still apply:

// ~/.config/gji/config.json
{ "hooks": { "afterCreate": "nvm use", "afterEnter": "echo hi" } }

// .gji.json
{ "hooks": { "afterCreate": "pnpm install" } }

// effective hooks
{ "afterCreate": "pnpm install", "afterEnter": "echo hi" }

JSON output

gji ls --json returns branch/path entries:

gji ls --json

gji status --json returns a top-level object with:

  • repoRoot
  • currentRoot
  • worktrees

Each worktree entry contains:

  • branch: branch name or null for detached worktrees
  • current
  • path
  • status: clean or dirty
  • upstream: one of
    • { "kind": "detached" }
    • { "kind": "no-upstream" }
    • { "kind": "tracked", "ahead": number, "behind": number }

Notes

  • gji works from either the main repository root or any linked worktree
  • the current worktree is never offered as a gji clean removal candidate
  • gji pr accepts GitHub, GitLab, and Bitbucket-style PR/MR links, but still fetches from origin using GitHub-style refs/pull/<number>/head

License

MIT