Create custom shell commands
If you type the same long command more than a few times a day, you're paying a tax you don't need to pay.
The problem
Some commands in your daily workflow are long: a cd into a deeply nested project path, a docker run with ten flags, a git command you never remember the exact syntax for. You type it once, it works, and then you type the same thing again tomorrow. And the day after.
Each time costs a few seconds and a chance to typo a path. That's not a big deal once. Multiply it by every day you work on that project, and it adds up to real friction for zero benefit — you already know what the command does.
Alias it
The fix is a shell alias: a short name that expands to the full command. Instead of cd /path/to/your/first/project, you type project-1. The shell does the substitution before running anything, so the alias behaves exactly like typing the long version yourself.
This works the same way in bash and zsh, since both read alias definitions from a startup file.
How to set one up
0. Back up your config file first
cp ~/.zshrc ~/.zshrc.backup
Use ~/.bashrc if you're on bash. You're about to edit a file that runs every time you open a terminal — a backup means a bad edit costs you a revert, not a broken shell.
1. Open the config file
nano ~/.zshrc
Again, ~/.bashrc for bash. Any editor works — nano, vim, whatever you're comfortable with.
2. Add the alias
At the end of the file:
alias project-1='cd /path/to/your/first/project'
alias project-2='cd /path/to/your/second/project'
Replace the paths with your actual project directories. The pattern is alias name='command' — anything you can run in the terminal can go on the right side.
3. Enable autocompletion (zsh only)
autoload -U compinit && compinit
Without this, zsh won't tab-complete arguments after your alias the way it does for built-in commands.
4. Reload the config
Save the file, then:
source ~/.zshrc
This applies the change to your current session without needing to open a new terminal.
Where aliases fall short
Aliases are static text substitution — they don't take arguments the way a function does. alias greet='echo hello' works, but you can't call greet world and expect world to slot in anywhere. If you need a command that takes input and does something conditional with it, you want a shell function, not an alias.
The other failure mode is aliasing too much. If you rename every command you use into something project-specific, you'll eventually forget the real syntax, which hurts the moment you're on a machine without your dotfiles. Alias the things you type often and verbatim — long paths, multi-flag invocations, commands with a syntax you never fully memorized. Leave the rest alone.
The result
A handful of aliases in your shell config turns a recurring, error-prone keystroke sequence into a two-word command. It's a small change, but it's one you benefit from every single time you open a terminal — which, if you're doing this kind of work, is a lot.