Terminal Tools I Actually Use

Abstract generated cover for Terminal Tools I Actually Use.

The terminal is one of those places where it is easy to overbuild. You can spend days customizing prompts, aliases, panes, themes, keybindings, and shell plugins. Some of that is useful. A lot of it is decoration. The tools I care about most are the ones that make daily development faster:

  • finding files
  • searching text
  • reading JSON
  • navigating projects
  • working with Git
  • running repeatable project commands The terminal should help you move through a project without making the setup fragile.

The Mental Model

A good terminal setup should make common commands shorter, faster, and less error-prone. It should not require you to remember a private language of aliases that only works on one machine. I like tools that are:

  • easy to install
  • easy to explain
  • useful across many projects
  • scriptable when needed
  • not tied to one editor That is why simple command line tools often beat larger systems.

`rg` for Searching Text

`rg`, or ripgrep, is one of the first tools I install. It searches text quickly and respects `.gitignore` by default. Examples:

rg "NOTION_BLOG_DATABASE_ID"
rg "class Product"
rg "TODO"

You can search specific file types:

rg "def sync" -t py
rg "useEffect" -t ts

This is useful in almost every codebase. If I need to understand where a setting is loaded, where a function is called, or where an error message comes from, `rg` is usually the first command.

`fd` for Finding Files

`fd` is a friendlier file finder. Examples:

fd notion
fd .md content
fd dev-start

It is faster and nicer to use than many basic `find` commands for day-to-day work. I still use `find` when I need portable shell scripting, but for interactive work, `fd` is easier.

`jq` for JSON

APIs, config files, and command outputs often involve JSON. `jq` makes JSON readable and searchable. Example:

cat package.json | jq ".scripts"

Or:

curl https://example.com/api/data | jq ".items[] | .name"

Even if you only know a little `jq`, it is worth having. Pretty-printing JSON alone is enough to save time.

`fzf` for Fuzzy Picking

`fzf` is a fuzzy finder for the terminal. It can be used for files, command history, Git branches, and custom scripts. One simple use:

git branch | fzf

More advanced shell integrations can let you search command history or jump through directories. The value is speed. If you know part of what you want, fuzzy search gets you there without typing the exact full name.

Git From the Terminal

I prefer understanding Git in the terminal even when an editor or desktop app has Git features. The core commands are enough for a lot of work:

git status
git diff
git add path/to/file
git commit -m "message"
git pull
git push

Two commands matter especially:

git status
git diff

`git status` tells you what changed. `git diff` shows what changed. Those two commands prevent a lot of accidental commits.

Project Scripts

One of the best terminal habits is giving projects obvious scripts. Examples:

./dev-start.sh
npm run dev
npm run build
python manage.py test

A good project script hides boring setup details without hiding the whole system. For example, a development start script might:

  • create a virtual environment
  • install dependencies
  • sync content if credentials exist
  • build static files
  • start a local server That is useful because the project becomes easier to run on a second machine.

Shell Aliases

Aliases can be useful, but I keep them modest. Examples:

alias gs="git status"
alias gd="git diff"
alias ll="ls -la"

The danger is building a private shell language that makes you helpless on a new machine. Aliases should save typing, not replace understanding.

Common Mistakes

Mistake 1: Customizing before using

It is easy to customize a terminal for workflows you do not actually have yet. Use the plain tools first. Customize once a pattern repeats.

Mistake 2: Hiding important commands behind unclear aliases

Aliases like `deploy-prod-now` can be dangerous if you forget exactly what they do. For important commands, clarity matters more than shortness.

Mistake 3: Depending on tools that are not documented

If a project needs a tool, document it. Otherwise the project works on your machine and fails everywhere else.

Where This Shows Up in Real Projects

Terminal tools are especially useful when debugging. If a site fails to build, I want to search config files, inspect scripts, check Git state, and run commands directly. If a Notion sync fails, I want to find the environment variable loader, inspect error messages, and reproduce the failing command. If images are missing, I want to locate source assets and build outputs quickly. The terminal is not separate from development work. It is where a lot of real debugging happens.

Key Takeaways

  • `rg`, `fd`, `jq`, and `fzf` are small tools with a lot of daily value.
  • `git status` and `git diff` should become habits.
  • Project scripts make projects easier to run on other machines.
  • Keep aliases simple and understandable.
  • Customize the terminal around real repeated work.

    Related Articles

  • Setting Up a Mac for Development

  • My Neovim Setup for Python, Go, and TypeScript
  • Git Branching Explained: Feature Branch to Master

← Back to Blog Index