Why I am not switching to ZSH

jrop profile image Jonathan Apodaca ・4 min read

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. 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.

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, 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, 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:

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:

[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.

Posted on by:


Editor guide

Fish is a nice and decent shell.
But if I made the switch I had to unlearn && and have to give up niceties like !-3.
At that point, I was done with fish. It's not fish's fault, but I am too lazy 😎


Fish history recall is very simple yet effective:

As in any modern shell, the Up arrow, ↑ recalls whole lines, starting from the last line executed. A single press replaces "!!", later presses replace "!-3" and the like.
If the line you want is far back in the history, type any part of the line and then press Up one or more times. This will constrain the recall to lines that include this text, and you will get to the line you want much faster. This replaces "!vi", "!?bar.c" and the like.

Fish docs


Thank you for your kind advice and hint to the docs.

No problem! I should thank you because I didn't know about !-3 before reading your comment. I was just sharing my findings :D


The equivalent of && is ; and. However, for !-3, I never use that anyway, so I'm not sure what the equivalent is :D


; breaks if the call on the left ends with error?

Then it's simply "; or" instead of "; and" in fish.


Drink the Kool aid! Become one of us. Come over to the dark side. However you want to put it. Long time ZSH user here prob 10+ years. First thing I do on a system that doesn't have zsh, Install zsh, then pull my zshrc file from my server. One you switch, you will never go back. zsh's tab completion and case insensitivity for me makes it the ultimate shell out there, far more superior than bash will ever be. Altho I still write all my shell scrips in bash, I will forever be a zsh user.

Just my 2cents

  ___  ____            _           ____      _     _  
 |   |/   /           | |         /    \    (_)   | | 
 |   '   /  ___   ___ | |  ___   /   _  \    _  __| | 
 |      <  / _ \ / _ \| | |___| /   (_)  \  | |/ _` | 
 |   .   \| (_) | (_) | |      /   ____   \ | | (_) | 
 |___|\___\\___/ \___/|_|     /___/    \___\|_|\__,_| 
     _______________          ____________            
    ( _____________ ) ___    (            )           
    /    _     _    \/ _ \   (  OH YEAH!  )           
   /    (,)   (,)    \/ \ \ /_____________)           
  |         _         | | |               _______     
  |        (_)        | | |   _______    (  . .  )_   
  |     .       .     |/ /   (  . .  )_  |   o   |_)  
   \     '.....'     /__/    |   o   |_)  ) '-' (     
    \               /         ) '-' (    (_______)    
     )_____________(         (_______)                

If tab completion and case insensitivity are your strong points to defend zsh, don't ever dare to try fish shell.

Now in all seriousness, In my opinion, it doesn't matter which one, the important thing is to use whatever makes you comfortable in the command line. I like the 3 of them, all have strong points and weaknesses.


Back when I tried ZSH, I was having trouble with completions: they would randomly stop working. I finally gave up spending the effort hunting the problem down each time. Perhaps it is better now, who knows!

Also, as mentioned above: I regard Bash as only offering slightly less than ZSH, and Bash usually comes by default on the systems I have to remote into. The cost of adopting ZSH is usually too high for me in my case.


I didn't learn bash well until I switched to fish. I think it's because I could finally do complex things in the shell, and then to share them, I had to figure out how to translate them back into bash.

Best fish feature, imo, is it's multiline support. I often compose scripts right in the shell.

I use programs over aliases, though (eg I would have a program gc) because these can be invoked from either shell, and even from non-shell processes.


Fish is a much more sane scripting language than bash, or any POSIX shell, for that matter.


And I love orange pencils with slightly soft tip.

Seriously, you prefer using Bash over ZSH, we understand, but why devoting such a long post telling us about? What's next? Color theme of VSCode?


Because this is what he felt like writing about and it's his blog post?



I respect his post in his blog, I just don't agree each of us start writing about his personal preferences in long posts, holding no useful information. You love bash? Great, use it, master it, share tips and tricks with us, not why you like it more than ZSH. I spent my time reading this post and at the end just understood my time was wasted on another "I prefer " writing.

Blog posts are a personal writing. That's literally the point of them. Some people use them for education, to deliver value in some way. Others talk about what interests them. All applicable uses of the platform.

You're just being grumpy and unreasonable.


I have only switched to zsh a couple of months ago and love it, because of zsh I actually spend more time in my terminal in stead of using GUI applications for everything.

I was wondering what OS has bash locked in?


Pretty sure "locked in" is referring to being unable to install. Example being a set of production servers. You can't just install ZSH on every server you connect to.


Underrated comment, right here!