
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 `curl` line
- Just add one `eval` line in `.zshrc` to start using it
- βοΈ 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
```zsh
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`:
```zsh
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.
```toml
[[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:
```toml
[[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:
```shell
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`:
```toml
[[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:
```bash
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:
```toml
[[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:
- `file` selects the plugin file inside the repository.
- `name` defines 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.
```toml
# 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:
```zsh
rz list
```
Example output:
```zsh
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
```zsh
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).
```zsh
# 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`.
```zsh
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
```zsh
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:
```zsh
rz upgrade
```
Update plugins:
```zsh
rz sync
```
## Uninstall
```zsh
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:
```zsh
# .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-start` manually.
- Especially effective when `zsh-autosuggestions` is loaded last (rat-zsh ensures this automatically).
## License
MIT License. See [LICENSE](./LICENSE) for details.