Exactly why I switched to fish. Fish doesn't come preconfigured exactly how I would like, but it's close enough that I just grew accustomed to fish defaults and have no trouble with it now, and no longer give any thought to shell configuration.
> For Vim users, I also suggest enabling Vim mode in Zsh. It makes editing commands much faster.
I am also an avid Vim user but I disagree. The default readline is perfectly fine for single line commands (you do have to know your way around some basic commands though C-a/u/k/l/w...). To edit long commands in $EDITOR you can always do C-x C-e in bash/zsh (M-v in Fish). As a matter of fact everytime I pair program with my colleague I always think he is editing those short commands slower than I would have because he has to change modes all the time.
Like many other people, I use oh-my-zsh for default setup and that's it. I literally use a single plugin for git and very actively autoload my custom functions to avoid startup delay. With my 384 line config and oh-my-zsh on, here are the results:
$ hyperfine -N "zsh -lc 'exit 0'" "zsh -c 'exit 0'"
Benchmark 1: zsh -lc 'exit 0'
Time (mean ± σ): 54.5 ms ± 6.3 ms [User: 10.2 ms, System: 14.3 ms]
Range (min … max): 38.1 ms … 64.9 ms 78 runs
Benchmark 2: zsh -c 'exit 0' Time (mean ± σ): 6.5 ms ± 1.4 ms [User: 0.8 ms, System: 1.3 ms]
Range (min … max): 3.9 ms … 14.2 ms 424 runs
It's crazy how their startup time is 380 ms, and I suspect something else might be the reason, not just oh-my-zshI switched to fish shell with star ship. Fish has autocomplete and syntax highlighting out of the box which is quite neat and the main features I use in omgzh so fish was a safe choice for me
I switched to zim years ago and found it has all the features that I need but is much faster and I think easier to install (though I haven’t installed either for some time).
I installed oh-my-zsh back in early college some 15 years ago, before zsh was even the default on macs, and it is so good I’ve never felt compelled to experiment or try any other shells terminals or configs. It’s the first thing I install on every new computer.
> The main problem with Oh My Zsh is that it adds a lot of unnecessary bloat that affects shell startup time.
Wowsers!
That +0.5 seconds delay will kill cats everywhere. We must microoptimise the startup time of shells!!!
Or ... we could simply use bash and KDE konsole with, say, 10 tabs. That setup works for me since ages; admittedly I use bash just as a wrapper for simple actions as well as calling a gazillion of aliases and mostly ruby scripts that do the real job. But damn I never knew there were guys who were concerned with +0.5 seconds delays caused by oh-my-zsh. The bloat! Oh my godsers!
Dunno.
I have 90 lines zsh config with 3 plugins (compinit, vcs-info, edit-command-line) and startup-exit sequence takes 0.32s.
You learn very quickly where the lags come though when you work on a big old repository (I learned this on Emacs source code) where getting current branch for jujutsu takes ~5 second. Git is faster in this regard but it still is ~0.3s
I'm not fan of starship (I don't use fancy command line variables in general) but many of those issues can be dealt with awesome bkt caching utility [0]. Instead of live reading just let bkt cache it with long TTL with eager async refreshes. My guess is that Starship does exactly that.
When I switched to zsh 5 years ago, I went with a stock set up too.
There's quite a few things the OP's post didn't mention about shell history that I think are really important:
setopt HIST_IGNORE_ALL_DUPS # Never add duplicate entries.
setopt HIST_IGNORE_SPACE # Ignore commands that start with a space.
setopt HIST_REDUCE_BLANKS # Remove unnecessary blank lines.
It's possible to roll your own prompt that does helpful things without using starship.Also you can roll your own zsh plugin manager in a few lines of shell scripts, `fast-syntax-highlighting` is a really useful plugin to get real-time feedback when typing commands.
Most of those things are mentioned here https://nickjanetakis.com/blog/i-recently-switched-to-zsh-an..., the post is 5 years old but just about all of that is what I do today still. Since then it has evolved to become better IMO, including using a dedicated Vim zsh plugin which is much improved over the default zsh key binds. Also another plugin to show zsh's tab complete in fzf instead of zsh's window. The tab complete demo video is here https://nickjanetakis.com/blog/hooking-up-fzf-with-zsh-tab-c....
I use a subset of omz by cloning it and manually sourcing the plugins I want myself rather than initializing the entire omz system. No themes, no checking for updates, etc. For me, it’s the best of both worlds.
I describe my setup and how to use it on a fresh MacBook here: https://github.com/agrounds/dotfiles
After holding out for literally years after Mac changed their default shell to ZSH, I finally switched over. I didn't love it, but it was okay and had some niceties that I wasn't used to. Then I started to configure it and inevitably ran into Oh My Zsh, and spent some time playing around with that to get it how I liked.
In the end, I realised nothing was as good (to me) as my original Bash set up. I have all the features I need, it's universally supported, and it's fast.
Tip: Install the post GNU2 version from brew
I use OMZ because it lets me rely on popular defaults instead of bike shedding and rolling my own. Its main advantage is convention over configuration. For instance, I just have to learn the git plugin aliases once, and then I can use them anywhere with OMZ + git plugin. Is there any lighter alternative that is compatible with OMZ plugins?
I had the same gripe as the author. OhmyZSH seems too bloated for my needs. Added to that, the defaults adds (and oft unnecessary) emojis to prompts & outputs - something I don't find tasteful or appealing.
I stripped out most of the OhMyZsh functions (which is pretty modular given a shell package) and created a smaller, leaner package (leanZSH) having only the known stuff I may use. I have been using it without much complaints.
The amount of time this author is complaining about is like, a fraction of the time I spend getting through the first few sips of coffee in my day. I'm sure there's so many bigger time optimizations to tackle first.
This feels like a strange hang up to me.
What workflow involves opening hundreds of shells every day? Like, I've got a half dozen shells open at any given time, and sometimes I gotta refresh or reboot, but even on my worst day in looking at two dozen.
How do you get to hundreds?
> OMZ adds bloat
They all do... if you want the niceties of not having to write your own shell config, what would you expect?
It's funny how many people pick up OMZ or doom emacs because some YouTuber told them to do it, then drop them in 6 months because they're all bloaty.
For command search I've replaced regular search and fzf with atuin. Works especially well with multiple hosts.. https://atuin.sh/
EDIT: The OP fails to mention zsh profiling: zprof. I discovered that atuin is my biggest waster at the moment with like 20ms and rest of the stuff I could clean up.
They complain about a startup time of 380ms, but with the default configuration it's only 60ms on my laptop. That's faster than the final startup time of 70ms of their custom config, and it has all the features that they added to their config. So with all the features they need OMZ should be fast enough for them? I don't get it.
I tries oh my zsh whil switching to it from fish ("the we don't believe in configuration" shell). I thought it would be great with all the popularity it has but 90 percent of the plug-ins are alias definitions which I certainly won't memorize somebody else's. Just found a few plugins I like for the fish functionality I liked. Spent some time configuring it asking for help on the irc channel for zsh when needed. Great people. Zsh is awesome. No plugin manager for me though. Thanks.
I never moved to omz (or even zsh; I still rock bash) because I have 10+ years of dotfiles that cover all of my needs. I can see all of the cloud accounts I'm logged into, the status of my Git repositories when I'm cd'ed into them, the number of directories deep my stack is when I use pushd, and have lots and lots of custom functions that save me time. I had moving to zsh in my personal backlog for many years but have yet to come across a pressing reason why I should!
Anyway, yeah, all of this adds startup and command invocation time, but the value far outweighs the latency.
I don't think 0.38s is a bad trade-off for convenience when the rest of the tools I need to do my job collectively are another 2s at shell startup. NVM alone adds 0.5-0.6s on my M4 Macbook Air.
Bigger fish to fry if we're being practical.
zsh is still crazy to me. I use bash for everything. I have no idea what I’m missing out on.
Highly recommend https://grml.org/zsh/
For nixos users: https://discourse.nixos.org/t/using-zsh-with-grml-config-and...
Super easy to setup, and works very well
This is the .zshrc file I have in my dotfiles.
It auto installs everything if you don't have it. Starts effectively instantly.
External dependencies (or remove their line at the bottom)
- [Mise](https://mise.jdx.dev/) fast asdf, runner, and direnv replacement
- [oxide](https://github.com/ajeetdsouza/zoxide) smart and fast cd replacement
-[atuin](https://atuin.sh/) ctrl + r and shell history finder
- [fzf](https://github.com/junegunn/fzf) fuzzy finder
``` # Plugin Manager
declare -A ZINIT ZINIT[NO_ALIASES]=1 ZINIT_HOME="${XDG_DATA_HOME:-${HOME}/.local/share}/zinit/zinit.git" [ ! -d $ZINIT_HOME ] && mkdir -p "$(dirname $ZINIT_HOME)" [ ! -d $ZINIT_HOME/.git ] && git clone https://github.com/zdharma-continuum/zinit.git "$ZINIT_HOME" source "${ZINIT_HOME}/zinit.zsh"
autoload -Uz compinit; compinit
# Plugins zinit light Aloxaf/fzf-tab zstyle ':fzf-tab:' use-fzf-default-opts yes zinit light zdharma-continuum/fast-syntax-highlighting zinit light zsh-users/zsh-autosuggestions
# Starship zinit ice as"command" from"gh-r" \ atclone"./starship init zsh > init.zsh; ./starship completions zsh > _starship" \ atpull"%atclone" src"init.zsh" zinit light starship/starship
zstyle ':fzf-tab:complete:' fzf-bindings 'shift-tab:toggle' zstyle ':fzf-tab:' switch-group ',' '.' zstyle ':fzf-tab:' continuous-trigger '`'
source <(fzf --zsh)
eval "$(mise activate zsh)" eval "$(zoxide init zsh)" eval "$(atuin init zsh --disable-up-arrow)" ```
> I'm using starship which is a fast and minimal prompt packed into a single binary.
cargo install starship --locked
downloads 336 packages. So much for "minimal". cargo is the new npm
In case the authors sees that, your default shell is configured via [0]:
users.users.yourUser.shell = pkgs.fish;
[0]: https://search.nixos.org/options?channel=unstable&show=users...I'm incredibly impatient with my tools and I've been running omz for many years. I spend my days in tmux/vim and generally run 6-12 shells at a time.
Some quick troubleshooting many years ago narrowed the vast majority of the problem down to the git plugin, especially for large, old repos.
I disabled the git plugin and everything has been fine ever since.
Figured I'd dig deeper and bring back the current branch name without the bloat at some point, but it hasn't bothered me enough to do it.
I'll go a step further, you probably don't need zsh at all. Once you install Starship there's not much difference if you just use bash.
My zsh config has three things:
setopt PROMPT_SUBST ; PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '
bindkey "^R" history-incremental-search-backward
autoload -Uz compinit && compinit
The first one is mentioned in `git-prompt.sh` that comes with git, which needs to be sourced as well.Oh My Zsh adds bloat but sets sensible default settings compared to vanilla zsh. I tried using zsh without OMZ and I realized how many things are in OMZ which I took for granted, especially keybindings.
~150ms with minimal setup is good enough for me, although I would prefer <50ms.
huh, is this a problem people really have? I just have a plugin that lets me type before zsh loads and I don't really have a problem with this, even before that i didn't really notice a problem since my 'default' configuration is .12s.
time zsh -i -c exit
zsh -i -c exit 0.12s user 0.09s system 81% cpu 0.276 total
~Surprised no one has shout out zsh4humans, perhaps because it's basically in maintenance mode but it's not like I need any new features. Love the ssh teleport feature.
I used Oh My Zsh for years, but there were literally 3-4 features I relied on: autocompletion, git plugin, history search, and one theme.
For some reason it was slow to load which I found annoying, so I used Claude Code to optimize it. In the end I ended up removing Oh My ZSH entirely, now I have a single .zshrc file that contains everything, and it became much faster.
Similarly I moved from Packer to Lazy.nvim and updated a number of libraries, and from iTerm to Ghostty, Claude Code essentially converted my configs in a matter of minutes
This is not an issue for me due to my workflow.
I have a script for each of my projects that I run when I open a new terminal window (Alacritty). The scripts set up tmux with 3-8 terminals, each terminal launches a components, utility or just sits in a folder from which I later run commands.
Having said that, I use only a few zsh plugins, and have a theme configured to not run commands that add extra latency.
I have these plugins: git, zsh-autosuggestions
/usr/bin/time -f "%e seconds" zsh -i -c exit
0.06 seconds
This is acceptable, maybe the zsh-autocomplete is the problem for author or something else?I originally switched to ZSH + Oh My Shell because it opens so fast. Ideally plugins would initialize asynchronously but it's not very easy with shell scripts I think.
I concur. I tried oh my zsh and for a while I thought I was doing something wrong. My experience was terrible. But it turns out that many people did not mind the bloat and the prompt lag. It was not for me. I uninstalled it and I have such a bad taste in my mouth that I am very reluctant to try any of the alternatives.
Are we really quibbling over 400ms startup delay to open a new terminal?
I have given up on any external bash configurator a long time ago, instead I write my own bash prompts these days, they lack a lot of functionalities but I am much happy with them for now, also a shameless plug: https://martianlantern.github.io/2025/11/updating-my-bash-pr...
I have been using OMZ for the last 8 years but recently made the switch to plain zsh with : - starship for a better prompt - Claude ported plugins I was using from omz (extract, sudo) - custom written aliases that were muscle memory - zoxide for the a command
So far that has been a great move, my terminal tab feel snappy again. One thing I miss (but I’m sure I could find a way to replace it) is `cd ….´
The problem with zsh, as with a lot of open source tools is bad defaults. If only zsh had a better out of the box experience then OMZ wouldn't be needed. I used maintain a lot of configs, over 10 years I just keep forgetting what did I set up. I don't want to be bothered with this anymore.
Like many I installed omz and ran it as the default for a long time. After a while I looked to optimize my shell starts and realized I was only using a fraction of the functionality.
So I figured out what I was using and created my own very paired down version of what I needed. My boot times are much faster and I’ve been totally happy with it. I also learned a lot more about shell configs as a result.
It's funny how there are operations so sensitive to latency that even half a second feels too long.
However I agree with other comments that the author's baseline of 380ms is suspicious. I get 150ms (full config, 6 plugins) vs 50ms with no config and plugins.
I agree, I used omz a while now but I have since also realised that the features I uses are so basic, it really does not warrant a whole software project as a dependency.
So I went and had Gemini make me a zsh config with the features I actually use. Took 15 minutes to get all the autocompelte, aliases and search functionality and done.
> Once in a while, it also checks for updates, which can take up to a few seconds when you open a new tab.
This can be disabled fairly trivially. I then alias the update command to a homebrew update alias.
Agree. If you want some colors, git status, a few convenience functions and a clean prompt, this is my current setup: https://monokai.pro/zsh
Didn't know about starship and need to check it out.
Shameless plug: I wrote a detailed git prompt in C which is similar to posh-git on Powershell: https://github.com/mahesh-hegde/promptsynth
I am just glad that it is sub-second start time, where with powershell, it was upwards of multiple seconds
I use oh my zsh for exactly one reason: I can get a good shell experience out of the box and immediately start working on stuff productively, whether it's a new machine, a new remote host or a container.
I could spend hours figuring out all those things, bit I'd rather use that time for something more important.