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

git-wtree

v0.6.0

Published

Git worktree manager with .env syncing and IDE integration

Readme

git-wtree

Git worktree manager with .env syncing and IDE integration

Streamline your git worktree workflow: create isolated branches, sync environment files, install dependencies, give each worktree its own editor color, and open your IDE — all in one command.

Install

npm install -g git-wtree

Usage

gitwtree <command>
# or
gwt <command>

Shell integration (recommended)

Run this once — it enables gwt switch (jumping between worktrees) and, on zsh + oh-my-zsh, frees the gwt name from the git plugin's alias:

gitwtree shell-init --install

It detects your shell, writes a small block to your rc (~/.zshrc, ~/.bashrc, or ~/.config/fish/config.fish), and is idempotent — re-run it any time to update or repair the block. Then open a new terminal.

Why gitwtree and not gwt? oh-my-zsh's git plugin aliases gwt (and gwta, gwtls, …) to git worktree, which shadows this CLI. gitwtree is never aliased, so it always works; the block it installs clears those aliases and defines a gwt function that wins. If gwt runs git worktree, you haven't run the integration yet — run gitwtree shell-init --install, or use gitwtree directly.

Manual alternative. If you'd rather not let a command edit your rc, append the block yourself (put it after any PATH setup, e.g. nvm/fnm, so gitwtree resolves) and open a new terminal:

gitwtree shell-init zsh >> ~/.zshrc   # or: bash | fish

Both write a static block (no gitwtree call at shell startup), so it's robust regardless of where your PATH is configured. To remove it later: gitwtree shell-init --uninstall.

Commands

| Command | Description | | ----------------------------------- | ------------------------------------------------------------- | | gwt add <branch> [--from <base>] | Create a worktree, sync .env files, and run the setup hook | | gwt pr <number> | Create a worktree from a GitHub pull request | | gwt rm [branch] [--force] | Remove a worktree (picker if omitted; guards unsaved changes) | | gwt ls | List all worktrees | | gwt open [branch] | Open a worktree in your IDE (picker if omitted) | | gwt switch [query] | cd to another worktree (needs the shell integration) | | gwt shell-init [--install] | Install (or print) the shell integration; --uninstall too | | gwt doctor | Diagnose the install (integration present + version, git) | | gwt sync-env [query] [--apply] | Re-copy .env from main into a worktree (--all for every) | | gwt config | Show current configuration | | gwt config ide | Configure your IDE | | gwt config scan-dirs [dirs] | Set directories to scan for .env files | | gwt config setup [commands...] | Post-create commands (auto / none / custom) | | gwt config teardown [commands...] | Pre-remove commands run in the worktree (none to clear) | | gwt config theme [on\|off] | Toggle per-worktree VS Code color + window title | | gwt config statusline [on\|off] | Toggle the Claude Code branch statusline | | gwt help | Show help |

gwt add <branch>

Creates a git worktree for the given branch, copies .env files from the main repo, and runs the setup hook.

  • If the branch doesn't exist, it's created from HEAD by default — use --from to specify a different base.
  • If the branch already exists locally, it fetches the latest remote changes and resets to them (handles force-pushes cleanly).
gwt add my-feature                     # create from HEAD
gwt add my-feature --from production   # create from production
gwt add codex/fix-bug                  # checkout existing branch, reset to remote

gwt pr <number>

Creates a worktree from a GitHub pull request (then runs the same .env sync, setup hook, and theming as gwt add). The worktree lives at <repo>-pr-<number>.

gwt pr 1234   # specific PR
gwt pr        # no number → pick from open PRs (arrow-key picker, requires gh)
  • If gh is installed, it runs gh pr checkout inside the worktree — you get the PR's real branch with push tracking (works for forks too), so you can push fixes back.
  • Otherwise it falls back to git fetch origin pull/<number>/head into a local pr-<number> branch (review only).

gwt open [branch]

Opens a worktree in your configured IDE. On first use, a wizard will prompt you to choose your IDE.

gwt open my-feature   # substring match on branch or path
gwt open              # no argument → arrow-key picker

Worktrees are resolved from git worktree list (the same source as gwt ls): the argument is matched as a substring of the branch or path, and you get a picker when it's ambiguous or omitted. The same resolution powers gwt switch and gwt rm, so a PR worktree (dir repo-pr-<n>, different branch) is found whether you pass its branch, pr-<n>, or pick it.

To reconfigure your IDE at any time:

gwt config ide

gwt switch — jump between worktrees

gwt switch [query] changes your shell's directory to another worktree. Because a binary can't change its parent shell's working directory, this needs the shell function installed by Shell integration (gitwtree shell-init --install). Once that's in place:

gwt switch my-feature   # cd to the worktree whose branch matches "my-feature"
gwt switch              # no query → arrow-key picker
gwt sw my-feature       # alias

query is a substring match on the branch name. If it matches exactly one worktree you go straight there; if it's ambiguous or omitted, you get an arrow-key picker (same style as the rest of the prompts). (gwt path [query] is the underlying primitive the wrapper calls — it resolves the worktree and writes the path back to the wrapper.)

gwt doctor

Checks the install: git availability, the gitwtree version, and whether the shell-integration block is present in your rc (and whether its version matches — if not, it tells you to re-run gitwtree shell-init --install).

gwt doctor

One thing it can't check: a binary can't inspect the parent shell, so it can't tell whether gwt currently resolves to the function or to oh-my-zsh's alias. Run type gwt yourself — "function" is good; "alias" means the integration isn't active in this shell.

.env syncing

By default, gwt add recursively scans the repo for .env* files (excluding node_modules, .git, dist, etc.) and copies them into the new worktree.

To restrict scanning to specific directories:

gwt config scan-dirs apps/api,apps/web

To reset back to auto scan:

gwt config scan-dirs --reset

Re-syncing after the fact

gwt add only copies .env files at creation time. When you refresh them on your main checkout (e.g. after pulling a new database), gwt sync-env re-copies them into existing worktrees. The main worktree is always the source (detected automatically, so it works from any worktree); it's never a target.

It is a dry run by default — it lists, per worktree, which files would be copied and which would overwrite an existing one — and only writes with --apply:

gwt sync-env                  # pick a worktree, preview the changes
gwt sync-env my-feature       # preview for the worktree matching "my-feature"
gwt sync-env my-feature --apply   # actually copy into that worktree
gwt sync-env --all            # preview across every secondary worktree
gwt sync-env --all --apply    # copy into all of them

Setup & teardown hooks

gwt add runs a setup hook after creating the worktree, and gwt rm runs a teardown hook before removing it. Both run inside the worktree.

Setup defaults to auto: if a package.json is present it runs <package-manager> install (plus <pm> run prepare when that script exists); otherwise it does nothing — so non-Node repos stay untouched. Override it with your own commands for any stack:

gwt config setup                              # show current value
gwt config setup "bundle install"             # Ruby
gwt config setup "go mod download" "make dev" # multiple commands, in order
gwt config setup none                         # do nothing
gwt config setup auto                         # back to auto-detection

Teardown is empty by default. Use it to release resources tied to a worktree (databases, containers, ports) before it's deleted. If a teardown command fails, removal is aborted unless you pass --force:

gwt config teardown "docker compose down"
gwt config teardown none                      # clear

Removing worktrees

gwt rm <branch> refuses to remove a worktree that has uncommitted changes, untracked files, or unpushed commits — to avoid losing work. Re-run with --force to remove anyway:

gwt rm my-feature
gwt rm my-feature --force

Worktree theming

To make parallel windows easy to tell apart, gwt add gives each worktree its own visual identity:

  • A deterministic color (derived from the branch name) is applied to the VS Code / Cursor title bar and activity bar, plus a worktree-aware window.title. Written to the worktree's .vscode/settings.json and merged into any existing settings without dropping your keys or comments.
  • A branch statusline is written to .claude/settings.local.json so each Claude Code session shows its branch.

Both files are kept out of git status automatically — skip-worktree when the file is tracked, the worktree's local info/exclude otherwise. Your shared .gitignore is never touched.

Toggle either feature (both on by default):

gwt config theme off        # disable color + window title
gwt config statusline off   # disable the Claude statusline

Worktree location

Worktrees are created as siblings of your repo directory:

~/projects/
  myrepo/           ← main repo
  myrepo-my-feature ← worktree created by gwt

Supported IDEs

VS Code, Cursor, Zed, WebStorm, IntelliJ IDEA, PyCharm, GoLand, Vim, Neovim, Sublime Text — or any custom IDE via the "Other" option in the wizard.

Requirements

  • Node.js >= 18
  • Git >= 2.5
  • gitwtree on your PATH. npm install -g handles this normally. If you use a lazy-loaded nvm (or similar), make sure your global npm bin directory is exported on shell startup — otherwise gitwtree/gwt won't resolve in a new shell. git-wtree assumes it's runnable; it deliberately doesn't touch your PATH.

License

MIT