twig
A tmux session manager with git worktree support, inspired by tmuxinator.
Built to scratch my own itch. Terminal UI built with Ratatui.
Requirements
tmuxgit
Installation
We recommend using mise to install.
Via mise
mise use -g cargo:https://github.com/andersonkrs/twig
This compiles twig from source and installs it globally.
From source (for development)
git clone https://github.com/andersonkrs/twig.git ~/Work/twig cd ~/Work/twig # Install all tools (rust, lefthook) + git hooks mise install # Build cargo build --release # Symlink to PATH ln -s ~/Work/twig/target/release/twig ~/.local/bin/twig
Usage
twig start [project] # Start/attach to session (interactive if no arg) twig list # List all projects/worktrees twig list --focus-current # Focus current TWIG_PROJECT/TWIG_WORKTREE twig new [name|repo_url] # Create new project (accepts name or git URL) twig edit [project] # Open config in $EDITOR twig delete [project] # Delete project config twig stop [project] # Kill tmux session # Worktree commands twig tree create [project] [branch] # Create worktree + session twig tree list [project] # List worktrees twig tree delete [project] [branch] # Delete worktree + kill session
When creating a project with a git URL, twig extracts the project name automatically:
twig new git@github.com:user/myproject.git # Creates project "myproject"Aliases: ls for list, s for start, n for new, e for edit, rm for delete, t for tree
Configuration
Global Config
Location: ~/.config/twig/config.yml
# Base path for worktrees (default: ~/Work/.trees) # Worktrees are created at: {worktree_base}/{project}/{branch} worktree_base: ~/Work/.trees # Projects directory (default: ~/.config/twig/projects) projects_dir: ~/.config/twig/projects
Project Config
Location: ~/.config/twig/projects/<name>.yml
name: myproject root: ~/Work/myproject # Optional: git repo URL (https or ssh) # If root doesn't exist, twig will clone this repo on first start repo: git@github.com:user/myproject.git windows: # Simple window with command - git: lazygit # Empty shell window - shell: # Window with multiple panes - editor: panes: - nvim # Window with layout and multiple panes - servers: layout: main-vertical # main-vertical, main-horizontal, even-vertical, even-horizontal, tiled panes: - rails server - bin/sidekiq # Optional: worktree configuration worktree: # Files/folders to copy from parent project to worktree copy: - .env - .env.local - config/master.key # Files/folders to symlink from parent project to worktree # Only supported on Unix symlink: - .env # Commands to run after worktree creation post_create: - bundle install - yarn install - rails db:migrate # Note: post_create runs inside a temporary setup window in the worktree session # so your shell init and environment (mise/rbenv/etc) are applied.
Example Configs
Rails project:
name: myapp root: ~/Work/myapp windows: - editor: panes: - nvim - shell: - rails: layout: main-vertical panes: - rails server - bin/sidekiq - console: rails console - git: lazygit worktree: copy: - .env - .env.local - config/master.key - config/credentials.yml.enc symlink: - .env post_create: - bundle install - yarn install - bin/rails db:prepare
Simple project:
name: dotfiles root: ~/.dotfiles windows: - editor: panes: - nvim - shell: - shell: - git: lazygit
How It Works
Sessions
When you run twig start <project>:
- Checks if session already exists → attaches if so
- Creates new tmux session with configured windows/panes
- Runs commands in each pane
- Attaches to the session (or switches if already in tmux)
Worktrees
When you run twig tree create <project> <branch>:
- Creates git worktree at
{worktree_base}/{project}/{branch} - Creates the branch if it doesn't exist
- Copies and symlinks configured files from parent project
- Runs post-create commands
- Starts a tmux session named
{project}__{branch}
Session naming: myproject__feature-auth (double underscore separator)
Worktree path: ~/Work/.trees/myproject/feature-auth
When you run twig tree delete <project> <branch>:
- Kills the tmux session if running
- Removes the git worktree
Tmux Popup Session Picker
You can replace the tmux session picker with a popup that calls twig ls --focus-current.
This uses the TWIG_PROJECT and TWIG_WORKTREE environment variables to focus the cursor
on the current project/worktree when available.
Add a key binding to your ~/.tmux.conf:
# Twig popup unbind s bind-key s display-popup -E -w 80% -h 60% "twig ls --focus-current"
If you want the popup to always open from anywhere (not just inside a twig session), it will still work but will fall back to the first project when the env vars are not set.
Development
# Install dependencies + git hooks mise install # Build cargo build --release
Formatting and linting are automatically run by lefthook on pre-commit.
License
MIT