yawn - Yet Another Worktree Navigator
A fast project switcher and worktree manager for git. Fuzzy-find any project on your machine and open it: terminal, IDE, whatever you want. Also makes git worktrees painless.

Features
- Fuzzy-find and open projects with any finder (fzf, rofi, dmenu...)
- Create worktrees with automatic branch resolution and one-step setup
- Auto-initialize worktrees: copy
.env, runnpm install, etc. - Discover all git repos recursively, displayed as a tree with worktrees grouped under their parent
- Bind to a WM hotkey, works great with i3/sway/hyprland
- JSON/porcelain output for scripting
Quick start
Project picker
yawn pick discovers projects, pipes them into a fuzzy finder, resolves the selection, and opens it. One command.
Bind it to a hotkey in your window manager:
# sway / i3
You can also set a default finder in your config and just run yawn pick.
Under the hood, yawn pick is equivalent to:
Name resolution
yawn resolve maps a pretty display name back to an absolute path. yawn prettify does the inverse — maps an absolute path to its pretty name:
Worktree management
# The manual way:
# With yawn:
Worktrees are created under a configurable root directory (default: ~/worktrees) using the convention <project>--<name>.
Branch resolution: checks out existing local branches, tracks remote branches, or creates a new branch from --source or the default branch.
Per-project setup with .yawn.toml
Place a .yawn.toml at the repo root to configure what happens during yawn init or yawn create --init:
[]
= [".env", ".env.local", "config/*.toml"]
= ["npm install", "cargo build"]
include: files, directories, or glob patterns to copy from the main repo into worktrees. Directories are copied recursively.commands: shell commands to run sequentially in the target directory. Stops on first failure.
Project discovery
yawn list recursively finds git projects. In a terminal, they're shown as a colored tree:
my-app
├─ fix-branch
└─ feature-x
dotfiles
notes (personal)
notes (work)
When piped, output falls back to flat names compatible with fzf and other tools. Use --raw for absolute paths or --json for structured output.
Configuration
Global config lives at ~/.config/yawn/config.toml. All fields are optional.
[]
= 3
= [".*", "node_modules", "target", "vendor"]
[]
= "code {dir}"
= "fzf"
[]
= "~/worktrees"
= false
discovery.max_depth: recursion depth when searching for projects (default:5)discovery.ignore: directory name patterns to skip (default:[".*", "node_modules"])session.opener: command template to open a project.{dir}and{name}are shell-quoted automatically. Examples:code {dir},kitty --directory {dir}. Falls back to$TERMINAL, thenTerminal.app(macOS) orxterm(Linux).session.finder: default finder foryawn pick(overridden by-F)worktree.root: where worktrees are created (default:~/worktrees)worktree.auto_init: always run init after creating a worktree (default:false)
Install
From source
GitHub Releases
Download a binary from the releases page, or use the shell installer:
|
Nix flake
inputs.yawn.url = "github:ComeBertrand/yawn";
# then in your packages:
inputs.yawn.packages.${system}.default
Shell completion & man page
Shell completions are included:
# Bash
# Zsh (or place it anywhere in your $fpath)
# Fish
A man page is generated at build time:
License
MIT