Pin to a branch
January 8, 2026 Β· View on GitHub

Rat Zsh
A lightweight, fast, and reproducible plugin manager for zsh.
Made with π & π¦ β no magic, no heavy frameworks.
Features πβ¨
- π Simple setup
- Install with a single
curlline - Just add one
evalline in.zshrcto start using it
- Install with a single
- βοΈ Configurable and reproducible
- Simple TOML-based configuration
- Automatic plugin load order control
- π GitHub integration
- Fetches plugins from GitHub repositories
- Supports branches, tags, and commits
- Handles Git submodules automatically
- β‘οΈ Lightweight and fast
- Parallel plugin sync
- Built in Rust π¦
- π Seamless updates
- Self-upgrade
- Plugin sync
Installation
curl -fsSL https://raw.githubusercontent.com/gotokazuki/rat-zsh/main/install.zsh | zsh
This installs $(rz home)/bin/rz.
(Default install location is $XDG_CONFIG_HOME/.rz. If not set, it falls back to $HOME/.rz.)
Setting up .zshrc
Add the following line to your .zshrc:
eval "$("${XDG_CONFIG_HOME:-$HOME}"/.rz/bin/rz init)"
Configuration
Write your plugin configuration in $(rz home)/config.toml.
A sample file will be created on the first install.
[[plugins]]
source = "github"
repo = "zsh-users/zsh-autosuggestions"
type = "source"
file = "zsh-autosuggestions.zsh"
[[plugins]]
source = "github"
repo = "zsh-users/zsh-completions"
type = "fpath"
fpath_dirs = ["src"]
[[plugins]]
source = "github"
repo = "zsh-users/zsh-syntax-highlighting"
type = "source"
file = "zsh-syntax-highlighting.zsh"
[[plugins]]
source = "github"
repo = "zsh-users/zsh-history-substring-search"
type = "source"
file = "zsh-history-substring-search.zsh"
[[plugins]]
source = "github"
repo = "olets/zsh-abbr"
type = "source"
file = "zsh-abbr.zsh"
[[plugins]]
source = "github"
repo = "gotokazuki/rat-zsh"
type = "fpath"
fpath_dirs = ["contrib/completions/zsh"]
[[plugins]]
source = "github"
repo = "Aloxaf/fzf-tab"
type = "source"
file = "fzf-tab.plugin.zsh"
requires = ["fzf"]
Supported keys
| Key | Description |
|---|---|
| source | Plugin source (currently only github is supported) |
| repo | Repository in owner/repo format |
| rev | Optional. Pin to a tag or branch |
| file | Optional. Relative path to the file to source |
| type | "source" or "fpath" (default: "source") |
| name | Optional. Alias name for the plugin |
| fpath_dirs | Optional. List of directories (relative to the repo root) to include in $fpath when type = "fpath" |
| requires | Optional. List of commands required for this plugin to be synced and loaded |
Conditional plugin loading with requires
Some plugins should only load when tools like fzf or peco are available.
You can declare such requirements using the requires field:
[[plugins]]
source = "github"
repo = "Aloxaf/fzf-tab"
type = "source"
file = "fzf-tab.plugin.zsh"
requires = ["fzf"]
Behavior:
- If all commands listed in requires exist in
$PATH, Rat Zsh will sync and load the plugin normally. - If any required command is missing, the plugin will be skipped entirely:
- It is not cloned or updated
- No symlink is placed in $(rz home)/plugins/
- It will not be loaded by rz init
Example skip message:
skip plugin fzf-tab: missing required commands ["fzf"]
This allows conditional, environment-dependent plugin activation without modifying the config file.
Example: fpath_dirs usage
Some plugins (like zsh-completions or rat-zsh itself) include completion functions in nested directories.
You can explicitly define which directories should be added to Zshβs $fpath:
[[plugins]]
source = "github"
repo = "gotokazuki/rat-zsh"
type = "fpath"
fpath_dirs = ["contrib/completions/zsh"]
[[plugins]]
source = "github"
repo = "zsh-users/zsh-completions"
type = "fpath"
fpath_dirs = ["src"]
When you run rz list, these appear like:
fpath
- gotokazuki/rat-zsh (github) [fpath: contrib/completions/zsh] @main (4243bb3)
- zsh-users/zsh-completions (github) [fpath: src] @master (173a14c)
Multiple plugins from a single repository
Some repositories provide multiple plugins (e.g. ohmyzsh/ohmyzsh).
In such cases you must specify the file and a unique name so they donβt overwrite each other:
[[plugins]]
source = "github"
repo = "ohmyzsh/ohmyzsh"
type = "source"
file = "lib/clipboard.zsh"
name = "clipboard"
[[plugins]]
source = "github"
repo = "ohmyzsh/ohmyzsh"
type = "source"
file = "plugins/copypath/copypath.plugin.zsh"
name = "copypath"
In this example:
fileselects the plugin file inside the repository.namedefines how it will appear in$(rz home)/plugins/and in the log messages.
Pinning to a specific tag or branch
You can use rev to pin a plugin to a specific version (tag or branch).
This ensures reproducible environments and avoids unexpected updates.
# Pin to a tag
[[plugins]]
source = "github"
repo = "zsh-users/zsh-autosuggestions"
rev = "v0.7.0"
type = "source"
file = "zsh-autosuggestions.zsh"
# Pin to a branch
[[plugins]]
source = "github"
repo = "zsh-users/zsh-completions"
rev = "develop"
type = "fpath"
fpath_dirs = ["src"]
- If rev is not specified, the plugin is synced to the default branch (usually main or master).
- When rev is specified, Rat Zsh checks out that branch or tag after cloning or fetching.
- Tags are checked out in a detached state.
- Branches are checked out in an attached state and will track updates.
Plugin load order
By default, Rat Zsh loads plugins in the following order:
| Priority | Plugins |
|---|---|
| 1 | All other plugins (alphabetical) |
| 2 | zsh-users/zsh-autosuggestions |
| 3 | zsh-users/zsh-syntax-highlighting |
This order is enforced automatically β you donβt need to configure it manually.
To see the actual order on your system:
rz list
Example output:
Source order
- olets/zsh-abbr (github) [source] @main (13b34cd)
- zsh-users/zsh-history-substring-search (github) [source] @master (87ce96b)
- zsh-users/zsh-autosuggestions (github) [source] @master (85919cd)
- zsh-users/zsh-syntax-highlighting (github) [source] @master (5eb677b)
fpath
- gotokazuki/rat-zsh (github) [fpath: contrib/completions/zsh] @main (4243bb3)
- zsh-users/zsh-completions (github) [fpath: src] @master (173a14c)
Commands
rz init # Print initialization code for .zshrc
rz config # Open the configuration file
rz sync # Clone/update plugins defined in config.toml
rz upgrade # Update rat-zsh itself to the latest release
rz list # Show plugins in the effective load order with source/type metadata
rz home # Show the rz home directory
Editing configuration
You can open the configuration file using the rz config command.
It respects the EDITOR environment variable (defaults to vim if unset).
# Open with code, nano, etc.
EDITOR=code rz config
Checking plugin update status
You can check whether attached plugins have upstream updates by using the --check-update (-u) option with rz list.
rz list -u
When this option is specified, Rat Zsh will access Git repositories and display additional status indicators at the end of each plugin entry.
Status symbols
| Symbol | Meaning |
|---|---|
| βN | The upstream branch has N new commits (updates available) |
| βN | The local branch is N commits ahead of upstream |
| β/β | Upstream and local branches are in sync |
| * | The working tree has uncommitted changes |
| ? | Upstream status is unknown or could not be checked |
- These symbols are shown only for plugins attached to a branch.
- Plugins pinned to a specific commit or tag do not track upstream changes. In such cases, only * (dirty working tree) may be shown.
- Symbols are displayed in color when output is connected to a TTY.
Example output
Source order
- Aloxaf/fzf-tab (github) [source] @master (fac1451) β3/β
- zsh-users/zsh-autosuggestions (github) [source] @master (85919cd) β/β2 *
- zsh-users/zsh-syntax-highlighting (github) [source] @master (5eb677b) β/β
fpath
- gotokazuki/rat-zsh (github) [fpath: contrib/completions/zsh] @main (29e2a7b) β/β *
Update
Update Rat Zsh itself:
rz upgrade
Update plugins:
rz sync
Uninstall
rm -rf "$(rz home)"
Then remove the line eval "$("${XDG_CONFIG_HOME:-$HOME}/.rz/bin/rz" init)" from .zshrc.
Recommended configuration
Speeding up zsh-autosuggestions
By default, zsh-autosuggestions rebinds zle widgets before every prompt,
which may slow down input responsiveness in some environments.
Add the following environment variable before rz init in your .zshrc
to disable automatic rebinding and improve performance:
# .zshrc
export ZSH_AUTOSUGGEST_MANUAL_REBIND=1
eval "$("${XDG_CONFIG_HOME:-$HOME}/.rz/bin/rz" init)"
- Effect: Skips redundant processing at every prompt, resulting in a snappier shell.
- Note: If you add plugins or change key bindings later, you may need to run
zle autosuggest-startmanually. - Especially effective when
zsh-autosuggestionsis loaded last (rat-zsh ensures this automatically).
License
MIT License. See LICENSE for details.