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.
Try https://starship.rs then. Starship gives you the same "drop in and go" experience but without the 200ms+ prompt lag. One curl -> one line in your rc file, works on zsh/bash/fish/whatever.
I'm so glad I switched to fish, I'd rather have genuinely good settings out of the box rather than endless configuration, and honestly it's much better out of the box than any configuration I've ever had.
Only drawback is that it's not POSIX, no issue for me, but maybe for people who have a lot of muscle memory with bash.
You can see that when the segments are empty, they still appear as a 1-width segment, rather than entirely disappearing.
It also makes you configure many things by hand. powerlevel10k has an interactive wizard that lets you design your prompt one option at a time (do you want a nerd font? do you want it one line or two? etc) but Starship makes you manually write escape codes if your preferences don't match one of the presets.
No judgment, but I do wonder what people like about Starship that makes up for these things.
Just tried Starship, even though it wasn't the first time I'd heard about it. I would not say it is a 'drop-in and go' experience. Let me explain.
After installing and adding it to my bashrc, I was wondering was those version numbers and cloud symbols meant. Turns out: Since NodeJS and Python were installed, it found a good idea to print the respective versions. I could not care less about those versions. The other part was that it thought that I would like to see my AWS region. Well, I mean, I have built something with AWS a few years back, and the config file for that still exists, but no, I don't want to see that region every time I open a shell. Finally, the default is to have the prompt in a new line. I think when you have a long prompt that makes sense, and it might also be a taste thing. However, the documentation has this example at the beginning about newlines:
# Inserts a blank line between shell prompts
add_newline = true
So I thought `add_newline = false` should do the trick, but it didn't.
Luckily, the AI (GPT-5.2) was pretty good at explaining and giving instructions for changing things. So after 30 minutes, everything was understood and configured to my liking. I like the result, but the default was pretty weird.
I tried using Starship, and it’s clearly faster than Oh My Zsh, but my issue was that I relied on some useful Oh My Zsh features that I didn’t know how to replicate in Starship. One of these is history filtering - for example, when I type source and press the up arrow, I only see previously run source commands, which makes it easy to find what I’m looking for. I tried to get this working in Starship, but had no luck.
FWIW if you're on a machine where you're allowed to use non-default configs like oh-my-zsh, you could also just copy over your own custom config. It seems like you're implying the alternative to using oh-my-zsh is to rewrite your config from scratch every time or use the default. It doesn't quite add up to me. If you craft a config file of your liking one time, then back it up somewhere, track it with git, whatever, you can keep making use of that config across other machines. I just set up a new personal machine recently, grabbed my dotfiles, now it's the same familiar feeling as my other machine.
In case you weren't aware, MacOS uses zsh as the default installed shell. The bash version that comes with MacOS is some ancient 3.x version, from 2005.
I stopped using Oh My Zsh for exactly one reason too: It was so freaking slow it had a noticeable effect on my shell and my mood. It frustrated me that I had to stop and wait every time I opened a tab.
So I removed it, then continued using Zsh and whenever I missed something from before I looked up what it was and installed the plugin easily with Homebrew. The whole process took under an hour. I realised I only needed two or three plugins.
Now my shell is fast, without unnecessary bloat, and does what I need. I’m much more productive and happier, and at the end of the day I don’t really see what’s more important than that (within the scope of the conversation).
Exactly. The popular culture has bad picks. We can be low effort without necessarily being 100% unselective! No taste is not mandatory! Just the littlest bit of trying & listening to our peers can make a better world.
There's so many better non-shite alternatives. Just one: Zim aka zimfw is one. It's just so sad that there's such a negative creep energy towards "I tried nothing and did nothing and this is where I am". Bad hacker bad. You deserve no voice.
Less than five minutes to read but how long to set up my own? The author only showed what he needs/prefers ("Here is my config for starship"). I'll need to navigate the documentation of starship to figure out all those options, which defeats the purpose. Their config documentation (https://starship.rs/config/) already gives me headaches.
And from the article
> Because cloud services are available globally, I've disabled them.
That's some bad defaults right there.
> When you run a command, it also shows how long it took to execute.
No I absolutely don't want this thing done by the author. Now I am fully in the "customize my config" territory.
Also, most of us are unlike the author, and 0.07s vs 0.38s startup time means no difference.
I think the point of the previous comment has been more than clear enough.
That misses the point. I don’t even want to think about any of that stuff.
It’s a single command to install oh-my-zsh. I can fire it off, check Slack, and come back in 5 minutes. If I have to take 5 minutes to setup it up, I’m just not going to do it.
I recreated my several hundred line + several plugins zsh config in a few dozen lines of fish and one plugin (fzf.fish), about 8 years ago. It’s been a joy to use.
I've spent few days and got some basic zsh settings adjust for me. Since then I'm mostly using zsh with very little configuration and I like it a lot. Yes, it's a steep curve, but I'm spending all my life in zsh, so I think that was good time investment for me. In my experience default zsh settings are good enough and require very little customization.
I will have forgotten almost everything by the time something inevitably breaks in a few years. Unless I am constantly recalling the knowledge and applying it, I don't find it worth it. And I _don't_ want to be constantly recalling this knowledge. I want it to just work.
OMZ has been working steadily for me for the past 8+ years. Autocomplete, syntax highlighting, and a concise prompt--really all I need.
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.
The additional upside of this approach is that you can also quite easily install fish on any host and it won't need any configuration to match what you're already used to
Totally agree. Fish out of the box is super performant, lots of tools ship completions for it, and the UX is just great. Only recommendation for people new to fish is to read the keybinds thoroughly. I convinced an eng on my team to switch but he was using it like sh: not using tab complete, shift+arrows for partial complete, etc. Slowed him down a ton.
> 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.
I like to re-add the readline binds after enabling vim mode, and then I only leave insert mode occasionally. C-x C-e really is great, though, I think I do tend to reach for that if I need to do a big edit of a one-liner.
Changing modes is a single key stroke away. That's hardly a reason to be slow.
Readline settings depend on what you're already used to. If you're comfortable with vi key bindings, then being in normal mode, navigating with `w`/`b`, deleting a word with `dw`, deleting up to a quote with `dt"`, etc., are all done with muscle memory, and should be much faster than learning the equivalent Emacs bindings, pressing unintuitive key chords, or opening the command in an editor. I don't like opening an editor since it's an interruption, and it hides the output of the previous command.
I wish I could have the full power of Vim in my shells. For example, I miss the delete between characters binding. `di"` or `di'` are great for modifying argument values.
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:
For anyone who cares about zsh startup performance, `zsh4humans` by `romkatv` (author of powerlevel10k) is worth a look: https://github.com/romkatv/zsh4humans
It achieves instant startup by rendering the prompt before the full shell initializes. Since adopting it, I am done fiddling with my shell config and the fact that `zsh4humans` is in maintenance-mode is actually an advantage as it keeps me from wasting time refactoring `zshrc`.
I think `zsh -l` start a login shell, which does not load zshrc so oh-my-zsh don't get initialized. Try `zsh -ic exit` and it should load zshrc before executing exit.
Valid points, I learned something new today. Thanks, you were right. If using -ic flags I am getting around 300 ms... Interesting how I never noticed, guess I don't open many terminal during the day
I 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
Fish is also not POSIX which has always been its, and my, issue. I use zsh+starship and my own very minimal init stuff+zsh autocomplete and syntaxhighlihg plugins. It’s not a perfect setup. I wish fish would “just work” but it doesn’t. Frequently I had to look up for “workarounds” for my setup. 25 years in, I think I got it and i just keep my zshrc and `machine-init.sh` on point for my-own-style-experience. I think a lot of that could be simplified with fish+starship, but it’s just not there.
> Fish is also not POSIX which has always been its, and my, issue
Could you give some examples of issues you encountered because of that? I've been using fish for about 8 years now I can't remember an instance where that was a problem in interactive use.
Yeah. I used zsh for decades, invested a reasonable amount of emotion and time in my config but swapped to fish last year as a sort of January trial and it stuck.
It's not perfect, the lack of HEREDOCs are annoying sometimes, and no background-able blocks (eg `{x}&`) means you can't async things as easily in scripts.
Zsh has a lot of advanced stuff (at least for a shell) that can deliver pretty complex scripting such as throw/catching, mountains of variable flags and switches which I do miss when I write fish scripts but really -- I've abused them a lot over the years and now days I would be more likely to just use a "builds to a single binary" language.
I will probably swap to nushell when it gets a bit more stable (in my experience it's runtime is stable, but it's feature set / command names are still shaking out. I really like it's general ideas though in terms operating on structured data.
I have been using omz for YEARS. I have practically grown up with it. I resent that I would have never noticed that it took several hundred milliseconds to load, if it were not for this discussion. I never felt the delay particularly unless I was in a very large Git repository — which is rare. On the bright side, now I know about `fish` and am learning there are some nice features I never had in ZSH (i.e. much more advanced autosuggest.) What I basically use omz for is 1) autocomplete, 2) git aliases, and 3) my beloved prompt. In about 30 minutes, Claude helped me port my prompt from ZSH, autocomplete comes OOB, and a cursory Google search shows someone has made a Fish plugin to satiate my Git alias muscle memory. I could leave Zsh/omz in the rear view mirror tomorrow — but for why? I never would have noticed before this discussion...
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).
Fast as sin, and one of the most flexible installers systems. You can point it at an incredibly diverse array of different things to install, in different forms, with different urls, and it will just do the thing.
Zimfw definitely has it's own ecosystem, plugins which are zimfw capable. But it's remarkably versatile at bringing in zsh code. Most plugin-systems are pretty ego-centric, demand specific implementations, and zimfw stands out not just for it's ridiculously impressive speed & handling, but for it's versatility too.
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!
For terminal-centric workflows, one ends up needing to open dozens of shells throughout the day.
Starting one command, realizing you need info from a previous command, often the fastest way to get that info is to open another terminal and start typing and the copy-pasting the relevant piece of cmd. Or needing the output from another command that's scrolled up in a window. In general you end up with a mosaic of tiles each of which is holding key information. So you inevitably open a new tab to make use of the information in the other 3 or 4 windows.
Shell startup is mainly not about waiting for a few terminals in abstraction, but about the way each shell is just a small piece of a longer live workflow and waiting a second for a shell so that you can fill in a piece of a command feels terrible. I think nushell will help cut down on this unpiped inefficiency, but it's usually much simpler to manually glue bash commands together than to parse text output and pipe.
Plus, how many shell can one individual open in a day ? I'm doing that once per day on a good day, maybe twenty if I have a lot of unplanned work on subprojects that needs to be done concurrently with my main task.
Sometimes hundreds per day. Tabs come and go here. People have different workflows.
Yesterday just shy over 50, according to entries from `login` in the system log.
I do launch multiple interpreters just to get a fancy coloful cowsay on each launch. Which involves the fortune program, lolcat (via ruby) and cowsay itself (via Perl). I probably should optimise that into a single C binary for better startup times! :)
The problem with long startups is that they break the flow. I live in CLI. I open and close terminal windows all day long, sometimes just for quick 2-3 commands to check something. 100 new interactive shells a day is my guess. I already know commands to run, my fingers are ready to type, they already pressed the keys ti spawn a new shell and now they have to stop for 500 ms. Repeat these 100 interruptions every day and you get the death by 1000 spoons.
I don't use oh my zsh, but on one laptop zsh took 600ms to start. I narrowed it down to a strange "bug": adding even a single empty file to the custom fpath caused the slowdown. It bugged me so bad that I decided to try fish again, but this time for real. And this time it stuck with me. I like its architecture (defining functions to change its look-and-feel - great idea!) and of course its 32 ms startup time.
As another commenter, I'm probably at 100s per day.
A reason is that I use i3 workspaces, with each workspace being for different tasks, so I don't want to reuse a terminal that has another context.
One issue with keeping a single shell is that the history is full of irrelevant stuff. If you run commands that take a while and print a lot of output, you want it to be as clean as possible. If I want the beginning of the command, I can scroll to the top, and I don't end up with some unrelated output.
I also take quite notes in vim everywhere, often next to long-running commands, using tmux.
I couldn’t help but think this as well. I understand wanting software that feels snappy, but this is hardly a problem. Instead of trying to convince the reader that we should care about this, it would be nice if the writer admitted this is an inconsequential personal preference.
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.
I moved from oh-my-zsh to grml ~10 years ago, and I've enjoyed it - it's got good defaults, is extensible (I've added custom stuff to handle how I manage directories for work things) and the single-file nature of the defaults makes it super straightforward to put it onto a new machine (ie a server) without then necessarily needing to do any extra tweaking
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....
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.
I use atuin for the shell history as it seems to know when I've run a command in one tab/split while another is open where fzf doesn't seem to sync it all the time. But I still use fzf to find files.
(Bonus, I use Zoxide to replace the alt+d cd shortcut as it's much faster, and use https://github.com/Aloxaf/fzf-tab for tab completions in the terminal to become fuzzy, very very useful)
Atuin also has syncing and backups though I've never really felt the need to use it. I prefer keeping histories separate and when I need to share shell commands I just do the usual methods like putting it in a shared text file, send it to myself on a chat app or just looking at the command and typing it out
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.
Seriously. I do think people should spend enough time with bash or posix sh to be comfortable with it, but I'd recommend everyone at least just try fish. It's a lovely interactive experience out of the box with colors, completions, a great prompt, etc. Plus, the scripting language is quite comfy. Like, somewhere between bash and Python (if you find Python comfy, I guess). At least to me it makes more intuitive sense, once I got over the fact that "it's not bash/zsh."
It's written in Rust, if you care about that sort of thing (I switched before that was a thing). And for simple one-liners, compatibility actually has improved at least a bit (like you can do && now, which wasn't a thing before).
Write your shell-specific helper scripts or personal scripts in fish, write your portable scripts in Python or Bash. Look, I love standards. Sometimes non-standard things make sense though. Sometimes they even make more sense in the right context.
Or maybe you'll hate it. That's fine. People won't know until they try though.
For something newer and even more different, check out nushell. I don't have much experience with it, but a lot of its ideas are enticing.
The problem is that I forgot (if I ever knew) bash.
I can write fish, scripting or interactively on my shell without thinking too hard about the syntax, but when scripting in bash I require an example or using my snippets to be sure I'm not shooting myself on the foot or writing something that bash will reject right away.
Glad to see fish getting some shout outs here. Been using it for over ten years now, and it is super easy to get going on new hosts - it is just one simple install away.
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.
In a similar vein, there is slimzsh [1]. For me, it is a minimal config that enables everything that's useful, and only that. Quite a few others and I have been using this for more than a decade.
https://github.com/changs/slimzsh
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.
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.
Temporary splits to run code close to the editor, tmux popups (they open lazygit or file manager on top of the current tab). Debug runs, where I want to preserve their output for some time, so I keep them in separate tabs.
I use a lot of short-lived terminals. I have zsh+foot configured so that ctrl+shift+n opens a new terminal with the same current directory, so when using Vim, that's as fast as putting Vim in background, but I can tile both windows easily.
I never have more than a one or two dozen terminals at a time, but I definitely open hundred of short-lived ones.
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.
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've been an oh-my-zsh user for many years now, being very happy with the very small set of features I use from it. Previously I could never think of trying to figure out how to replicate the features I need without the other features from oh-my-zsh, which does make the shell noticeably slower.
Just now, after reading this article, I used Claude code and have removed the OMZ config within 5 minutes. Here's my prompt - maybe others could find it useful. I ran this from `~/.oh-my-zsh`.
```
Here's my zsh config - I'd like to remove oh-my-zsh and replace the provided functionality with just raw zsh. i use starship for my prompt so i don't need
any help there.
can you explore the oh-my-zsh codebae and see what it would take to replicate the features it currently provides me in the shell?
my zsh config below:
export ZSH="$HOME/.oh-my-zsh"
ZSH_THEME=""
DISABLE_AUTO_TITLE="true"
plugins=(direnv fzf)
source $ZSH/oh-my-zsh.sh
--- CLAUDE RESPONSE ---
Minimal Raw Zsh Replacement
Since you use starship and have DISABLE_AUTO_TITLE=true, you can skip prompt and title-related code. Here's what you'd need:
# Completions
autoload -Uz compinit
compinit
zstyle ':completion:*' menu select
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' # case insensitive
# History
HISTFILE=~/.zsh_history
HISTSIZE=50000
SAVEHIST=10000
setopt extended_history hist_expire_dups_first hist_ignore_dups
setopt hist_ignore_space hist_verify share_history
# Directory navigation
setopt auto_cd auto_pushd pushd_ignore_dups pushdminus
# Key bindings (emacs mode)
bindkey -e
bindkey '^[[H' beginning-of-line # Home
bindkey '^[[F' end-of-line # End
bindkey '^[[1;5C' forward-word # Ctrl-Right
bindkey '^[[1;5D' backward-word # Ctrl-Left
bindkey '^[[3~' delete-char # Delete
# Colors
autoload -Uz colors && colors
export CLICOLOR=1 # macOS ls colors
# Plugins replacement
eval "$(direnv hook zsh)"
eval "$(fzf --zsh)"
```
Granted I've only done this like 5 minutes ago and might be missing functionality I'll realise later, but a quick few checks give me hope I have all the functionality I want.
FWIW, I still use bash as well. Nothing against zsh per-se, it's just that I know bash, bash works, and there's no particular pain I experience using bash that will obviously be solved by switching. And when you factor in anticipated switching costs, I haven't found any compelling reason to spend any significant time on zsh so far.
Yes, I'll throw my hat into this group too. Bash is fine.
YMMV but I have found using zsh too frictitious to be helpful. Sure, theoretically zsh living in a bash world (lets face it, all scripts are bash) is completely fine but reality seems to differ. Copied a one liner from shell history into your script? Crash. Use arrays? Weird bugs. Use shell builtins? Whoa unexpected interactivity!!! Etc...
Bash is absolutely fine as a default shell. As an added benefit, you don't feel like an invalid once logged in to a container or server.
I've been using it for the last 6 or 7 years and I can only remember one specific feature I use a lot: "unset HISTFILE" to disable history when I need to run commands with passwords.
Other than that, oh-my-zsh with git, systemd, and fzf plugins. Saves a lot of typing.
The main selling point for me is how easy it is to setup.
I don't think it is crazy, but I know and love the bash quirks. I've got permanent history setup thanks to Eli Bandersky [1] which I know zsh has a solution to already. But what annoys me with zsh is some of the ways it tab completes when navigating the filesystem, and not by default allowing comments on the command line, e.g. '# github api key blahblahblah', which I can then pull later using phgrep.
Slight pain on a mac to get the latest version and use it as terminal shell, but it gets easier everytime I work on a fresh mac.
If you want vi history editing like you are used to in bash for the last 20 years it's subtly different in a manner that makes it insanity inducing. If you use the traditional emacs like editing it's much the same.
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'm changing to GhosTTY as we speak (from Mac Terminal, because I'm tired of gemini-cli not getting my shift-return for newlines). Wasn't until that process that I learned that new Mac accounts are on a different shell (zsh) than I have (bash). Last time I switched shells was when Apple flipped from tcsh.
Now, I'm deep down the rabbit hole of standardizing all my shells/terminals/configs with Nix. Either a really good or really bad project to start on a Friday night.
It's basically the same, except smarter about command history and auto-completion by default. I'm sure you could get Bash to act the same way with a bit of prodding.
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.
You can replace nvm with https://mise.jdx.dev/ , it starts effectively instantly and works not only for node versions but all programming languages and tools.
I am seeing a phenomenon of people wanting to hyper optimise their workflows. It’s nonsensical when you consider the other stuff you need to do or how slow everything else is.
Holy heck, I just profiled my zsh initialization and nvm was the big source of bloat, holy hell. Similar setup as you (M4 MBP), same amount of startup bloat. Lazy loading it fixes it.
That's why I switched to Mise (https://mise.jdx.dev). Having new terminal sessions taking up hundreds of milliseconds because of nvm isn't the end of the world, but it's annoying when you're in the middle of something.
Mise reads in your .nvmrc files so you don't have to configure anything new.
Although this is what Opus recommends, it will give you many issues as you don’t really have any node runtimes in the path (or worse if you do).
What I recommend is replacing it with $PATH=(a command to find the nvm default alias directory, detect the verion and load it from that specific version directory directly) so you always have default node in path and then lazy loading only nvm itself, so you can switch when you need to.
Sorry I don’t have the command handy as I’m on mobile but if you paste the above into Opus you’ll get it.
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 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?
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.
Current branch without bloat is to cat .git/HEAD, and if that didn't exist, run git symbolic-ref HEAD. The first is faster and works in the common case where you're in the top of a git repo. In either case, run it through ${branch##*/} to strip down to just the current branch.
I have used this for a long time, never understood how people would put all of git in between them and the next prompt.
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
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.
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.
Yes! The very famous xz hack was only found, because a German wondered why his ssh session lagged 200 ms at the start. Everyone should go mad when their main tool lags a few hundred milliseconds. It is unacceptable that we sit on machines, that run billions of calculations per second and our software still lags.
Yes, and hundreds of developers just spent 5 minutes reading about it.
This investment makes sense for OP who opens hundreds of terminal sessions, but does it make sense to bother about 1s delay when they start the terminal session once in a while? I have several sessions opened all the time, the last time I wasted my 1s on zsh was in 2025 when I rebooted my machine due to a nvidia drivers update.
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.
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 ….´
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.
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.
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
~
# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
# Initialization code that may require console input (password prompts, [y/n]
# confirmations, etc.) must go above this block; everything else may go below.
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
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.
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.
Had this problem awhile ago of my zsh startup being slow. Just opened claude code and told it to benchmark my shell start and then optimize it. Took like 5 minutes and now it's ultra fast. Hardly any idea what it did exactly but worked great.
I have a fast machine, never noticed a difference in shell start up time between with and without and given how much more pleasant it is with I'll take the hit.
I had my phase of having a fancy shell with all bells and whistles. I’ve now settled with the default terminal so that 1. It is fast, 2. Whereever I work, I have the same experience.
I have not a small number of plugins on fish and I've never noticed a problem with startup time. I do wish there was a better way of managing or installing plugins. It just feels so fragile.
CachyOS is basically arch on easy mode. I used to spend countless hours tinkering with arch but then I got older and don’t have much time. Plus there are helpful meta packages for gaming that work great out of the box, which for a gamer like me sans Windows is pretty awesome.
I've tinkered at most an hour on my arch install and it's just been running smoothly. The installer these days is easy to go through as well. It's the same for bash, very little customization, then it runs smoothly for years.
I'm not saying CachyOS is bad, just that it is in my opinion another layer of complexity that may change/deprecate/etc.
>I used to spend countless hours tinkering with arch but then I got older and don’t have much time.
Have your lost your old configs that you worked hard on? That's a shame if so. I love moving my configs I've worked hard on to new machines and instantly getting up and running in a now-familiar environment. It saves so much time and effort.
I was annoyed by this enough that I ended up cloning the OMZ repository locally, and stripping out all the modules I don’t use. And now I just have it as part of my dotfiles[1].
It's just a handful of files and I manually source them in my zshrc[2]:
It's essentially the same as omz setup I was using before, but loads in just ~25ms (Note: it's on a hard drive, with ddr3 ram and 18ms out of that is spent by compinit)
It also fixed another issue I had with Oh-My-Zsh: whenever they (very rarely) tweak their default config - it breaks my muscle memory.
I switched to Prezto because of how slow OMZ is, been really happy with it. At one point it started causing issues with the IntelliJ environment reader but it’s been perfect once I sorted that out.
> My workflows involve opening and closing up to hundreds of terminal or tmux tabs a day. I do everything from the terminal. Just imagine that opening a new tab in a text editor would take half a second every time.
This sounds like overoptimization on a neglible time loss for what is essentially an unique (and dare I say: broken?) workflow.
I use terminals a lot ... but I work with 4-5 day-persistent terminals that I open once a day and keep in the background. The QoL effects of omz outweigh microtuning startup times significantly.
Well yeah, you need antibody https://getantibody.github.io/ and then whatever plugins you desire. Been using it for years and it's never been anything other than fast and reliable.
I mean it's not like I've done any formal benchmarks but like I've used a bunch of plug-in managers and antidote, sorry antibody is the old one, it's just so much faster than all the others.
I may not need this sort of shell bling. And I don't use it. But my first Unix system was an early version of Xenix, which had the original Bourne shell that didn't even support cursor up to get a previous command. (I do use cursor up, C-r, and the shell editing commands.)
But yesterday's conveniences become today's essentials, and those who came in after me have their expectations set by the much more sophisticated things available at the time. Like, I'm still flabbergasted by people—working professionals—who go "I can't program without syntax highlighting, autocomplete, and my IDE generally going bing bing wahoo at me as I work, and I don't know how anybody can." We just type the code in. Like we all had to back in the day.
Anyway I can certainly see where someone younger than about 35, or who came to Linux late, would be completely at sixes and sevens without their colorized racing-stripes shell prompt.
Prezto is faster than OMZ, and has been for over a decade. Starship is faster still. I switched from using Prezto standalone to using Prezto + Starship and relying primarily on Starship several years ago. I'd be surprised if many people are still using Oh My ZSH in 2026 vs using Prezto, anyway.
This thread feels so foreign to me. I use basic ass vanilla Windows terminal. It’s fine. I also use the vanilla built-in to VSCode terminal. It is also fine.
Terminals are such a small, unimportant part of my job I barely even think about them.
Yes, Windows users don't have time for such luxuries when they're constantly fighting a losing fight with an increasingly hostile OS. Playing whack-a-mole dismissing ads, dismissing Edge and reopening links in your preferred browser, waiting for React to render in the start menu, coping with the ever increasing theft of personal data, and on and on and on the list goes. The rest of the time is spent on working around Windows oddities that other developers using sensible OSes simply don't need to deal with. No wonder there's no time to think about anything else.
Show me an environment where I can interact with my system programmatically, where I can compose together arbitrary tools, and which will never, ever, ever break on me, and I'll switch! My experience with graphical environments has been that they rarely compose, often break, and constantly make arbitrary changes that break my workflow. So every time I try something else I end up coming back to the terminal.
But I agree that terminal environments have serious shortcomings. I think it's a real shame we haven't created anything else that does what the terminal does, and I think it's mostly for lack of trying.
You're replying to someone that says POSIX shells are holding people back, not that the terminal is a bad idea, there are many alternative shells which offer benefits over POSIX shells. fish-shell has everything you want from an interactive shell included, xonsh is a mix Python shell, nushell and elvish are adding types and other things to shell.
The VT protocols that all shells have to confirm with are pretty dated and I'd love to throw them off the roof for something less stateful and with multiple font sizes but there's no arguing that text based interfaces are good.
> I think it's a real shame we haven't created anything else that does what the terminal does, and I think it's mostly for lack of trying
I'd rather just take terminals a step forward, which I agree hasn't happened due to a lack of trying. But the people who aren't trying are the people who are instead tricking out zsh with plugins. I'm a nushell fan myself but my point here is not
> try nushell
but rather,
> be willing to try things that aren't backwards compatible with `sh`
If more people relaxed on that sticking point, we could actually benefit from the excellent post-POSIX work that has been done. As it is, people are reluctant to try new shells for some reason.
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.
Try https://starship.rs then. Starship gives you the same "drop in and go" experience but without the 200ms+ prompt lag. One curl -> one line in your rc file, works on zsh/bash/fish/whatever.
Configuration is straightforward and easy imo: https://starship.rs/config/
Give it a spin, I think you won't regret it.
I'm so glad I switched to fish, I'd rather have genuinely good settings out of the box rather than endless configuration, and honestly it's much better out of the box than any configuration I've ever had.
Only drawback is that it's not POSIX, no issue for me, but maybe for people who have a lot of muscle memory with bash.
16 replies →
I'm surprised Starship is so popular. It's missing really basic powerlevel10k features like empty segments. If you look at some examples:
https://starship.rs/presets/gruvbox-rainbow
You can see that when the segments are empty, they still appear as a 1-width segment, rather than entirely disappearing.
It also makes you configure many things by hand. powerlevel10k has an interactive wizard that lets you design your prompt one option at a time (do you want a nerd font? do you want it one line or two? etc) but Starship makes you manually write escape codes if your preferences don't match one of the presets.
No judgment, but I do wonder what people like about Starship that makes up for these things.
2 replies →
Just tried Starship, even though it wasn't the first time I'd heard about it. I would not say it is a 'drop-in and go' experience. Let me explain.
After installing and adding it to my bashrc, I was wondering was those version numbers and cloud symbols meant. Turns out: Since NodeJS and Python were installed, it found a good idea to print the respective versions. I could not care less about those versions. The other part was that it thought that I would like to see my AWS region. Well, I mean, I have built something with AWS a few years back, and the config file for that still exists, but no, I don't want to see that region every time I open a shell. Finally, the default is to have the prompt in a new line. I think when you have a long prompt that makes sense, and it might also be a taste thing. However, the documentation has this example at the beginning about newlines:
So I thought `add_newline = false` should do the trick, but it didn't.
Luckily, the AI (GPT-5.2) was pretty good at explaining and giving instructions for changing things. So after 30 minutes, everything was understood and configured to my liking. I like the result, but the default was pretty weird.
I tried using Starship, and it’s clearly faster than Oh My Zsh, but my issue was that I relied on some useful Oh My Zsh features that I didn’t know how to replicate in Starship. One of these is history filtering - for example, when I type source and press the up arrow, I only see previously run source commands, which makes it easy to find what I’m looking for. I tried to get this working in Starship, but had no luck.
6 replies →
From what I can tell, this doesn't nearly fill the gap that OMZ occupies
Nice history, command auto complete, and similar beyond just the looks, out of the box
Oh my zsh makes installing extension so easy, just edit .zshrc and add extract, fzf, z, etc. To the list of plugins
1 reply →
I'll second this. I've had a really pleasant experience using Starship across development environments.
starship is great. I use it with a powerlevel10k fallback in my dotfiles for systems, starship is not installed yet to not break the shell entirely.
2 replies →
Never heard of this, looks pretty good. Are there any community themes based on starship like powerlevel9k/10k?
1 reply →
FWIW if you're on a machine where you're allowed to use non-default configs like oh-my-zsh, you could also just copy over your own custom config. It seems like you're implying the alternative to using oh-my-zsh is to rewrite your config from scratch every time or use the default. It doesn't quite add up to me. If you craft a config file of your liking one time, then back it up somewhere, track it with git, whatever, you can keep making use of that config across other machines. I just set up a new personal machine recently, grabbed my dotfiles, now it's the same familiar feeling as my other machine.
> just copy over your own custom config
That already defeats the purpose:
I don't want to copy things around
I never spend time crafting a custom config
1 reply →
Hmm, weren't dotfiles invented just for that reason?
I'm joking but on a more serious note, installing a shell as a default shell seems more complicated than copying over your .bashrc
In case you weren't aware, MacOS uses zsh as the default installed shell. The bash version that comes with MacOS is some ancient 3.x version, from 2005.
3 replies →
I stopped using Oh My Zsh for exactly one reason too: It was so freaking slow it had a noticeable effect on my shell and my mood. It frustrated me that I had to stop and wait every time I opened a tab.
So I removed it, then continued using Zsh and whenever I missed something from before I looked up what it was and installed the plugin easily with Homebrew. The whole process took under an hour. I realised I only needed two or three plugins.
Now my shell is fast, without unnecessary bloat, and does what I need. I’m much more productive and happier, and at the end of the day I don’t really see what’s more important than that (within the scope of the conversation).
Yeah but you can use something like zim that is better than omz but still easy. The shell starts so fast with zim and it is a breeze to set up
Exactly. The popular culture has bad picks. We can be low effort without necessarily being 100% unselective! No taste is not mandatory! Just the littlest bit of trying & listening to our peers can make a better world.
There's so many better non-shite alternatives. Just one: Zim aka zimfw is one. It's just so sad that there's such a negative creep energy towards "I tried nothing and did nothing and this is where I am". Bad hacker bad. You deserve no voice.
1 reply →
> I could spend hours figuring out all those things,
This post is explaining how to set up those things. Less than five minutes to read.
Less than five minutes to read but how long to set up my own? The author only showed what he needs/prefers ("Here is my config for starship"). I'll need to navigate the documentation of starship to figure out all those options, which defeats the purpose. Their config documentation (https://starship.rs/config/) already gives me headaches.
And from the article
> Because cloud services are available globally, I've disabled them.
That's some bad defaults right there.
> When you run a command, it also shows how long it took to execute.
No I absolutely don't want this thing done by the author. Now I am fully in the "customize my config" territory.
Also, most of us are unlike the author, and 0.07s vs 0.38s startup time means no difference.
I think the point of the previous comment has been more than clear enough.
1 reply →
> Less than five minutes to read.
OMZ is still easier to set up consistently. That’s why we use it.
If the concern is the bloat of OMZ then make FMZ - fast my zsh - that is just as quick to set up and doesn’t add “bloat”?
3 replies →
That misses the point. I don’t even want to think about any of that stuff.
It’s a single command to install oh-my-zsh. I can fire it off, check Slack, and come back in 5 minutes. If I have to take 5 minutes to setup it up, I’m just not going to do it.
15 replies →
I just use fish shell. Way easier.
https://fishshell.com/
I recreated my several hundred line + several plugins zsh config in a few dozen lines of fish and one plugin (fzf.fish), about 8 years ago. It’s been a joy to use.
Biggest problem being not being able to paste much of the complicated code found online. You can save it and run it via bash command though.
oh my zsh can recreate much of the fish functionality while maintaining good bash interoperability.
1 reply →
I've spent few days and got some basic zsh settings adjust for me. Since then I'm mostly using zsh with very little configuration and I like it a lot. Yes, it's a steep curve, but I'm spending all my life in zsh, so I think that was good time investment for me. In my experience default zsh settings are good enough and require very little customization.
You really only have to go through that once and it's a good learning experience.
I will have forgotten almost everything by the time something inevitably breaks in a few years. Unless I am constantly recalling the knowledge and applying it, I don't find it worth it. And I _don't_ want to be constantly recalling this knowledge. I want it to just work.
OMZ has been working steadily for me for the past 8+ years. Autocomplete, syntax highlighting, and a concise prompt--really all I need.
1 reply →
just install fish then
One man’s bloat is another man’s feature.
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.
The additional upside of this approach is that you can also quite easily install fish on any host and it won't need any configuration to match what you're already used to
Totally agree. Fish out of the box is super performant, lots of tools ship completions for it, and the UX is just great. Only recommendation for people new to fish is to read the keybinds thoroughly. I convinced an eng on my team to switch but he was using it like sh: not using tab complete, shift+arrows for partial complete, etc. Slowed him down a ton.
Really curious what is missing from the default configuration in your setup.
If I'm feeling really fancy I may enable vim bindings and add the fuzzy find plugin, but plain fish is so good on its own.
Best shell UX for minimal effort is: fish shell + starship prompt.
Using starship for the prompt provides many pretty UX improvements (showing current git branch, language version, kubernetes context, etc.).
> 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.
> you can always do C-x C-e in bash/zsh (M-v in Fish).
Thanks I didn't know!
I like to re-add the readline binds after enabling vim mode, and then I only leave insert mode occasionally. C-x C-e really is great, though, I think I do tend to reach for that if I need to do a big edit of a one-liner.
Changing modes is a single key stroke away. That's hardly a reason to be slow.
Readline settings depend on what you're already used to. If you're comfortable with vi key bindings, then being in normal mode, navigating with `w`/`b`, deleting a word with `dw`, deleting up to a quote with `dt"`, etc., are all done with muscle memory, and should be much faster than learning the equivalent Emacs bindings, pressing unintuitive key chords, or opening the command in an editor. I don't like opening an editor since it's an interruption, and it hides the output of the previous command.
I wish I could have the full power of Vim in my shells. For example, I miss the delete between characters binding. `di"` or `di'` are great for modifying argument values.
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'
Benchmark 2: zsh -c 'exit 0'
It's crazy how their startup time is 380 ms, and I suspect something else might be the reason, not just oh-my-zsh
For anyone who cares about zsh startup performance, `zsh4humans` by `romkatv` (author of powerlevel10k) is worth a look: https://github.com/romkatv/zsh4humans
It achieves instant startup by rendering the prompt before the full shell initializes. Since adopting it, I am done fiddling with my shell config and the fact that `zsh4humans` is in maintenance-mode is actually an advantage as it keeps me from wasting time refactoring `zshrc`.
I think `zsh -l` start a login shell, which does not load zshrc so oh-my-zsh don't get initialized. Try `zsh -ic exit` and it should load zshrc before executing exit.
That said, the time of `zsh -ic exit` isn't really meaningful metric for measuring the performance of an interactive shell. See https://github.com/romkatv/zsh-bench#how-not-to-benchmark for details.
Valid points, I learned something new today. Thanks, you were right. If using -ic flags I am getting around 300 ms... Interesting how I never noticed, guess I don't open many terminal during the day
Better way to benchmark zsh startup time is with zprof. Add this to your ~/.zshrc:
And then restart terminal.
Trying doing the benchmark in a git repo.
That's where I actually did it, by coincidence
You should try extract, z, and fzf
I 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
https://ruky.me/moving-from-zsh-to-fish-nixos-darwin/
Fish is also not POSIX which has always been its, and my, issue. I use zsh+starship and my own very minimal init stuff+zsh autocomplete and syntaxhighlihg plugins. It’s not a perfect setup. I wish fish would “just work” but it doesn’t. Frequently I had to look up for “workarounds” for my setup. 25 years in, I think I got it and i just keep my zshrc and `machine-init.sh` on point for my-own-style-experience. I think a lot of that could be simplified with fish+starship, but it’s just not there.
> Fish is also not POSIX which has always been its, and my, issue
Could you give some examples of issues you encountered because of that? I've been using fish for about 8 years now I can't remember an instance where that was a problem in interactive use.
8 replies →
Yeah. I used zsh for decades, invested a reasonable amount of emotion and time in my config but swapped to fish last year as a sort of January trial and it stuck.
It's not perfect, the lack of HEREDOCs are annoying sometimes, and no background-able blocks (eg `{x}&`) means you can't async things as easily in scripts.
Zsh has a lot of advanced stuff (at least for a shell) that can deliver pretty complex scripting such as throw/catching, mountains of variable flags and switches which I do miss when I write fish scripts but really -- I've abused them a lot over the years and now days I would be more likely to just use a "builds to a single binary" language.
I will probably swap to nushell when it gets a bit more stable (in my experience it's runtime is stable, but it's feature set / command names are still shaking out. I really like it's general ideas though in terms operating on structured data.
Also, you probably don’t need to customize it at all, it’s more than good enough out of the box.
I have been using omz for YEARS. I have practically grown up with it. I resent that I would have never noticed that it took several hundred milliseconds to load, if it were not for this discussion. I never felt the delay particularly unless I was in a very large Git repository — which is rare. On the bright side, now I know about `fish` and am learning there are some nice features I never had in ZSH (i.e. much more advanced autosuggest.) What I basically use omz for is 1) autocomplete, 2) git aliases, and 3) my beloved prompt. In about 30 minutes, Claude helped me port my prompt from ZSH, autocomplete comes OOB, and a cursory Google search shows someone has made a Fish plugin to satiate my Git alias muscle memory. I could leave Zsh/omz in the rear view mirror tomorrow — but for why? I never would have noticed before this discussion...
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).
https://zimfw.sh/
Fast as sin, and one of the most flexible installers systems. You can point it at an incredibly diverse array of different things to install, in different forms, with different urls, and it will just do the thing.
Zimfw definitely has it's own ecosystem, plugins which are zimfw capable. But it's remarkably versatile at bringing in zsh code. Most plugin-systems are pretty ego-centric, demand specific implementations, and zimfw stands out not just for it's ridiculously impressive speed & handling, but for it's versatility too.
Zimfw rocks.
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!
For terminal-centric workflows, one ends up needing to open dozens of shells throughout the day.
Starting one command, realizing you need info from a previous command, often the fastest way to get that info is to open another terminal and start typing and the copy-pasting the relevant piece of cmd. Or needing the output from another command that's scrolled up in a window. In general you end up with a mosaic of tiles each of which is holding key information. So you inevitably open a new tab to make use of the information in the other 3 or 4 windows.
Shell startup is mainly not about waiting for a few terminals in abstraction, but about the way each shell is just a small piece of a longer live workflow and waiting a second for a shell so that you can fill in a piece of a command feels terrible. I think nushell will help cut down on this unpiped inefficiency, but it's usually much simpler to manually glue bash commands together than to parse text output and pipe.
Plus, how many shell can one individual open in a day ? I'm doing that once per day on a good day, maybe twenty if I have a lot of unplanned work on subprojects that needs to be done concurrently with my main task.
Sometimes hundreds per day. Tabs come and go here. People have different workflows.
Yesterday just shy over 50, according to entries from `login` in the system log.
I do launch multiple interpreters just to get a fancy coloful cowsay on each launch. Which involves the fortune program, lolcat (via ruby) and cowsay itself (via Perl). I probably should optimise that into a single C binary for better startup times! :)
The problem with long startups is that they break the flow. I live in CLI. I open and close terminal windows all day long, sometimes just for quick 2-3 commands to check something. 100 new interactive shells a day is my guess. I already know commands to run, my fingers are ready to type, they already pressed the keys ti spawn a new shell and now they have to stop for 500 ms. Repeat these 100 interruptions every day and you get the death by 1000 spoons.
I don't use oh my zsh, but on one laptop zsh took 600ms to start. I narrowed it down to a strange "bug": adding even a single empty file to the custom fpath caused the slowdown. It bugged me so bad that I decided to try fish again, but this time for real. And this time it stuck with me. I like its architecture (defining functions to change its look-and-feel - great idea!) and of course its 32 ms startup time.
As another commenter, I'm probably at 100s per day.
A reason is that I use i3 workspaces, with each workspace being for different tasks, so I don't want to reuse a terminal that has another context.
One issue with keeping a single shell is that the history is full of irrelevant stuff. If you run commands that take a while and print a lot of output, you want it to be as clean as possible. If I want the beginning of the command, I can scroll to the top, and I don't end up with some unrelated output.
I also take quite notes in vim everywhere, often next to long-running commands, using tmux.
I couldn’t help but think this as well. I understand wanting software that feels snappy, but this is hardly a problem. Instead of trying to convince the reader that we should care about this, it would be nice if the writer admitted this is an inconsequential personal preference.
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.
[0]: https://github.com/dimo414/bkt
https://grml.org/zsh/
Simple, sensible defaults.
Ships with the Arch Linux installation ISO.
I moved from oh-my-zsh to grml ~10 years ago, and I've enjoyed it - it's got good defaults, is extensible (I've added custom stuff to handle how I manage directories for work things) and the single-file nature of the defaults makes it super straightforward to put it onto a new machine (ie a server) without then necessarily needing to do any extra tweaking
Yes, that's also what I use. Always found oh-my-zsh a little too much and too hipster-y for my taste.
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:
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....
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.
I'm using fzf and it's amazing. What does atuin bring additionally? Looks very similar
I use atuin for the shell history as it seems to know when I've run a command in one tab/split while another is open where fzf doesn't seem to sync it all the time. But I still use fzf to find files.
(Bonus, I use Zoxide to replace the alt+d cd shortcut as it's much faster, and use https://github.com/Aloxaf/fzf-tab for tab completions in the terminal to become fuzzy, very very useful)
2 replies →
Atuin also has syncing and backups though I've never really felt the need to use it. I prefer keeping histories separate and when I need to share shell commands I just do the usual methods like putting it in a shared text file, send it to myself on a chat app or just looking at the command and typing it out
1 reply →
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
Or simply use fish
Seriously. I do think people should spend enough time with bash or posix sh to be comfortable with it, but I'd recommend everyone at least just try fish. It's a lovely interactive experience out of the box with colors, completions, a great prompt, etc. Plus, the scripting language is quite comfy. Like, somewhere between bash and Python (if you find Python comfy, I guess). At least to me it makes more intuitive sense, once I got over the fact that "it's not bash/zsh."
It's written in Rust, if you care about that sort of thing (I switched before that was a thing). And for simple one-liners, compatibility actually has improved at least a bit (like you can do && now, which wasn't a thing before).
Write your shell-specific helper scripts or personal scripts in fish, write your portable scripts in Python or Bash. Look, I love standards. Sometimes non-standard things make sense though. Sometimes they even make more sense in the right context.
Or maybe you'll hate it. That's fine. People won't know until they try though.
For something newer and even more different, check out nushell. I don't have much experience with it, but a lot of its ideas are enticing.
Fish gang represent.
I was a bash => zsh/omz person and had these same complaints. But that was 10 years ago. https://github.com/paulirish/dotfiles/blame/main/fish/config...
The baseline fish experience is just better.
Craziest thing: You can still script in bash/zsh even if you use fish but you can't always copy-paste from StackOverflow.
The problem is that I forgot (if I ever knew) bash.
I can write fish, scripting or interactively on my shell without thinking too hard about the syntax, but when scripting in bash I require an example or using my snippets to be sure I'm not shooting myself on the foot or writing something that bash will reject right away.
2 replies →
Glad to see fish getting some shout outs here. Been using it for over ten years now, and it is super easy to get going on new hosts - it is just one simple install away.
+1
Nowadays I just use fish with the out of box installation and it fits all my needs.
Yeap, each time I need a complex shell script, actually Python is a better chose. I just don't need a POSIX compliant shell
I've started to play with the idea more recently to try out fish. No appearant reason.. 10 years in zsh is time enough to get comfortable..
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.
https://github.com/gradientwolf/leanzsh
In a similar vein, there is slimzsh [1]. For me, it is a minimal config that enables everything that's useful, and only that. Quite a few others and I have been using this for more than a decade. https://github.com/changs/slimzsh
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.
I notice the delay, but I try to check myself with it. Not everything has to be instant gratification. We're ruining our brains.
This feels like the craziest excuse for slow software.
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?
Temporary splits to run code close to the editor, tmux popups (they open lazygit or file manager on top of the current tab). Debug runs, where I want to preserve their output for some time, so I keep them in separate tabs.
I use a lot of short-lived terminals. I have zsh+foot configured so that ctrl+shift+n opens a new terminal with the same current directory, so when using Vim, that's as fast as putting Vim in background, but I can tile both windows easily.
I never have more than a one or two dozen terminals at a time, but I definitely open hundred of short-lived ones.
Why? You've said you do but not why you do? Why not leave a terminal open?
1 reply →
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.
> 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.
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.
Startup time depends on hardware and (assume) features you're enabling. Better hardware and less features, less lag.
I've been an oh-my-zsh user for many years now, being very happy with the very small set of features I use from it. Previously I could never think of trying to figure out how to replicate the features I need without the other features from oh-my-zsh, which does make the shell noticeably slower.
Just now, after reading this article, I used Claude code and have removed the OMZ config within 5 minutes. Here's my prompt - maybe others could find it useful. I ran this from `~/.oh-my-zsh`.
``` Here's my zsh config - I'd like to remove oh-my-zsh and replace the provided functionality with just raw zsh. i use starship for my prompt so i don't need any help there.
--- CLAUDE RESPONSE --- Minimal Raw Zsh Replacement
```
Granted I've only done this like 5 minutes ago and might be missing functionality I'll realise later, but a quick few checks give me hope I have all the functionality I want.
zsh is still crazy to me. I use bash for everything. I have no idea what I’m missing out on.
FWIW, I still use bash as well. Nothing against zsh per-se, it's just that I know bash, bash works, and there's no particular pain I experience using bash that will obviously be solved by switching. And when you factor in anticipated switching costs, I haven't found any compelling reason to spend any significant time on zsh so far.
Maybe one day though.
Yes, I'll throw my hat into this group too. Bash is fine.
YMMV but I have found using zsh too frictitious to be helpful. Sure, theoretically zsh living in a bash world (lets face it, all scripts are bash) is completely fine but reality seems to differ. Copied a one liner from shell history into your script? Crash. Use arrays? Weird bugs. Use shell builtins? Whoa unexpected interactivity!!! Etc...
Bash is absolutely fine as a default shell. As an added benefit, you don't feel like an invalid once logged in to a container or server.
I've been using it for the last 6 or 7 years and I can only remember one specific feature I use a lot: "unset HISTFILE" to disable history when I need to run commands with passwords.
Other than that, oh-my-zsh with git, systemd, and fzf plugins. Saves a lot of typing.
The main selling point for me is how easy it is to setup.
Just out of curiosity, what sort of typing do those plugins save in comparison to doing it in bash? Can you give some examples?
1 reply →
Space before the command will have the same effect
I remember when I switched to zsh solely for SUNKEYBOARDHACK.
Prefixing a space on that command will keep it out of history.
I don't think it is crazy, but I know and love the bash quirks. I've got permanent history setup thanks to Eli Bandersky [1] which I know zsh has a solution to already. But what annoys me with zsh is some of the ways it tab completes when navigating the filesystem, and not by default allowing comments on the command line, e.g. '# github api key blahblahblah', which I can then pull later using phgrep.
Slight pain on a mac to get the latest version and use it as terminal shell, but it gets easier everytime I work on a fresh mac.
[1]: https://eli.thegreenplace.net/2013/06/11/keeping-persistent-...
If you want vi history editing like you are used to in bash for the last 20 years it's subtly different in a manner that makes it insanity inducing. If you use the traditional emacs like editing it's much the same.
Oh that’s good. I’m an emacs guy. I don’t like change.
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'm changing to GhosTTY as we speak (from Mac Terminal, because I'm tired of gemini-cli not getting my shift-return for newlines). Wasn't until that process that I learned that new Mac accounts are on a different shell (zsh) than I have (bash). Last time I switched shells was when Apple flipped from tcsh.
Now, I'm deep down the rabbit hole of standardizing all my shells/terminals/configs with Nix. Either a really good or really bad project to start on a Friday night.
It's basically the same, except smarter about command history and auto-completion by default. I'm sure you could get Bash to act the same way with a bit of prodding.
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.
You can replace nvm with https://mise.jdx.dev/ , it starts effectively instantly and works not only for node versions but all programming languages and tools.
`mise use node@latest`
or asdf
3 replies →
I am seeing a phenomenon of people wanting to hyper optimise their workflows. It’s nonsensical when you consider the other stuff you need to do or how slow everything else is.
Holy heck, I just profiled my zsh initialization and nvm was the big source of bloat, holy hell. Similar setup as you (M4 MBP), same amount of startup bloat. Lazy loading it fixes it.
GPT-5.2 changed the nvm initialization script to:
That's why I switched to Mise (https://mise.jdx.dev). Having new terminal sessions taking up hundreds of milliseconds because of nvm isn't the end of the world, but it's annoying when you're in the middle of something.
Mise reads in your .nvmrc files so you don't have to configure anything new.
Although this is what Opus recommends, it will give you many issues as you don’t really have any node runtimes in the path (or worse if you do).
What I recommend is replacing it with $PATH=(a command to find the nvm default alias directory, detect the verion and load it from that specific version directory directly) so you always have default node in path and then lazy loading only nvm itself, so you can switch when you need to.
Sorry I don’t have the command handy as I’m on mobile but if you paste the above into Opus you’ll get it.
1 reply →
..have you checked. It's 0.04s in my setup. I have it a bit customized but I don't remember chasing milliseconds on config
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 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
> 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
Some of those are the equivalent of a single C source file.
We wouldn't celebrate a C project for specifically holding down to say, 10 source files max. We'd celebrate it separating concerns well instead.
Right. A lot of people when they say "minimal" mean "simple looking at first glance", and it rarely is.
In case the authors sees that, your default shell is configured via [0]:
[0]: https://search.nixos.org/options?channel=unstable&show=users...
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?
My zsh config has three things:
The first one is mentioned in `git-prompt.sh` that comes with git, which needs to be sourced as well.
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.
https://github.com/romkatv/zsh4humans
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.
Current branch without bloat is to cat .git/HEAD, and if that didn't exist, run git symbolic-ref HEAD. The first is faster and works in the common case where you're in the top of a git repo. In either case, run it through ${branch##*/} to strip down to just the current branch.
I have used this for a long time, never understood how people would put all of git in between them and the next prompt.
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
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.
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.
Are we really quibbling over 400ms startup delay to open a new terminal?
Yes! The very famous xz hack was only found, because a German wondered why his ssh session lagged 200 ms at the start. Everyone should go mad when their main tool lags a few hundred milliseconds. It is unacceptable that we sit on machines, that run billions of calculations per second and our software still lags.
Yes, and hundreds of developers just spent 5 minutes reading about it.
This investment makes sense for OP who opens hundreds of terminal sessions, but does it make sense to bother about 1s delay when they start the terminal session once in a while? I have several sessions opened all the time, the last time I wasted my 1s on zsh was in 2025 when I rebooted my machine due to a nvidia drivers update.
400ms is a ton if you have a terminal centric workflow with short lived shells.
HN has gone on a decade long crusade against Electron, of course 400ms is a lot.
Of course. We're nerds. You should have seen the passionate discourse, a couple days ago, for Brave browser saving 45MB of memory!
400ms here, 400ms there, and before you know it, you're dead. I've switched terminal emulator and upgraded computers for less.
I have these plugins: git, zsh-autosuggestions
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.
FWIW, that’s not a great way to benchmark zsh.
Check out zsh-bench⁽¹⁾ for a more authoritative approach, including first prompt lag, first command lag, input lag and exit lag.
⁽¹⁾ https://github.com/romkatv/zsh-bench
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.
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 ….´
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.
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.
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.
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.
What plugin?
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.
https://stackoverflow.com/a/25876379
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.
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
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
Had this problem awhile ago of my zsh startup being slow. Just opened claude code and told it to benchmark my shell start and then optimize it. Took like 5 minutes and now it's ultra fast. Hardly any idea what it did exactly but worked great.
Like others I don't use too many of the features but Oh-My-Zsh is so easy to install.
Even better recently I discovered that FreeBSD has a package for it!
`pkg install ohmyzsh` and 5 seconds later it's ready. Plus I figure it's a bit more secure and insulated to any ohmyzsh breaches.
I have a fast machine, never noticed a difference in shell start up time between with and without and given how much more pleasant it is with I'll take the hit.
I had my phase of having a fancy shell with all bells and whistles. I’ve now settled with the default terminal so that 1. It is fast, 2. Whereever I work, I have the same experience.
I don't use it because I'm tired of having one package manager per tool you want to use. I can handle a simpler shell configuration.
I have not a small number of plugins on fish and I've never noticed a problem with startup time. I do wish there was a better way of managing or installing plugins. It just feels so fragile.
I am just glad that it is sub-second start time, where with powershell, it was upwards of multiple seconds
The tips in the article on enabling vi mode and fzf keybind are worth the read imho
I've discovered plugins zsh-autosuggestions and fzf (available out of the box) and OH MY ZSH am I impressed with my quality of life improvement.
For me the bloat is acceptable since it saves so much time and JustWorks (Tm)
I agree. And you probably neither need Omarchy, CachyOS, etc. Choose boring and get peace of mind.
CachyOS is basically arch on easy mode. I used to spend countless hours tinkering with arch but then I got older and don’t have much time. Plus there are helpful meta packages for gaming that work great out of the box, which for a gamer like me sans Windows is pretty awesome.
I've tinkered at most an hour on my arch install and it's just been running smoothly. The installer these days is easy to go through as well. It's the same for bash, very little customization, then it runs smoothly for years.
I'm not saying CachyOS is bad, just that it is in my opinion another layer of complexity that may change/deprecate/etc.
1 reply →
>I used to spend countless hours tinkering with arch but then I got older and don’t have much time.
Have your lost your old configs that you worked hard on? That's a shame if so. I love moving my configs I've worked hard on to new machines and instantly getting up and running in a now-familiar environment. It saves so much time and effort.
I was annoyed by this enough that I ended up cloning the OMZ repository locally, and stripping out all the modules I don’t use. And now I just have it as part of my dotfiles[1].
It's just a handful of files and I manually source them in my zshrc[2]:
It's essentially the same as omz setup I was using before, but loads in just ~25ms (Note: it's on a hard drive, with ddr3 ram and 18ms out of that is spent by compinit)
It also fixed another issue I had with Oh-My-Zsh: whenever they (very rarely) tweak their default config - it breaks my muscle memory.
[1] https://codeberg.org/janAkali/dotfiles/src/branch/main/confi...
[2] https://codeberg.org/janAkali/dotfiles/src/branch/main/zshrc
> affects shell startup time
You'll never get back those milliseconds. Just like I can't get back the time I wasted reading this article.
Shaving milliseconds off of terminal load time seems like a silly thing to optimize for. I notice omz takes a brief moment but it’s never bothered me.
Switching from OMZ shaves a few ms on my very fast desktop machine. It shaves seconds of SSHing into a heavily loaded server.
I switched to Prezto because of how slow OMZ is, been really happy with it. At one point it started causing issues with the IntelliJ environment reader but it’s been perfect once I sorted that out.
I think they are just doing something wrong. Why people are upvoting this nonsense
Am I the only one that uses ohmyposh with fish? I have a killer custom posh theme that I’ve been using for years and the performance is fantastic.
At some point you need to remove the training wheels, otherwise you'll never learn to ride the bike.
At first, you need them. You'll fall without it. But if you still rely on them after a while, it's not a good sign.
> My workflows involve opening and closing up to hundreds of terminal or tmux tabs a day. I do everything from the terminal. Just imagine that opening a new tab in a text editor would take half a second every time.
This sounds like overoptimization on a neglible time loss for what is essentially an unique (and dare I say: broken?) workflow.
I use terminals a lot ... but I work with 4-5 day-persistent terminals that I open once a day and keep in the background. The QoL effects of omz outweigh microtuning startup times significantly.
Well yeah, you need antibody https://getantibody.github.io/ and then whatever plugins you desire. Been using it for years and it's never been anything other than fast and reliable.
Why antibody and not any of the 60 alternatives? Is it truly the best among them or is your choice sub-optimal?
Thinking about that I realized I prefer not to use any plugin manager at all.
I mean it's not like I've done any formal benchmarks but like I've used a bunch of plug-in managers and antidote, sorry antibody is the old one, it's just so much faster than all the others.
github says in maintenance since 2022 and that users should move to next great thing, antidote
Oh shit you're right it is actually antidote, God why do they have to name them the same things. Even their websites are similar.
I may not need this sort of shell bling. And I don't use it. But my first Unix system was an early version of Xenix, which had the original Bourne shell that didn't even support cursor up to get a previous command. (I do use cursor up, C-r, and the shell editing commands.)
But yesterday's conveniences become today's essentials, and those who came in after me have their expectations set by the much more sophisticated things available at the time. Like, I'm still flabbergasted by people—working professionals—who go "I can't program without syntax highlighting, autocomplete, and my IDE generally going bing bing wahoo at me as I work, and I don't know how anybody can." We just type the code in. Like we all had to back in the day.
Anyway I can certainly see where someone younger than about 35, or who came to Linux late, would be completely at sixes and sevens without their colorized racing-stripes shell prompt.
“Still gangsta” I mutter to myself as I syntax-highlight punchcard #818 by hand and Port-a-Punch a replacement.
Prezto is faster than OMZ, and has been for over a decade. Starship is faster still. I switched from using Prezto standalone to using Prezto + Starship and relying primarily on Starship several years ago. I'd be surprised if many people are still using Oh My ZSH in 2026 vs using Prezto, anyway.
zsh4humans is even faster than Prezto, according to their benchmarks. that’s what I’m using daily.
I use fish now instead, honestly a nicer shell and shell language all around.
Slightly off topic but:
>> My workflows involve opening and closing up to hundreds of terminal or tmux tabs a day.
What?!?
Should have been titled "I probably don't need Oh My Zsh because of my weird niche tab workflow" but that's a lot less clickbaity.
This thread feels so foreign to me. I use basic ass vanilla Windows terminal. It’s fine. I also use the vanilla built-in to VSCode terminal. It is also fine.
Terminals are such a small, unimportant part of my job I barely even think about them.
Yes, Windows users don't have time for such luxuries when they're constantly fighting a losing fight with an increasingly hostile OS. Playing whack-a-mole dismissing ads, dismissing Edge and reopening links in your preferred browser, waiting for React to render in the start menu, coping with the ever increasing theft of personal data, and on and on and on the list goes. The rest of the time is spent on working around Windows oddities that other developers using sensible OSes simply don't need to deal with. No wonder there's no time to think about anything else.
I also use Linux and Mac. And sometimes a little bit of Android.
Win11 Pro is also fine. I spend radically less time fighting Windows than I spend fighting Linux userspace disfunction.
Conversely, I spend about 60% of my working day in the terminal, with another 20% in Zed. Wild how much workflows differ, isn’t it?
You probably don't need zsh. POSIX shells are holding us back.
Show me an environment where I can interact with my system programmatically, where I can compose together arbitrary tools, and which will never, ever, ever break on me, and I'll switch! My experience with graphical environments has been that they rarely compose, often break, and constantly make arbitrary changes that break my workflow. So every time I try something else I end up coming back to the terminal.
But I agree that terminal environments have serious shortcomings. I think it's a real shame we haven't created anything else that does what the terminal does, and I think it's mostly for lack of trying.
https://fishshell.com/ https://xon.sh/ https://www.nushell.sh/ https://elv.sh/
You're replying to someone that says POSIX shells are holding people back, not that the terminal is a bad idea, there are many alternative shells which offer benefits over POSIX shells. fish-shell has everything you want from an interactive shell included, xonsh is a mix Python shell, nushell and elvish are adding types and other things to shell.
The VT protocols that all shells have to confirm with are pretty dated and I'd love to throw them off the roof for something less stateful and with multiple font sizes but there's no arguing that text based interfaces are good.
3 replies →
> I think it's a real shame we haven't created anything else that does what the terminal does, and I think it's mostly for lack of trying
I'd rather just take terminals a step forward, which I agree hasn't happened due to a lack of trying. But the people who aren't trying are the people who are instead tricking out zsh with plugins. I'm a nushell fan myself but my point here is not
> try nushell
but rather,
> be willing to try things that aren't backwards compatible with `sh`
If more people relaxed on that sticking point, we could actually benefit from the excellent post-POSIX work that has been done. As it is, people are reluctant to try new shells for some reason.
Nushell. Still a terminal experience. But not a POSIX one. https://www.nushell.sh/
2 replies →