Building the Ultimate Developer Shell

Building the Ultimate Developer Shell

Modern development workflows increasingly live inside the terminal. With the right tooling, your shell becomes a fast, expressive, and deeply ergonomic environment—far beyond what the default macOS setup provides.

In this guide, we’ll build a state-of-the-art developer shell on macOS using the following tools:

  • fish – User-friendly, smart, interactive shell
  • oh-my-posh – Beautiful, information-rich prompts
  • zoxide – Smarter cd navigation
  • fzf – Lightning-fast fuzzy finder
  • eza – Modern replacement for ls
  • bat – Syntax-highlighting cat alternative
  • lazygit – Terminal-native Git UI
  • yazi – Ultra-fast terminal file manager
  • LazyVim – Neovim preconfigured as a full-fledged IDE
  • Ghostty – GPU-accelerated terminal for macOS (and Linux)

By the end of this post, you’ll have an extremely productive terminal environment optimized for coding, navigation, version control, and file management.


1. Base Setup: Ghostty Terminal + Fish Shell

Ghostty is a modern terminal emulator that is fast, GPU-accelerated, and highly configurable. It pairs beautifully with fish, which provides smart defaults, autosuggestions, and a much smoother user experience than bash or zsh.

Install fish

brew install fish

Add fish to valid shells:

echo /opt/homebrew/bin/fish | sudo tee -a /etc/shells
chsh -s /opt/homebrew/bin/fish

Enable fish for Ghostty

Ghostty will automatically pick up your default shell.
Optionally configure font, themes, and keybindings in:

~/Library/Application Support/com.mitchellh.ghostty/config

2. Add a Powerful Prompt with Oh My Posh

A meaningful prompt surfaces context: Git branch, Kubernetes context, execution time, error codes, etc. Oh My Posh is cross-platform and beautifully customizable.

Install:

brew install jandedobbeleer/oh-my-posh/oh-my-posh

Activate in fish:

Add to ~/.config/fish/config.fish:

oh-my-posh init fish --config ~/.poshthemes/yourtheme.json | source

Pick a theme:

oh-my-posh get themes

I recommend starting with jandedobbeleerparadox, or bubbletea.


3. Smarter Navigation with Zoxide

zoxide replaces cd by learning which directories you visit most often and jumping there instantly.

Install:

brew install zoxide

Fish integration:

zoxide init fish | source

Now navigation becomes:

z myproject
z src
z ~/dev/ai

Zoxide also integrates with fzf:

zi  # interactive directory jump

4. Fuzzy Finding Everything with FZF

fzf adds fuzzy search to directory jumping, Git history, command history, file navigation, and more.

Install:

brew install fzf

Run setup:

$(brew --prefix)/opt/fzf/install

Useful keybindings (fish)

Add to config.fish:

# CTRL+R: fuzzy search command history
bind \cr '__fzf_history'

You now have frictionless interactive search everywhere.


5. Modern CLI Replacements: eza and bat

eza (ls replacement)

brew install eza

Define useful aliases:

alias ls="eza --icons auto"
alias ll="eza -l --git --icons"
alias lt="eza --tree --icons"

bat (cat on steroids)

brew install bat

bat brings syntax highlighting, paging, line numbers, and Git integration.

Combine it with fzf:

fzf --preview 'bat --style=numbers --color=always {}'

6. Terminal File Manager: Yazi

Yazi is a blazing-fast, TUI-based file manager with previews, tabs, and excellent navigation.

brew install yazi

Launch it from anywhere:

y

For fish convenience:

alias yy="yazi"

Yazi integrates nicely with zoxide and fzf indirectly, giving you instant exploration of deep directory structures.


7. Git Superpowers with Lazygit

Lazygit is one of the most impactful CLI tools for developers. It gives you a mouse-free UI for:

  • staging/unstaging
  • resolving merge conflicts
  • browsing logs
  • managing branches
  • viewing diffs

Install:

brew install lazygit

Run:

lazygit

Add an alias:

alias lg="lazygit"

8. Neovim as a Full IDE with LazyVim

LazyVim turns Neovim into a powerful IDE with:

  • LSP (TypeScript, Go, Rust, Python, etc.)
  • Treesitter
  • Git signs
  • Debug adapters
  • File explorer
  • Telescope fuzzy search
  • Beautiful UI

Installation

brew install neovim

Backup existing config:

mv ~/.config/nvim ~/.config/nvim.bak

Install LazyVim starter:

git clone https://github.com/LazyVim/starter ~/.config/nvim
cd ~/.config/nvim && rm -rf .git

Start Neovim:

nvim

LazyVim will install all plugins automatically.

Integrate with the ecosystem

  • Telescope uses fzf for fuzzy finding
  • LazyVim shortcuts align well with yazi + zoxide navigation
  • Lazygit integrates via plugins like kdheepak/lazygit.nvim

Your terminal becomes a complete development cockpit.


9. Putting It All Together

At this point, your developer shell includes:

  • Ghostty: fast, GPU-accelerated terminal
  • fish: smart, interactive shell
  • oh-my-posh: information-dense prompt
  • zoxide: intelligent directory jumping
  • fzf: fuzzy searching everywhere
  • eza + bat: modern file and content tools
  • yazi: fast file manager
  • lazygit: powerful Git UI
  • LazyVim: a full development IDE inside the terminal

A typical workflow becomes:

z project           # instantly jump to a repo
yy                  # inspect directories with yazi
nvim .              # open repo in LazyVim
lg                  # manage Git with lazygit

or:

fzf                 # find any file
bat file.txt        # preview contents
lt                  # browse structure with eza tree view

Every part of the stack is designed for speed, clarity, and minimal friction.


Absolutely — here’s a clean, production-ready dotfiles section plus a complete config.fish tailored to the toolchain you’re using (fish, zoxide, fzf, oh-my-posh, bat, eza, yazi, lazygit, LazyVim).
Everything is macOS + Ghostty friendly.


10. Dotfile Snippets for the Developer Shell

These snippets can be dropped into your dotfiles repository (e.g., ~/.config/fish/config.fish~/.config/ghostty/config~/.config/nvim/init.lua, etc.) or symlinked using GNU stow and stored in Github which I highly recommend.

fish configuration — ~/.config/fish/config.fish

Full file is provided below in section “Complete config.fish”.

It includes:

  • oh-my-posh prompt init
  • fzf keybindings
  • zoxide integration
  • aliases for eza, bat, lazygit, yazi
  • environment improvements
  • Neovim defaults

Ghostty Config — ~/Library/Application Support/com.mitchellh.ghostty/config

Example:

font-family = "JetBrainsMono Nerd Font"
font-size = 13.0
theme = "TokyoNight"
cursor-style = "block"
background-opacity = 0.92
keybind = ["ctrl+shift+t=new_tab", "ctrl+shift+w=close_tab"]

Ghostty reloads configs automatically.

Yazi Config — ~/.config/yazi/yazi.toml

[preview]
wrap = true
tab_size = 2
max_size = 5_000_000

[manager]
show_hidden = true

bat Config — ~/.config/bat/config

--theme="TwoDark"
--style="numbers,changes,header"

eza aliases — placed in fish config or ~/.config/fish/conf.d/eza.fish

alias ls="eza --icons"
alias ll="eza -l --git --icons"
alias la="eza -la --git --icons"
alias lt="eza --tree --icons --git"

lazygit Config — ~/Library/Application Support/lazygit/config.yml

git:
  paging:
    colorArg: always
    pager: delta --dark --paging=never

(Requires brew install git-delta)

Zoxide + FZF directory jumper — optional helper script

~/.config/fish/functions/cd.fish:

function cd
    if test (count $argv) -eq 0
        z
    else
        z $argv
    end
end

This makes cd behave like z.


11. Complete config.fish — Ready to Use

Below is a fully structured, clean, and portable config.fish tailored around your stack.

You can copy/paste it as-is.

~/.config/fish/config.fish

# -----------------------------------------------------------
#  Fish Shell Configuration — The Ultimate Dev Shell
#  macOS + Ghostty + LazyVim + yazi + lazygit
# -----------------------------------------------------------

# ----- PATH Setup -----------------------------------------------------------
set -Ux PATH /opt/homebrew/bin $PATH
set -Ux PATH ~/.local/bin $PATH

# ----- Oh My Posh Prompt ----------------------------------------------------
if type -q oh-my-posh
    oh-my-posh init fish --config ~/.poshthemes/jandedobbeleer.omp.json | source
end

# ----- Zoxide (smarter cd) --------------------------------------------------
if type -q zoxide
    zoxide init fish | source
end

# ----- FZF Integration ------------------------------------------------------
if type -q fzf
    # History search: CTRL+R
    bind \cr '__fzf_history'
end

# FZF Defaults (ripgrep + bat)
set -Ux FZF_DEFAULT_COMMAND "rg --files --hidden --follow --glob '!.git/*'"
set -Ux FZF_CTRL_T_COMMAND $FZF_DEFAULT_COMMAND
set -Ux FZF_DEFAULT_OPTS "--height=80% --layout=reverse --border"
set -Ux FZF_PREVIEW_COMMAND "bat --color=always --style=numbers --line-range=:200 {}"

# ----- eza aliases (modern ls) ---------------------------------------------
if type -q eza
    alias ls="eza --icons"
    alias ll="eza -l --git --icons"
    alias la="eza -la --git --icons"
    alias lt="eza --tree --icons --git"
end

# ----- bat alias (modern cat) ----------------------------------------------
if type -q bat
    alias cat="bat"
end

# ----- lazygit alias --------------------------------------------------------
if type -q lazygit
    alias lg="lazygit"
end

# ----- yazi alias -----------------------------------------------------------
if type -q yazi
    alias yy="yazi"
end

# ----- Neovim as default editor --------------------------------------------
set -Ux EDITOR nvim
set -Ux VISUAL nvim
alias vi="nvim"
alias vim="nvim"

# ----- macOS Specifics ------------------------------------------------------
# Fix Homebrew issues with fish
fish_add_path /opt/homebrew/bin
fish_add_path /opt/homebrew/sbin

# Enable colored man pages (via bat)
if type -q bat
    set -gx MANPAGER "sh -c 'col -bx | bat -l man -p'"
end

# ----- Git quality-of-life --------------------------------------------------
set -gx GIT_EDITOR nvim

# ----- Helpful functions ----------------------------------------------------
function mkcd
    mkdir -p $argv[1]
    cd $argv[1]
end

function fzf-open
    set file (fzf --preview "bat --style=numbers --color=always {}")
    if test -n "$file"
        nvim "$file"
    end
end

# -----------------------------------------------------------
# End of config
# -----------------------------------------------------------

12. Final Thoughts

Building a highly productive terminal environment isn’t about adding random tools—it’s about making your CLI feel natural, fluid, and joyful to use. With this setup on macOS using Ghostty, you get a modern, unified experience that dramatically improves navigation, coding, file exploration, Git workflows, and shell interaction.

This is the kind of terminal setup that grows with you over time and becomes an essential part of your developer workflow.