I could spend hours figuring out all those things, bit I'd rather use that time for something more important.
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.
$ hyperfine -N "zsh -lc 'exit 0'" "zsh -c 'exit 0'"
Benchmark 1: zsh -lc 'exit 0'
Time (mean ± σ): 54.5 ms ± 6.3 ms [User: 10.2 ms, System: 14.3 ms]
Range (min … max): 38.1 ms … 64.9 ms 78 runs
Benchmark 2: zsh -c 'exit 0' Time (mean ± σ): 6.5 ms ± 1.4 ms [User: 0.8 ms, System: 1.3 ms]
Range (min … max): 3.9 ms … 14.2 ms 424 runs
It's crazy how their startup time is 380 ms, and I suspect something else might be the reason, not just oh-my-zshWowsers!
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!
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.
Simple, sensible defaults.
Ships with the Arch Linux installation ISO.
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.
There's quite a few things the OP's post didn't mention about shell history that I think are really important:
setopt HIST_IGNORE_ALL_DUPS # Never add duplicate entries.
setopt HIST_IGNORE_SPACE # Ignore commands that start with a space.
setopt HIST_REDUCE_BLANKS # Remove unnecessary blank lines.
It's possible to roll your own prompt that does helpful things without using starship.Also you can roll your own zsh plugin manager in a few lines of shell scripts, `fast-syntax-highlighting` is a really useful plugin to get real-time feedback when typing commands.
Most of those things are mentioned here https://nickjanetakis.com/blog/i-recently-switched-to-zsh-an..., the post is 5 years old but just about all of that is what I do today still. Since then it has evolved to become better IMO, including using a dedicated Vim zsh plugin which is much improved over the default zsh key binds. Also another plugin to show zsh's tab complete in fzf instead of zsh's window. The tab complete demo video is here https://nickjanetakis.com/blog/hooking-up-fzf-with-zsh-tab-c....
I 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 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
This feels like a strange hang up to me.
Oh My Zsh is more sluggish than benching zsh -ic 'exit 0' would suggest. This benchmark will show command lag among other things, which is very noticeable on a slower computer. https://github.com/romkatv/zsh-bench
I use https://github.com/romkatv/zsh4humans. I installed it once, took an hour or two to tweak it to my liking, and haven't touched it since. It's in maintenance mode so I'm not worried about my zshrc breaking randomly. I have transient git prompt, autosuggestions, autocomplete, syntax highlighting, vim mode, a whole bunch of added functions and line editor additions, and my terminal opens in one frame. It feels more like an extension of my mind than a tool I'm interacting with. OMZ by comparison, feels like typing over a slow ssh connection.
How do you get to hundreds?
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.
Bigger fish to fry if we're being practical.
Anyway, yeah, all of this adds startup and command invocation time, but the value far outweighs the latency.
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)" ```
cargo install starship --locked
downloads 336 packages. So much for "minimal". cargo is the new npm
For nixos users: https://discourse.nixos.org/t/using-zsh-with-grml-config-and...
Super easy to setup, and works very well
users.users.yourUser.shell = pkgs.fish;
[0]: https://search.nixos.org/options?channel=unstable&show=users...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.
setopt PROMPT_SUBST ; PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '
bindkey "^R" history-incremental-search-backward
autoload -Uz compinit && compinit
The first one is mentioned in `git-prompt.sh` that comes with git, which needs to be sourced as well.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.
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.
Some quick troubleshooting many years ago narrowed the vast majority of the problem down to the git plugin, especially for large, old repos.
I disabled the git plugin and everything has been fine ever since.
Figured I'd dig deeper and bring back the current branch name without the bloat at some point, but it hasn't bothered me enough to do it.
I describe my setup and how to use it on a fresh MacBook here: https://github.com/agrounds/dotfiles
For some reason it was slow to load which I found annoying, so I used Claude Code to optimize it. In the end I ended up removing Oh My ZSH entirely, now I have a single .zshrc file that contains everything, and it became much faster.
Similarly I moved from Packer to Lazy.nvim and updated a number of libraries, and from iTerm to Ghostty, Claude Code essentially converted my configs in a matter of minutes
This 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.
After a few months with lazyvim I'm missing barebones nvim. Batteries included is nice but requires maniacal restraint.
/usr/bin/time -f "%e seconds" zsh -i -c exit
0.06 seconds
This is acceptable, maybe the zsh-autocomplete is the problem for author or something else?I originally switched to ZSH + Oh My Shell because it opens so fast. Ideally plugins would initialize asynchronously but it's not very easy with shell scripts I think.
I 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.
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 ….´
~150ms with minimal setup is good enough for me, although I would prefer <50ms.
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.
This can be disabled fairly trivially. I then alias the update command to a homebrew update alias.
Shameless plug: I wrote a detailed git prompt in C which is similar to posh-git on Powershell: https://github.com/mahesh-hegde/promptsynth
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.
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.
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.
time zsh -i -c exit
zsh -i -c exit 0.12s user 0.09s system 81% cpu 0.276 total
~It's just a handful of files and I manually source them in my zshrc[2]:
source $ZSH/lib/async_prompt.zsh
source $ZSH/lib/key-bindings.zsh
source $ZSH/lib/completion.zsh
source $ZSH/lib/history.zsh
source $ZSH/lib/git.zsh
source $ZSH/lib/theme-and-appearance.zsh
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
Terminals are such a small, unimportant part of my job I barely even think about them.
You'll never get back those milliseconds. Just like I can't get back the time I wasted reading this article.
/usr/bin/time -f "%e seconds" zsh -i -c exit
0.04 seconds
I think they are just doing something wrong. Why people are upvoting this nonsense>> My workflows involve opening and closing up to hundreds of terminal or tmux tabs a day.
What?!?