Developers spend a lot of time working in their terminal doing the following tasks:

Navigating the file system

Manipulating files (creating, updating, reading and deleting)

Running git commands

Running local servers

Running tests

And a lot more...

A great developer experience can be achieved for the above mentioned tasks using a combination of Zsh as well as Hyper. This article will explain how to optimally set things up to achieve just that.

Zsh

Zsh is a shell that is very similar to bash, but with a few enhancements. With a few configuration tweaks, this shell can be very powerful.

Installation

Zsh can be installed through homebrew.

bash 1 brew install zsh

Once, installed, you can switch the default shell used in your terminal by running the following command:

bash 1 chsh -s /bin/zsh

Now, you just need to close and re-open your terminal and then you should be running zsh.

Changing and Updating Zsh Config

Configuration for zsh is done in a .zshrc file found in your home directory (i.e. ~ ). Whenever a change is made in .zshrc and you'd like to see the changes applied to an already open terminal window, you need to run the source ~/.zshrc command to propagate the changes to the current terminal session. I've setup 2 aliases to make it easier to edit and update the zsh configuration:

bash 1 2 alias change = "code-insiders ~/.zshrc" 3 4 alias update = "source ~/.zshrc"

The above aliases can be added to the .zshrc file. With these aliases, the change command will open .zshrc in VS Code and then the update command will apply the new changes an active terminal session. It should noted that you can also simply open a new terminal tab/window to see the newly applied changes.

For a complete look at my Zsh configuration, you can take a look at this gist.

A lot of people like to use oh-my-zsh with Zsh since it facilitates the setup of themes as well as the addition of functionality through the oh-my-zsh plugin system. I've moved away from using oh-my-zsh as I've found that it comes along with a lot of bloat that I don't use.

Prompt

The prompt is the text that appears before writing out any command in the terminal. Using spaceship prompt with zsh shell, you are presented with a good set of information related to the directory your located in. Spaceship prompt can display the following information:

Directory name

git repository information (e.g. branch name, files changed, local branch out of date with remote, etc)

Current Node version

Red prompt character when last command fails

Package version (the one found in a package.json file)

file) and more

To install spaceship prompt run npm install -g spaceship-prompt . The command will automatically setup files on your file system as well as include some lines in the .zshrc file to load the spaceship prompt for every new terminal session.

Syntax Highlighting

zsh-syntax-highlighting allows for colors to be added to shell commands within zsh. Basically, this highlights actual commands in green while highlighting non-commands in red. This is useful to make sure what you are actually typing is a command.

To install zsh-syntax-highlighting, run the following commands:

bash 1 2 3 cd /usr/local/share/zsh 4 5 git clone https://github.com/zsh-users/zsh-syntax-highlighting.git 6 7 echo "source ${(q-)PWD} /zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" >> ${ZDOTDIR :- $HOME} /.zshrc

Run the update command mentioned previously or open a new terminal session to see syntax highlighting enabled for shell commands.

Directory Navigation

With zsh, you can install a z command which will allow you to quickly jump around commonly accessed directories. Using the z command followed by the name of a directory, you can navigate to a directory on your computer, no matter where the directory is nested in your file system (as long as you've previously accessed the file in the past). This saves you from navigating your computer's directory structure with the cd command.

The nice thing about the z command is that it does fuzzy matching, so you don't have to type the full name of a directory in order to be able to navigate to the directory.

In order to install the z command, create a z.sh file in the /usr/local/etc/profile.d directory on you computer (doesn't have to be in that directory, but by convention that's where you should place application-specific startup files). The contents of the z.sh file should be taken from the Github repo for the z command.

Then, all you need to do is add the following line to your .zshrc file:

bash 1 2 . /usr/local/etc/profile.d/z.sh

Folder and File Icons

Using Color LS, you're able to list the contents of a directory and display icons beside folder and file names. Its like your normal ls terminal command, except it includes icons. This helps to more quickly identify what content exists in a directory. Follow these instructions to install Color LS.

You're also able to customize the colors and icons used with Color LS. Personally, i've kept the default icons and have customized the colors using a dark_colors.yaml file. If you're interested in my custom set of colors, view this gist to see the contents of my dark_colors.yaml file.

The best way to work with Color LS is to set up an alias for l (list folder & file names only) and ll (list detailed information for folders & files) to display the contents of a directory. Here is my alias setup in my .zshrc configuration file.

bash 1 alias l = 'colorls --group-directories-first --almost-all' 2 alias ll = 'colorls --group-directories-first --almost-all --long'

Automatically Switch Node Versions

A lot of project directories contain a .nvmrc file which specifies which node version a project uses. The .nvmrc file works with nvm so a user can run the nvm use command to switch to the version of node specified in a .nvmrc file. However, an issue some developers run into is that they forget to manually run the nvm use command, which causes developers to be using a version of node that may not be compatible with the project they are working on.

Fortunately there is an easy way to automate this with zsh. Zsh gives users the ability to use hook functions to execute commands whenever certain shell actions occur. For example, we can run a script whenever the current working directory is changed in order to run the nvm use command if an .nvmrc file exists in the directory.

Here is the code to do just that (add this to your .zshrc file):

bash 1 2 autoload -U add-zsh-hook 3 4 load- nvmrc ( ) { 5 local node_version = " $( nvm version ) " 6 local nvmrc_path = " $( nvm_find_nvmrc ) " 7 8 9 if [ -n " $nvmrc_path " ] ; then 10 local nvmrc_node_version = $( nvm version " $( cat " ${nvmrc_path} " ) " ) 11 12 13 if [ " $nvmrc_node_version " = "N/A" ] ; then 14 15 nvm install 16 17 elif [ " $nvmrc_node_version " != " $node_version " ] ; then 18 19 nvm use 20 fi 21 22 elif [ " $node_version " != " $( nvm version default ) " ] ; then 23 echo "Reverting to nvm default version" 24 nvm use default 25 fi 26 } 27 28 add-zsh-hook chpwd load-nvmrc 29 load-nvmrc

Now any time you switch to a directory with a .nvmrc file, you will automatically switch to the node version specified in the .nvmcrc file.

Hyper Terminal

Hyper is a terminal app that's built with JavaScript using React for the UI and packaged with Electron to make it available as a desktop app across Mac, Windows, and Linux platforms. The best parts of Hyper are its UI, plugin system, and configurability. You can download Hyper from their website.

Configuration

The configuration of Hyper is done within a .hyper.js file found in your home directory. A quick way to edit this file is to open the Hyper app and then use the ⌘+, shortcut which will open .hyper.js in your default code editor.

The configuration file is where settings such as font size, colors, shells (e.g. bash, zsh, fish), and plugins can be configured. One important note is that plugins will overwrite your own config values specified in .hyper.js . For example, if you use a theme plugin which will set all the colors in your Hyper terminal, then all the colors you've specified in your .hyper.js will not take effect.

See this gist to view my current Hyper configuration.

Border

One of the first things that might stand out from my terminal setup is the border surrounding the terminal. This can be added by using the hyperborder plugin and the colors are specified in a hyperBorder config object in .hyper.js :

bash 1 hyperBorder: { 2 borderColors: [ '#1D976C' , '#93F9B9' ] , 3 blurredColors: [ '#177C59' , '#84E0A6' ] 4 } ,

Theming

There are many Hyper theme plugins (with a lot of them listed in the awesome-hyper repository. Personally, I'm using the hyper-night-owl theme since it matches the Night Owl theme I use in VS Code.

Tabs and Panes

Panes

You're able to split planes with ⌘+d (vertical panes) and ⌘+⇧+d (horizontal panes). I usually like to split panes when I want to do multiple things in the same project. For example, I might use one pane to compile assets and start a local web server, another pane to run tests, and then a third pane to run any other commands for the project.

Tabs

You're able to create new tabs using ⌘+t . I like to create new tabs to separate my terminal views between different projects.

In order to keep the tab title minimal, I only include the name of the current directory. To do this with Zsh, we can create a precmd function hook in our .zshrc file which will be executed before each prompt:

bash 1 2 function precmd ( ) { 3 window_title = " \\ 033]0; ${ PWD ## * / } \\ 007" 4 echo -ne " $window_title " 5 }

Terminal Performance

Hyper has recently updated their terminal to version 3 which comes with a major performance boost. This was for a long time one of the biggest problems with using Hyper since it relied on a DOM renderer which is inherently slow. This would cause the terminal to run slowly and crash when trying to run some CPU intensive commands. However, with the new renderer based on WebGL, the performance is greatly improved.

Hopefully this article has given you ideas on how to improve your terminal setup. If you have your own unique terminal setups that help improve your development experience I'd love to hear about them.