Why I am not switching to ZSH
Tags: fish, shell, bash, zsh
Published: 2019-07-11 17:22:11

---
title: Why I am not switching to ZSH
published: true
description: Or, why I'm switching from Bash to Fish
tags: fish, shell, bash, zsh
---

Recently Apple made a surprising announcement: due to licensing issues with Bash, they decided to [change the default shell on macOS from Bash to ZSH](https://support.apple.com/en-us/HT208050).  This change affects macOS Catalina and later.  It is no secret that many developers enjoy a UNIX-like development experience from the comfort of a Mac, and it is thus no surprise that in the wake of Apple's announcement, my Twitter feed began to fill up with a lot of [ZSH buzz](https://twitter.com/search?q=%23zsh&src=typd).

A lot of people are jumping ship to ZSH.

Now, ZSH is certainly not new in the UNIX-shell space.  I have been hearing about this shell for some years now, and why I should be switching to it.  Heck, I even gave it a try in 2017.  I spent ample time customizing it, and enjoying its superior interactivity, customizability, and completion experience.  Ultimately, however, I switched back to Bash.  Why, you may ask, did I downgrade from ZSH to Bash?  There were numerous factors, but overall the big reason was that the extra wins that I gained in using ZSH over Bash were dwarfed by the fact that I was remoting into boxes at the time that had their default shells locked to Bash.  Given that most of the boxes I was using already had Bash, and Bash could be customized nearly to the same level of ZSH using [Bash-it](https://github.com/Bash-it/bash-it), I decided to unify my experience and converge back to one shell everywhere: Bash.

**So what is the problem, exactly?** Don't get me wrong: I love ZSH, but in this case I just wanted to consolidate my efforts to customizing one shell.  In the end, I had almost all of the things I originally had with ZSH, but this time _everywhere_ with Bash-it.  Score? 90% win.  I'll take it!

## Weighing The "Cost of Adoption"

You see, for most of us, we will continue to use Bash everyday, as long as we are on machines that have us locked to Bash shells.  It is therefore safe to assume -- at least in my case -- that Bash is not leaving my life anytime soon.  Therefore, it is worth me spending some amount of time customizing Bash to suite my needs.  We could even pretend that there is a semi-mathematical way to view this:

```
CostOfAdopting(X) = CostOfMaintainingStatusQuo + CostOfCustomizing(X)
```

Do you see what the constant in that equation is?  Yep: maintaining the status-quo.  And what is the status quo in my case?  Customizing Bash.

So, according to the above equation, for me to have incentive to adopt a new shell "X", it must have a low cost of customization.

Hmmm. I wonder what shell that sounds like.

## Enter Fish Shell

Some time ago, I took the Fish Shell for a test drive, and promptly gave up when I realized it was not POSIX compliant.  For many this is a big deal, especially in one case: sourcing other script files.  While my daily workflow often still relies on being able to source a few script files, I have recently brought the Fish Shell back into my evaluation process.  I am excited to report that I am now using the Fish Shell as my daily (personal) shell!

I have lead right into the "why", but I will state it anyway: Fish Shell has an extremely low cost of adoption in my case.  [Zero Config](https://twitter.com/hashtag/zeroconfig?src=hash), is all the rage right now, and for good reason: in this age of ephemeral everything, it needs to be easy to go from 0-60 _fast_.  Fish Shell is no exception!  In its default state, it provides _so many_ sane defaults:

* syntax highlighting
* a killer [completion story](https://fishshell.com/docs/current/commands.html#fish_update_completions)
* ~~aliases~~ -- who needs 'em when you have abbreviations [1]?
* a more sane and consistent language
* killer [documentation](https://fishshell.com/docs/current/index.html)
* seriously: [`funced`](https://fishshell.com/docs/current/commands.html#funced)/[`funcsave`](https://fishshell.com/docs/current/commands.html#funcsave)

Sure, I cannot have Fish everywhere, but it is so easy to work with, that I am willing to commit to using it as my daily driver on my development machines.  Soon I hope to write more regarding my development setup, and the customizations I have been able to (easily) make to Fish.

In the meantime, during limited exposure to Fish, the following are my favorite addons:

* [jorgebucaran/fisher](https://github.com/jorgebucaran/fisher)
* [matchai/spacefish](https://github.com/matchai/spacefish)
* [jethrokuan/fzf](https://github.com/jethrokuan/fzf)
* [jorgebucaran/fish-bax](https://github.com/jorgebucaran/fish-bax)

[1] Fish abbreviations are similar in function to other shells' aliases, but they expand in place on the shell-edit-line, so you can see exactly what they are expanding to.  In my humble opinion, this is great because it removes the "magic" of aliases: especially if another developer is looking over your shoulder: no longer do you need to explain that `gc` is short for `git commit`.