# radleylewis/zsh cannot configure zsh from inside zsh, so it patches the system startup file

> radleylewis/zsh is a small shell configuration split into five sourced files, with four plugins cloned on first launch and a prompt delegated to Starship. The interesting part is the bootstrap: because zsh only reads .zshenv from a directory it already knows about, the setup has to modify the system-wide startup file, and that step is not undone by uninstalling.

**radleylewis/zsh** — Powerful but tastefully minimal zsh configurations.

- Repository: https://github.com/radleylewis/zsh
- Stars: 418 · Forks: 89
- Language: Shell
- License: MIT
- Published: 2026-09-20 · Updated: 2026-09-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/radleylewis-zsh

## The config has to be told where it is, by a file outside itself

The whole repository is cloned straight into the configuration directory, which is the standard location:

```sh
git clone https://github.com/radleylewis/zsh ~/.config/zsh
```

That leaves a problem the file solves head-on. zsh reads its environment file from a directory it has to already know about, so a configuration placed in a new directory cannot tell zsh to look there. Something outside the configuration has to say it, and the place chosen is the system-wide environment file, which is the one zsh reads before anything else. What gets added is short:

```sh
if [[ -z "$XDG_CONFIG_HOME" ]]
then
    export XDG_CONFIG_HOME="$HOME/.config"
fi

if [[ -d "$XDG_CONFIG_HOME/zsh" ]]
then
    export ZDOTDIR="$XDG_CONFIG_HOME/zsh"
fi
```

Two details in those two blocks are deliberate. The first sets the standard configuration variable only when it is empty, so an existing setting wins. The second checks that the directory exists before pointing zsh at it, so a failed clone leaves your shell working instead of pointing it at nothing.

The cost is that this is a system file outside your home directory, it needs administrative rights to change, and nothing in the visible file describes how to put it back. The same setup section then makes zsh your login shell with a single command, and the last step tells you to create two directories the configuration assumes but does not make: one under the local state path for history, one under the cache path for completions.

## Five sourced files, and the file names are the whole architecture

There is no framework here. No oh-my-zsh, no plugin framework, no theme system, and no template language. The repository is a licence, a readme, a gitignore, two files zsh reads by convention, and five fragments whose names describe what each one does.

The two conventional files are the environment file and the resource file, which is the standard zsh pair. The five fragments are a file for aliases, a file for keybindings, a file for the fuzzy finder integration, a file for plugin management, and a file for the prompt. The one non-shell file is the prompt configuration, and the setup section says it is loaded automatically through an environment variable set in the environment file rather than sourced as code.

The consequence of that split is worth stating plainly, because it is the argument for the layout as much as the layout itself. A keybinding lives in one file, the fuzzy finder wiring lives in another, and the plugin list lives in a third, so a change to one does not risk breaking another, and turning a feature off means removing a line that sources a file rather than editing a large generated block. Whether the files are small enough to read end to end is not stated in the visible text, but the naming discipline is the part you can see.

What the prompt file itself contains is not described. The file says the Starship configuration is loaded through an environment variable; it does not say what the prompt fragment does, and that is the one gap in an otherwise complete map of the configuration.

## Plugins are cloned into the config directory on your first shell

Plugin management is described in one sentence: it is managed without a third-party plugin manager, and plugins are cloned into a plugins subdirectory of the configuration directory on first launch. The setup section repeats it from the other direction, saying plugins install automatically on first launch via the built-in manager.

Four plugins are listed, each with one job. A syntax highlighting plugin handles highlighting. An autosuggestions plugin provides fish-style inline suggestions. A history substring search plugin handles filtering the up and down arrows by what you have already typed. A vi-mode plugin provides vi keybindings. Updating all of them is a single command:

```sh
zplugin-update
```

Three things follow from this design. First, there is a network dependency at a moment you do not control, because the first shell you launch after setup is when the clones happen, and a first launch on a machine that cannot reach the plugin hosts gives you a shell with no highlighting and no suggestions and no error explaining why. Second, the clones land inside a directory that is itself a git clone, so two different things are writing into the same working tree. Third, the cost of the no-manager claim is real: you have four repositories on disk and one command to update them, rather than a declarative manifest that could also remove a plugin.

Against that, the list is short and the purposes do not overlap, which is the whole point of the layout. Four plugins with four distinct jobs is a configuration you can hold in your head, which is what the repository's own description claims for it.

## Ubuntu is the only platform that needs symlinks for the same keys to work

Three platforms, three install lines, and one of them is doing considerably more work than the other two. Arch installs nine packages in a single command through its helper, and macOS does the same through Homebrew. Ubuntu's package line covers seven of the nine:

```sh
sudo apt install zsh neovim eza bat fd-find fzf ripgrep
```

The two missing tools are zoxide and starship, and the file installs each by piping a remote script into a shell, from each project's own site. Then comes the part that is easy to skip. That distribution ships the file viewer and the file finder under different names, and the configuration looks for the short names, so the setup creates two symlinks into a local binary directory to bridge the gap.

That is a real difference in what the same keybindings do. Two of the three documented file-related shortcuts drive the fuzzy finder, and the fuzzy finder is driven by the file finder, so on Ubuntu those keys do nothing useful until the symlinks exist. The file's own comment says as much: it names the renamed packages as the reason.

The trust profile differs too, and not only in the symlinks. On Arch and macOS all nine tools arrive through a package manager with versioned packages. On Ubuntu, two of them arrive by executing a script fetched at that moment. Neither is wrong, but they are not the same installation, and the shorter command line is not doing less work.

## Nine dependencies for a prompt, four shortcuts, and a search key

The keybinding table is short enough to read as a description of the whole setup. A control and R combination opens a fuzzy search over history. A control and T combination opens a fuzzy file search that includes hidden files. A control and F combination opens the same search excluding hidden files. The control and arrow combinations move a word forward and backward. The up and down arrows search history by prefix. And a control and backslash toggles the inline suggestions on and off.

Three of those are worth reading twice. The T and F pair is the same tool twice with one difference, hidden files or not, which is a deliberate split rather than an accident. The arrow keys are taken over by prefix search, so the usual behaviour of recalling the previous command is replaced rather than added to. And the backslash combination is the only binding that changes a plugin's state instead of running a command, which is what makes it a toggle.

Against that, the dependency list is a starting kit rather than a requirement list. An editor and a replacement for the directory listing command appear in all three install lines, and nothing in the visible keybinding table, plugin list, or setup steps uses either. The prompt needs a patched font in the terminal, and that is the one visual dependency stated outright rather than implied by a package name.

So the honest count is that four shortcuts, a history search, a suggestion line, and a prompt are what you actually get, and the rest of the install line is there because the author uses them.

## There is no uninstall step, and no release to pin

A few gaps in the visible file are worth naming because they are the kind a person discovers at the wrong moment.

The first is the missing inverse of setup. The instructions explain how to add a block to the system-wide environment file, make zsh the login shell, create two directories, and clone a repository, and then stop. There is no section on removing any of it, and the one step that touches a file outside your home directory is the one you would most want written down. Changing your login shell back is a single command that anyone can guess; editing a system file is not.

The second is the first-launch dependency. Plugins are cloned when the shell starts, so the setup is not complete until a shell has run once with network access, and the file does not call that out as a step of its own.

The third is the prompt. There are two files involved, one shell fragment and one configuration file for the prompt program, and only the second is described. What the fragment does, and whether it is a fallback for when the prompt program is missing, is not stated.

The fourth is versioning. There are no releases, so the configuration is whatever the default branch contains today, and the readme is the only documentation. Given that the whole thing is five small files, that is a reasonable trade, and it is also why reading the files rather than trusting a snapshot is the more reliable way to know what you have.

## Conclusion

radleylewis/zsh is a good fit for someone setting up a fresh machine from a written list who wants a working prompt, fuzzy search, and history search without a framework imposing its own keybindings or theme, because the whole configuration is five readable files and four cloned plugins you can delete. It is a poor fit if you already have a zsh setup, if your distribution ships the file utilities under different names and you would rather not create symlinks, or if you do not want to edit a system file. Before you start, check three things yourself: that you are prepared to modify the system-wide startup file and to undo it yourself, since the visible file gives no uninstall step; that your first shell launch has network access, because the plugins are cloned at that moment and a first launch without it leaves you without highlighting; and that your terminal has a patched font, since the prompt configuration requires one and every glyph in it depends on that.

## FAQ

### How do I install the radleylewis zsh configuration?

Clone the repository into your configuration directory, then add a short block to the system-wide zsh environment file that sets the standard configuration variable if it is empty and points zsh at the config directory if it exists. Then set zsh as your login shell, create the state and cache directories the config expects, and start a new shell, which is when the plugins get cloned.

### Does the radleylewis zsh config need a plugin manager?

No. Plugin management is described as built in rather than third-party, and the four plugins are cloned into a plugins subdirectory of the config directory on first launch. They are syntax highlighting, inline autosuggestions, history substring search, and vi-mode keybindings, and all four update with a single command.

### Why is there extra setup on Ubuntu for the radleylewis zsh config?

Two of the nine tools are not in the Ubuntu package line and are installed by piping a remote script into a shell instead. That distribution also ships the file viewer and file finder under different names than the config expects, so the setup creates two symlinks into a local binary directory, without which the two fuzzy file-search keybindings do not work.

## Sources

- [Issues](https://github.com/radleylewis/zsh/issues)
- [License: MIT](https://github.com/radleylewis/zsh/blob/main/LICENSE)
- [radleylewis/zsh on GitHub](https://github.com/radleylewis/zsh)
- [README](https://github.com/radleylewis/zsh/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/radleylewis-zsh
