Hi, I’m Erika Rowland (a.k.a. erikareads). Hi, I’m Erika. I’m an Ops-shaped Software Engineer, Toolmaker, and Resilience Engineering fan. I like Elixir, Reading, and Design. She/Her. If you're looking for experienced talent, I would love to chat. Published on

zsh Completion

Today I continued my exploration of shell completion with zsh completion. And it’s a lot simpler than bash completion.

Enabling zsh Completion

I learned that you can enable zsh completion to autostart by adding these two lines to your .zshrc:

autoload -Uz compinit

Both were added by the zsh configuration wizard when I opened the shell for the first time. The first line loads compinit so that it’s available to zsh. The second line calls compinit to enable completions.

Custom completion

A minimal example of zsh completion looks like this:

#compdef my_echo

  completions=("hello" "hear" "today")
  _describe "completions" completions

That’s it.

In order to enable this completion, I needed to name the file _my_echo, and add it to my zsh fpath in my .zshrc:

fpath=(~/.zsh/functions $fpath)
autoload -Uz compinit

Let’s break down the minimal example:


When compinit runs, zsh will look at the first line of each file it finds on the fpath. #compdef is a tag that defines the function to be called for name, in our case my_echo. Since the filename matches the function name, it loads _my_echo.


_describe is a utility function provided by zsh that takes a tag, in this case "completions", and an array of completions and loads them.

Unlike bash, there’s no further work needed. zsh has all the information it needs, and dutifully provides tab completion for my_echo.

The simplicity of zsh after bash is refreshing.