Introduction
Let’s be honest: the default terminal experience on macOS and Linux is… rough. Like, really rough. You open Terminal.app on a Mac and you’re greeted with this bland, uninspiring blank rectangle that feels like it was designed in 2003 (spoiler: it basically was). The default shell prompt tells you almost nothing useful, the colors make reading logs an eye-straining nightmare, and don’t even get me started on trying to split panes or manage multiple sessions.

My palette of choice


My preferred font: Fira Code
Talking about consistency, I love having matching fonts in all my daily tools. A good monospace font might seem like a minor detail, but when you’re staring at code for hours, it makes a real difference. Fira Code has been my go-to for years. It’s a free, open-source monospaced font designed specifically for developers, and its killer feature is ligatures. You know how operators like->, <=, !=, or === are technically multiple characters but represent single logical concepts? Fira Code renders them as unified glyphs. It sounds gimmicky until you try it. Suddenly your code just looks cleaner and is easier to scan.
But here’s the thing: if you want fancy icons in your terminal prompt (git branch symbols, folder icons, language logos), you need more than just Fira Code. You need the Nerd Font version.
Nerd Fonts is a project that patches popular programming fonts with thousands of additional glyphs from icon sets like Font Awesome, Devicons, Octicons, and Powerline symbols. The Fira Code Nerd Font gives you all the ligature goodness plus the icons that make modern shell prompts and file explorers look gorgeous.
Installing is straightforward:
Other solid options
Fira Code isn’t the only game in town. Here are some other excellent monospace fonts worth considering:- JetBrains Mono - Created by JetBrains, excellent ligatures and optimized for reading code. Very popular.
- Ubuntu Mono - Clean and highly readable, the default on Ubuntu systems.
- Cascadia Code - Microsoft’s modern font with ligatures, designed for Windows Terminal.
- Source Code Pro - Adobe’s take on a programming font, clean and professional.
- Hack - Designed for source code, great readability at small sizes.
GhostTTY: The Terminal that finally gets it right
Ghostty is a fast, feature-rich, and cross-platform terminal emulator that uses platform-native UI and GPU acceleration. It was created by Mitchell Hashimoto who co-founded Hashicorp and is definitely worth a follow!~/.config/ghostty/themes/.
which shell?
Now that we have a proper terminal emulator, let’s make what happens inside it actually useful.
fish
fish (friendly interactive shell) is my shell of choice. It’s actively maintained and is a modern alternative tobash or zsh that prioritizes usability out of the box. It comes with syntax highlighting, intelligent autosuggestions from your command history, and robust tab completions without any configuration.
Installing and switching to fish is straightforward:
fish over zsh within Ghostty:
bash. For me, the improved interactive experience is worth it, and I can always run bash -c "command" for POSIX-specific scripts when needed.
My whole
config.fish file: See on GithubZsh: The macOS default
If you prefer to stick with something more traditional, Zsh has been the default shell on macOS since Catalina. You’re probably already using it if you’re on a Mac. Zsh offers better tab completion than Bash, more powerful globbing, shared history across sessions, and a massive ecosystem of plugins and themes through frameworks like Oh My Zsh. It’s a solid choice if you want something more powerful than Bash while maintaining POSIX compatibility. On Ubuntu or other Linux distros still running Bash, switching to Zsh is easy:My whole
.zshrc file: See on GithubStarship: A prompt that actually helps
Your shell prompt is prime real estate. The defaultusername@hostname:~$ tells you almost nothing useful. Starship fixes that.
Starship is a minimal, blazing-fast prompt written in Rust. It automatically detects what you’re working on and shows relevant context: git branch and status, current language versions, cloud provider profiles, Kubernetes context or whatever’s relevant to your current directory.
~/.config/fish/config.fish):
~/.zshrc instead:
~/.config/starship.toml.

devcenter project/folder on the my-terminal git branch with unstaged changes ([?]). It shows my package.json version (1.0.0) as well as my node.js runtime version. Especially useful if you are switching node versions with nvm to get rid of compatibility issues between major releases.
Here’s my whole config:
Some modules may take too long to evaluate. If the prompt, feel sluggish, run
env STARSHIP_LOG=trace starship timings to get a detailed trace of the execution.
eza: ls, but actually good
The defaultls command is… fine. But eza is better in every way. It’s a modern replacement with colors, icons, git status integration, and sensible defaults.
ls to eza so it’s automatic. In fish, add this to your ~/.config/fish/config.fish:
~/.zshrc):

ls gives you a beautiful, informative file listing. lt shows a tree view with git status. Once you’ve used it, going back to plain ls feels painful.
fzf: Fuzzy find everything
fzf is a general-purpose fuzzy finder, and once you start using it, you’ll wonder how you ever lived without it. It lets you interactively filter any list: files, command history, processes, git branches, you name it.- Ctrl+R - Fuzzy search through your command history (game changer)
- Ctrl+T - Fuzzy find files and insert the path
- Alt+C - Fuzzy find directories and cd into them

zoxide: cd that remembers
zoxide is a smartercd command. It tracks which directories you visit most frequently and lets you jump to them with minimal typing.
cd ~/projects/company/frontend/src/components, you just type z components and zoxide figures out which “components” directory you probably mean based on your history. The more you use it, the smarter it gets.

zi opens a fuzzy finder with your most-visited directories.
My aliases
Beyond the tool-specific aliases above, here are some shortcuts I use constantly. In fish:~/.zshrc instead.
The philosophy here is simple: if you type something more than a few times a day, alias it. Your fingers will thank you.
Bonus: Nushell
If you’re feeling adventurous and want to try something completely different, check out Nushell. It’s a modern shell that treats everything as structured data instead of text strings. Instead of piping text throughgrep and awk and hoping you got the parsing right, Nu pipelines work with actual typed data. You can work with JSON, YAML, SQLite, even Excel files natively. Error messages actually tell you what went wrong and where.

NeoVim + LazyVim: When you need real editing power

nvim and let it install all the plugins. First startup takes a minute, but after that it’s instant.
The best resource I’ve found for getting started is this video by Elijah Manor:
It walks you through the LazyVim setup and the essential keybindings you need to be productive. Bookmark it, you’ll reference it often in your first few weeks.
A few tips for the learning phase:
- Start with
:Tutor- NeoVim has a built-in tutorial. Run it. Actually do the exercises. - Use Vim keybindings in your regular editor first - Both VS Code and JetBrains IDEs have excellent Vim plugins. Build muscle memory without sacrificing productivity.
- Don’t try to learn everything at once - Master
hjklnavigation, thenw/b/efor word movement, then gradually add more. - Keep a cheat sheet handy - You’ll need it for months. That’s normal.
Claude Code: Your AI Programmer Buddy in the Terminal

claude in any project directory, authenticate, and you’re good to go.
Pro tip: create a
CLAUDE.md file in your project root describing your codebase and conventions. Review my other article on the topic for a detailed walkthrough.Integrating with NeoVim
claude-code.nvim brings Claude Code directly into NeoVim. Add this to your LazyVim config:<leader>ac and Claude Code pops up in a floating window. When it makes changes to files, NeoVim automatically reloads them. The workflow is seamless: edit, toggle Claude, describe what you need, watch it work, and you’re back to editing with changes already applied. No context switching.
If you’re using a different AI assistant (or want to use multiple), check out avante.nvim. It’s a Cursor-like experience for NeoVim that supports Claude, GPT, Gemini, and local models.
Conclusion
Look, I’m not going to tell you this is the “perfect” setup or the “only” way to configure your terminal. There’s no such thing. Your workflow is different from mine, your muscle memory is different, and what drives you crazy might not bother me at all. But what I will tell you is this: investing time in your terminal setup is absolutely worth it. You’re going to spend thousands of hours in this environment over your career. Making it fast, pleasant, and actually helpful isn’t being picky. It’s being smart. And I love the occasional “Oh wait. How did you do that?”You can find all my configurations on my dotfiles Github repository.