Open-source project
mfaerevaag/wd avatar
mfaerevaag/wd

wd, the zsh plugin that replaces cd with named warp points

:rocket: Jump to custom directories in zsh

739 stars49 forksShellMIT

At a glance

What is it?
wd is a small zsh plugin that lets you give a directory a short name and jump to it later, so long paths and frequently visited folders stop costing you keystrokes. It is a good fit for zsh users who already live in oh-my-zsh, antigen, antibody or zplug, and a poor fit for anyone who needs the same behaviour in bash.
Who is it for?
Adopt wd if your work is zsh based and you keep coming back to a handful of deep directories, and check first that the warp point names you plan to use contain no colons. Do not adopt it if you need cross shell support or a plugin free setup, because every install path in the documentation is a zsh plugin manager entry and the project ships only a zsh implementation.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 125 days ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Why a warp point beats typing a path

The problem wd solves is narrow and real: a directory you visit often, with a path long enough that typing it costs you attention. The README puts it as cd seeming inefficient when the folder is frequently visited or has a long path. wd, which stands for warp directory, lets you name such a folder once and then move to it from anywhere.

It is a shell plugin written in Shell, distributed under the MIT licence, with topics of productivity, shell and zsh. The whole thing is a handful of files at the repository root: wd.sh, the plugin entry point, wd.plugin.zsh for plugin managers, a leading underscore file for zsh completion, wd.1 as the manpage, install.sh and a test directory.

The mechanism is deliberately conventional. wd registers itself as a zsh function, so calling wd foo is really a function call rather than an external binary on the path, and the warp points themselves are stored as plain text in a config file. That is the kind of implementation a shell user can read, change or replace, and it also explains the limits you will hit later.

Six ways to install, and which one you should pick

The README lists install routes for six plugin managers, and the shortest one is for anyone already running oh-my-zsh, because wd ships with it. Add the plugin to your .zshrc:

zsh
plugins=(... wd)

Antigen and Antibody each need a single bundle line in the same file:

zsh
antigen bundle mfaerevaag/wd
zsh
antibody bundle mfaerevaag/wd

On Arch the AUR package is called zsh-plugin-wd-git, and the README shows an AUR helper doing the work:

zsh
yay -S zsh-plugin-wd-git
# or use any other AUR helper

After the package is installed you still need the function in your .zshrc, because the package places the script at a fixed path:

zsh
wd() {
    . /usr/share/wd/wd.sh
}

Nix users add the plugin through Home Manager instead, naming the file and the completion directory explicitly:

nix
programs.zsh.plugins = [
  {
    name = "wd";
    src = pkgs.zsh-wd;
    file = "share/wd/wd.plugin.zsh";
    completions = [ "share/zsh/site-functions" ];
  }
];

The Home Manager route is the one that gets completion for free, because completions are declared. zplug users can load it as a command:

zsh
zplug "mfaerevaag/wd", as:command, use:"wd.sh", hook-load:"wd() { . $ZPLUG_REPOS/mfaerevaag/wd/wd.sh }"

The automatic installer runs remote code before you read it

Two one-line installers sit at the end of the setup section, one for curl and one for wget:

zsh
curl -L https://github.com/mfaerevaag/wd/raw/master/install.sh | sh
zsh
wget --no-check-certificate https://github.com/mfaerevaag/wd/raw/master/install.sh -O - | sh

The README itself flags both problems. It notes that automatic install does not provide the manpage, and it says plainly that running remote code without reviewing it first is poor security practice, pointing at install.sh for you to read.

That warning is worth taking seriously, and the wget form makes it worse by disabling certificate checking with --no-check-certificate. If you use either pipe, you are executing a script you have not read, over a transport that may not be authenticated. The manual route costs one clone and one shell function, and it leaves you in control of what runs:

zsh
git clone [email protected]:mfaerevaag/wd.git ~/.local/wd --depth 1
zsh
wd() {
    . ~/.local/wd/wd.sh
}

If you want the manpage too, the README documents moving it into place and refreshing the index:

zsh
sudo install -m 644 ~/.local/wd/wd.1 /usr/share/man/man1/wd.1
sudo mandb /usr/share/man/man1

That step has to be repeated whenever you pull a newer copy of the repository and the manpage changed, which is a small but real upkeep item that plugin managers avoid.

Warp point names cannot hold colons or be only spaces and dots

Adding a warp point is straightforward. To name the current directory foo:

zsh
wd add foo

To point at a directory elsewhere, wd offers two forms. wd addcd /foo/ bar adds the directory /foo/ under the name bar, and wd addcd /foo/ adds it under the current directory's own name. You can leave the name out entirely and wd uses the directory name for you.

Overwriting works with an explicit flag rather than a prompt, wd add foo --force.

The naming rules are where people trip. The README states that a warp point cannot contain colons, and cannot consist of only spaces and dots. The colon restriction has a storage reason, since colons conflict with how wd writes warp points into its config file. The spaces and dots rule conflicts with other features, and those other features are the dot syntax for navigation: wd .. warps back to the previous directory and wd ... goes one level higher, a wrapper around the zsh dirs function. That wrapper relies on the shell's directory stack, so the README notes you may need setopt AUTO_PUSHD in your .zshrc if you are not using oh-my-zsh.

The point of that syntax is that wd .. is not a warp point at all. It is zsh's own pushd behaviour, dressed in the same command.

Autocompletion and the fzf browse widget

Once a warp point exists, you jump to it with its name:

zsh
wd foo

You can also land inside a warp point rather than at its root, and completion fills in the rest of the path:

zsh
wd foo some/inner/path

Completion depends on how the plugin was installed. If you are not using oh-my-zsh, the README says you also need to add the path to your wd installation to fpath, and gives ~/bin/wd as the example location for the automatic installer:

zsh
fpath=(~/path/to/wd $fpath)

If the completions do not appear, the README suggests forcing a rebuild of the completion cache:

zsh
rm -f ~/.zcompdump; compinit

The second feature is search rather than completion. wd comes with an fzf powered browse mode that fuzzy searches every warp point you have, reachable as wd browse. To make it a keystroke away, the README suggests binding it in your .zshrc:

zsh
# ctrl-b to open the fzf browser
bindkey ${FZF_WD_BINDKEY:-'^B'} wd_browse_widget

The default binding is ctrl-b, and the environment variable lets you override it without editing the line again. The catch is that fzf has to be present, which the README assumes rather than installs.

Warp points live in a plain text file you can inspect and version

Every warp point ends up in a config file, ~/.warprc by default, and wd list shows what is in it:

zsh
wd list

Because it is a text file, you can look at it, edit it by hand, or keep it under version control. The WD_CONFIG environment variable overrides the location, which the README notes is useful for testing:

zsh
wd --config ./file <command>

A second global option, wd --quiet <command>, silences all output. wd help prints the usage information, and the same usage text appears if you call wd with no command at all. wd --version reports the running version.

The read-only commands are as useful as the write ones. wd path foo prints the path of a warp point, wd show lists warp points for the current directory and can also show the path to a given point, and wd ls foo lists the files inside a named point.

Cleanup has its own command, wd clean, which removes warp points whose directories no longer exist. It asks for confirmation, and wd clean --force skips the prompt. That last detail matters for scripts: a warp point pointing at a deleted directory is the normal outcome of moving your work around, and silently pruning them keeps the list short without the risk of a batch removal that takes a good point with it.

Testing it yourself and who is maintaining it

wd ships a small test suite built on shunit2, and the README suggests it as a way to confirm the plugin works on your setup before filing an issue. You run it from the test directory:

zsh
cd ./test
./tests.sh

For a shell plugin this is the closest thing to a safety net: you can confirm that add, list, removal and the dot syntax behave on your machine rather than trusting the README, which is quick because the suite is small.

On maintenance, the project is MIT licensed, which is permissive and lets you vendor the script if you want to keep it in a dotfiles repository yourself. The last push was on 2026-06-22, and the tagged releases are v0.9.3 on 2025-01-29, v0.10.0 on 2025-04-23 and v0.10.1 on 2025-06-23. The README also records a change in responsibility, stating that after the original author stepped away from active maintainership, two other users now maintain the repository.

The upgrade path is simple and unglamorous: pull the repository again and re-source wd.sh, then repeat the manpage install if that file changed. There is no plugin API to relearn and no migration step for existing warp points, since they live in your own config file rather than in a format the tool owns.

Editorial conclusion

Adopt wd if your work is zsh based and you keep coming back to a handful of deep directories, and check first that the warp point names you plan to use contain no colons. Do not adopt it if you need cross shell support or a plugin free setup, because every install path in the documentation is a zsh plugin manager entry and the project ships only a zsh implementation.

Frequently asked questions

How do I install wd in zsh?

If you use oh-my-zsh, add wd to the plugin list in your .zshrc. Antigen and Antibody users add a bundle line for mfaerevaag/wd, Arch users can install zsh-plugin-wd-git from the AUR, and Nix users declare it under programs.zsh.plugins in home.nix.

Where does wd store my warp points?

Warp points are stored in ~/.warprc by default, and you can change that path with the WD_CONFIG environment variable or per invocation with wd --config ./file.

Can I use wd with bash instead of zsh?

Every install path in the documentation targets zsh, through a zsh plugin manager or a zsh function that sources wd.sh. The README does not describe a bash integration, so bash users should expect to implement the loading themselves.

Why does the automatic wd installer warn about security?

The README states that it is poor security practice to run remote code without first reviewing it, and it also notes that automatic install does not provide the manpage. The wget variant additionally uses --no-check-certificate, which disables certificate verification.

How do I remove warp points that no longer exist?

Run wd clean, which removes warp points pointing at non-existent directories and asks for confirmation. Use wd clean --force to skip the prompt, for example in a script.

Official sources

  1. Issues
  2. License: MIT
  3. mfaerevaag/wd on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/mfaerevaag-wd.svg)](https://hysenlabs.com/projects/mfaerevaag-wd)

Was this useful?