Supercharge Your Terminal: The Fast Path to Shipping Code in 2024
Frederick Mannings
Your terminal shouldn't be a bottleneck to shipping code. Yet for many engineers, wrestling with terminal configuration is! But doing so wastes precious development time that could be spent deploying features.
Today, we're removing that barrier. By the end of this guide, you'll have a terminal setup that gets you back to developing and helps you ship code faster, not slower.
Ship Now, Configure Later
Short on time? I get it - you've got code to ship. I've packaged up my entire battle-tested configuration into a CLI that you can deploy in seconds:
curl -o setup.sh https://raw.githubusercontent.com/Solvicode/term-config/refs/heads/main/setup.sh \
&& chmod +x setup.sh && ./setup.sh
God speed.
Your Terminal, Your Rules
The most productive terminal setup is the one that matches your workflow. Every high-velocity developer I've worked with has customised their terminal to remove friction from their development process. While starting from scratch is admirable, it's not always practical when you need to ship features today.
This guide gives you a production ready foundation you can build on - let's get started.
Picking a Terminal
Here is my stance on terminals:
- Only use Windows Powershell if you absolutely need to
- Don't use Windows cmd - it's not worth the headache
- Use a Unix based terminal wherever possible
If you're in Mac OS, I would always suggest using iTerm.
For Windows, I would suggest first installing Windows Subsystem for Linux (WSL2). Then, to launch straight into your Linux instance, I use Windows Terminal. The combination of WSL2 and Windows Terminal will be enough for you to forget that you are using Windows. As for the Linux version to install, choose the latest Ubuntu LTS (Long Term Support) - it's low fuss and will get you progressing quicker.
If you're in a native Linux distro, checkout this discussion on terminal emulators.
The Shell
Let's upgrade your shell from bash to zsh with Oh-my-zsh - a game-changing enhancement that transforms your terminal from a basic command line into a powerfuld development tool.
Oh-my-zsh isn't just another shell - it's your partner in rapid development. Here's how it will help you ship faster:
- Smart Command Completion: While bash makes you type out full commands, zsh predicts what you need. As you type, it suggests commands, paths, and options based on your history - meaning less time typing, more time shipping.
- Shared Command History: Your command history follows you across all terminal windows, with smart search capabilities. No more retyping that complex deployment command you used yesterday - just search and execute.
- Rich Plugin Ecosystem: Oh-my-zsh plugins will give you the syntactic sugar you're looking for when working with any tool
The best part? Zsh maintains compatibility with your existing bash scripts, so you can upgrade without breaking your current deployment workflows.
To install zsh and Oh-my-zsh run the following commands from within your terminal:
sudo apt install zsh
sh -c "$(curl -fsSL \
https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
Then to make available some advanced autosuggestions and highlighting to Oh-my-zsh, add the following packages:
git clone https://github.com/zsh-users/zsh-autosuggestions.git \
$ZSH_CUSTOM/plugins/zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git \
$ZSH_CUSTOM/plugins/zsh-syntax-highlighting
We will enable these plugins later.
Version Control
Rule 1 of shipping fast: Don't loose your progress. So let's get your terminal configuration into version control.
First create a git repo for storing your zsh config:
mkdir ~/git/zsh-config -p
Now, move your ~/.zshrc
into this directory, whilst also creating a symbolic link to the file:
mv ~/.zshrc ~/git/zsh-config && ln -s ~/git/zsh-config/.zshrc ~/.zshrc
Now, when zsh starts up, it will run the ~/.zshrc
file to load in your configuration - but with
the functionality proxied to the ~/git/zsh-config/.zshrc
file due to the symbolic link.
Whilst we're here, let's configure git inside our ~/.zshrc
. You'll thank me later:
export GIT_EDITOR="vim"
echo "machine github.com login $GITHUB_USER password $GITHUB_TOKEN" > ~/.netrc
chmod 600 ~/.netrc
I like to use vim as my git editor. Set to 'nano' if you prefer.
Configuration
Now the fun begins. There are suite of things that we're going to install and configure:
- Private environment variables - secrets that you're most likely going to need. I will show you how I keep these away from version control
- Aliases - short hand references to more complex commands
- Utility commands - to perform custom tasks such as aiding in navigation to common directories
Private Environment Variables
Environment variables like $GITHUB_USER
and $GITHUB_TOKEN
should be kept far away from
version control. To do this I put them in a seperate ~/.private_envs
file. You can then source this
file from within your ~/git/term-config/.zshrc
file.
Lets do this now:
touch ~/.private_envs # create the file
echo "export GITHUB_USER=<your github user name>" >> ~/.private_envs # set github username
echo "export GITHUB_TOKEN=<your github token>" >> ~/.private_envs # set github token
echo ". ~/.private_envs" >> ~/.zshrc # will redirect to the version controlled .zsh because of the symbolic link
We've now got a system that allows us to stash environment variables consistently, and load them on boot, whilst keeping them away from version control. Nice.
Functions
Now for a utility function that I use daily:
slap()
{
cd ~/git/"$@";
};
slap
allows me to easily navigate to folders within my ~/git/
directory. E.g. I can do
the following kind of operations:
slap solvicode # takes me to ~/git/solvicode
slap solvicode/term-config # takes me to ~/git/solvicode/term-config
Don't under estimate the impact that navigating between projects has on your speed to production.
Here are some docker related functions I use here and there:
# stop and remove all docker containers
docker_rm_all() {
docker stop $(docker ps -aq)
docker rm $(docker ps -aq)
}
This one helps me detox after a busy dev cycle:
# stop, remove and delete all docker containers, images and volumes. Use with caution.
docker_nuke() {
docker_rm_all
docker network prune -f
docker rmi -f $(docker images --filter dangling=true -qa)
docker volume rm $(docker volume ls --filter dangling=true -q)
docker rmi -f $(docker images -qa)
}
Oh-my-zsh Config
Now, we inject our Oh-my-zsh configuration:
plugins=(
git
zsh-autosuggestions
zsh-syntax-highlighting
)
source $ZSH/oh-my-zsh.sh
These plugins provide nice features for the various apps that I configure and use. I have not covered additional
tools (such as Node, Python and Go!), but if you include them as plugins, ensure that they are on the
$PATH
prior to this step.
Use plugins sparingly as they will slow down initialisation.
Aliases
And last but not least - aliases. I place aliases at the end of my configuration as there are certain default aliases that come with Oh-my-zsh that I like to overwrite.
I have built up this set of aliases over years of using the full commands, to the point that I get fed up typing them out all the time, so I shove them into an alias.
I would say this is the best way to learn shorthand forms of commands - by suffering with the longer form for long enough that you can't bear using them any more.
BUT - you are short on time and you need to ship. So, here are my aliases. I have structured them so they are somewhat semantically sensible. E.g.:
"Git push to the upstream origin" translates to gpsuo
"Git push, force but with lease" translates to gpsfwl
And so on. Treat these as a base set and extend them with your own encantations:
# General aliases
alias cl='clear'
alias ls='ls -lah --color=auto'
alias grep='grep --color=auto'
alias open="explorer.exe" # WSL specific
alias nvim='~/nvim-linux64/bin/nvim'
# Git aliases
alias gcaa='git commit --amend --no-edit'
alias gacaa='git commit -a --amend --no-edit'
alias gls='git log --oneline -n10'
alias gst='git status'
alias gps='git push'
alias gpsf='git rev-parse --abbrev-ref HEAD | gps origin -f'
alias gpsfwl='git rev-parse --abbrev-ref HEAD | gps origin --force-with-lease'
alias gcm='git commit -m $@'
alias gpl='git pull'
alias gfp='git fetch -p'
alias gckm='git checkout main'
alias gpsuo='git push --set-upstream origin $(git rev-parse --abbrev-ref HEAD)'
And That's It! Time to Ship Faster
You've just removed one of the biggest friction points in the deployment pipeline - terminal inefficiency.
With this setup, you're ready to:
- Switch between projects at lightning speed
- Interact with git seamlessly through custom aliases
- Track updates to your terminal configuration
- Start shipping faster than ever before
No more fighting with your terminal. Just pure, friction-free development velocity.
If you're looking for more ways to speed up your deployment process, check out my other resources.
You might just find what you're looking for.