Setting up your new machine - A simple dev environment configuration guide
Published at 2024-09-02
Updated at 2024-12-20
Licensed under CC BY-NC-SA 4.0
unix
windows
terminal
productivity
software-engineering
configuration
tool
Table of Content
- Why Development Environment Configuration Matters
- Network Configuration: The First Step
- Client-Side Configuration: Windows, macOS, and Linux
- Adding a User Account
- Choosing the Right Font
- Terminal, Console & Terminal Emulator: Beyond the Basics
- Shell: The Bridge Between You and the System Kernel
- Package Managers: The App Store for Developers
- Gsudo: A Third Party sudo for Windows
- TLDR: A Quick & Dirty Manual
- Vim & VS Code: The Two Editors
- Version Control of the Environment
- Dotfiles: Persisting your App Configurations
- Server Side Configuration: Linux Is Your Best Friend
- SSH: Connecting to the Server with Ease
- Summary
As developers, we interact with all kinds of machines every day. A well-configured development environment can significantly boost productivity and make coding more enjoyable. This comprehensive guide will help you set up a comfortable and efficient workspace. It's mainly for beginners, but experienced developers may also find some useful tips.
Why Development Environment Configuration Matters
When I started coding, my terminal was a stark black and white window that failed to inspire creativity. Now, my terminal is colorful, feature-rich, and a joy to use. This transformation is just one example of how proper configuration can enhance your coding experience.
Terminal configuration is just one part of the larger concept of development environment configuration. These configurations can be complex, but this guide tries to provide a road map for beginners. This guide will not be a step-by-step tutorial, meaning I will not show you how to download and install the individual applications. You can refer to the official websites to learn how to install and use these applications in detail.
This post is inspired by:
Network Configuration: The First Step
Before diving into development environment setup, ensure your network is functioning correctly. You'll need a stable Internet connection to download various tools and packages.
You may need a proxy for a better Internet connection.
When you open your proxy software and turn on the "System Proxy" option, your browser reads this configuration and automatically applies it so that your web traffic is routed through the proxy server. However, this is not the case for our terminal tools - they generally don't read the system proxy settings automatically, instead they read some proxy-related environment variables. So to use the proxy in your terminal environment, you need to set these environment variables.
Usually you can find a "Copy Environment Variables" button in your proxy software to copy the above commands to set the environment variables. If your proxy is running on 127.0.0.1:7890
, the command to set the environment variables might look like this:
export https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7890
Tip
If you are using a WSL, you will need to do some configuration to make it accessible to your proxy on Windows. Please edit the .wslconfig
file in your user directory and add the following lines:
[wsl2]
networkingMode=mirrored
autoProxy=true
For details, please refer to:
Also see:
Client-Side Configuration: Windows, macOS, and Linux
When I say "client side", I mean the local machine you are using, i.e. your PC or Mac.
On a Mac, you must use macOS, while on a PC, you can use Windows or Linux. Most configurations on a Unix-like operating system (like macOS or Linux) are similar, while they may vary on Windows. As developers, we use Unix-like systems (most of which are Linux) much more than Windows. However, as a beginner in the IT field (e.g. a Chinese CS student), you may only have a PC running Windows.
In this guide, I will respect that by trying to make your Windows a little more "Unix-like". Here I am referring to a pure Windows environment and not a virtual machine (such as VMWare or WSL).
Tip
Although this article mentions some ways to make Windows more “Unix-like”, I still recommend that, if you can, you should use WSL and configure it according to the general approach mentioned in this article applicable to Linux or Unix. The benefits of doing so are at least twofold:
- avoidance of some Windows-specific problems
- better performance (for some reason, the same configuration on Windows is not nearly as good as on other platforms)
Adding a User Account
This section is for Linux users only. When you install a new Linux system, you may only have a root
account. It is not recommended to use the root
account for daily work, as it is too powerful and can cause serious problems if you make a mistake. It's recommended that you create a new user account and use it instead.
Tip
If you are using WSL, you will be asked for a username and password when you first start up. In that case, you can skip this step.
See:
You can create a new account with the following command (replace username
with your desired username)
useradd -m username
The useradd
command is a POSIX-compliant command that creates a new user account. The -m
flag creates a home directory for the new user. After running this command, you can use the passwd
command to set a password for the new user. You may also want to make the new user a sudoer, which can be done by adding the user to the sudo
group:
usermod -a -G sudo username
Tip
Depending on your distribution, the name of the default sudo user group is not the same. The sudo
group mentioned above is Debian-based, while in Arch Linux the name of this user group is wheel
.
Or you can edit the sudoers file manually by running visudo
.
If you are using Ubuntu, you can use the adduser
command instead. Follow the instructions it gives and enjoy a more user friendly experience:
adduser username # add a new user with name "username"
adduser username sudo # make the new user a sudoer
Choosing the Right Font
A good programming font can make a world of difference. Look for fonts with features like:
- Mono spacing
- Easily distinguishable characters (so that you can easily tell the difference between
1
,l
andI
,O
and0
, etc.) - Ligature support (Optional)
Moreover, a font collection called "Nerd Fonts" provides many patched fonts with icons, which are very useful in the terminal.
The FiraCode Nerd Font
is my favorite. Give it a try!
Terminal, Console & Terminal Emulator: Beyond the Basics
You may have heard the term "terminal" or "console" before. These pronouns are from the old days when computers were huge and expensive. There might be one computer in an entire building. Terminals would be placed in different rooms in the building so that people could interact with that computer. The terminal is a text-based interface, and the console is a physical device.
Another concept is the TTY, which originally referred to a teletypewriter, a device that allowed a user to enter commands through a keyboard and view the computer's output from a printer or monitor. In modern computing, TTY refers not only to traditional physical terminal devices, but also to software-emulated terminal interfaces. Each terminal device has a corresponding TTY device file on Unix/Linux systems, e.g., /dev/tty1
, /dev/pts/0
, and so on.
Related to this is the Pseudo Terminal (PTY), which is a pair of character devices, including a pseudo terminal master and a pseudo terminal slave. Pseudo TTYs are used to emulate terminal functions, enabling multiple users or processes to share the input and output of the same physical terminal. It is widely used in modern operating systems for terminal emulators, remote connections (e.g., SSH), and multiplexers (e.g., tmux), allowing users the flexibility to perform command-line operations.
While Terminal Emulator is software that emulates a terminal, it is basically a GUI application that looks like a terminal. Terminal windows in modern operating systems (such as GNOME Terminal, Konsole, etc.) fall into this category. When you use these terminal emulators, you are actually interacting with TTY and pseudo TTY interfaces.
Today, you can use these terms interchangeably in many contexts because their meanings have become blurred. I will use the term "terminal" here.
No matter what operating system you are using, you have a built-in terminal, e.g. Terminal.app
on Mac and Windows Terminal
on Windows. However, third-party options offer more features and customization. Consider:
Alacritty
is a cross-platform, high-performance and highly customizable terminal emulator. You can also use Alacritty
on Mac, but I prefer iTerm2
on Mac.
Here is my Alacritty
configuration file on Windows:
working_directory = "D:\\Documents"
[shell]
program = "C:\\Program Files\\Git\\bin\\bash.exe"
args = ["--login", "-i"]
[font]
bold = { family = "FiraCode Nerd Font Mono", style = "Bold" }
normal = { family = "FiraCode Nerd Font Mono", style = "Light" }
size = 12
offset = { x = 0, y = 4 }
[window]
dimensions = { columns = 80, lines = 30 }
padding = { x = 12, y = 12 }
A theme is a set of configurations that change the appearance of an application. You can use themes to make your terminal tools look better and be easier to use. For example, set colorscheme
in Vim. However, I prefer to set themes in the terminal emulator so that all terminal tools share a similar look. I use the Dracula
theme in both Alacritty
and iTerm2
. The Dracula
theme is also available in many other applications, such as VS Code and JetBrains IDEs. Shared themes make your development environment more consistent and aesthetically pleasing. In addition to Dracula
, catppuccin
is another theme I really like.
Shell: The Bridge Between You and the System Kernel
The program running in the terminal is called a shell. It is a bridge between the user and the system kernel. On most Linux, the default shell is bash
, while on macOS, it is zsh
. There are two shells on Windows, cmd
and PowerShell
.
I recommend using zsh
on all systems. You can view it as a super set of bash with more features. Here is my configuration, in which I:
- Use the
oh-my-zsh
framework to makezsh
configuration easier - Use the theme
powerlevel10k
to customize the command prompt - Use a lot of other plugins and configurations
For example, here is a simple function I use to enable or disable the proxy in zsh
:
proxy() {
if [[ "$1" == "--disable" ]]; then
unset https_proxy http_proxy all_proxy
echo "Proxy disabled"
elif [[ "$1" == "--check" ]]; then
if command -v wget &> /dev/null; then
wget --spider --proxy=on http://google.com -q -T 10
if [ $? -eq 0 ]; then
echo "Proxy is working"
else
echo "Proxy is not working"
fi
elif command -v curl &> /dev/null; then
curl --proxy http://127.0.0.1:7890 http://google.com -s -m 10 --connect-timeout 10
if [ $? -eq 0 ]; then
echo "Proxy is working"
else
echo "Proxy is not working"
fi
else
echo "Neither wget nor curl is installed, cannot check proxy"
fi
else
export https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7890
echo "Proxy enabled"
fi
}
In addition to the powerlevel10k
mentioned above for customizing your command prompt, you might also want to take a look at starship, a cross-platform cross-shell command prompt configuration tool written in Rust that performs very well.
Tip
The command prompt is actually defined via the environment variable named PS1
, see:
If you don't want to use zsh
since it needs some configurations, a good alternative is fish
. However, fish
is not POSIX-compliant, which means you may have some compatibility issues with some shell scripts. This is the reason why I prefer zsh
. But it's fine for beginners.
You have bash
installed on most unix-like systems and it's easy to install zsh
or fish
on those platform. But on Windows, it is a little bit tricky.
If you want to install bash
on Windows, you may use git bash
. It will be installed when you install git
, a popular version control system, on Windows. Furthermore, you can also use zsh
on Windows. The articles below may be helpful:
I haven't yet found a good way to install fish
on Windows. If you know how to do that, please let me know by leaving a comment or sending me an email.
Caution
Another thing you may need to attention is the character set used on your Windows platform. If you are a Chinese CS student using Chinese Windows, the default character set of your system is usually not UTF-8. So you may encounter a mojibake issue. You can add the lines to the very head of your ~/.zshrc
which enables UTF-8 in your terminal to fix this issue:
# Set Windows code page to 65001 (UTF-8).
if [[ "$OSTYPE" == "msys" ]]; then
chcp.com 65001 &> /dev/null
fi
After installing the shell you like, you can make it the default shell by running the following command (Unix-like systems only):
chsh -s $(which zsh)
As a side note on PowerShell, PowerShell
on Windows is a powerful shell, but its syntax is very different from bash
. If you want to use PowerShell
, I recommend you to use PowerShell Core
, which is a newer, cross-platform version. You will need to install this version yourself, see the official documentation below:
Then, go through some configurations (e.g. refer to My Configurations) to make it more suitable for your needs.
Package Managers: The App Store for Developers
A package manager basically plays the role of an app store. The term "package" means a bunch of files. An executable application is basically a bunch of files, so you can think of an application as a package.
With the help of package managers, you no longer have to go to the official website of a particular application, click on download and then install it, but with one line of simple commands.
On different versions of Linux there are different package managers, for example, the most popular package manager on Ubuntu is apt
, and on Arch it is pacman
. They are installed when the Linux systems are ready.
On the Mac, however, you need to download and install a package manager. The most popular one is Homebrew. Windows does not have a package manager either. You can download and install scoop
or choco
yourself.
The concept of "package manager" explained above is really dirty and loose. To be more precise, the above package managers are system-wide. There are many more package managers in various tech stacks. For example, npm
in node.js projects and cargo
in rust projects, etc.
Tip
For Chinese users, a common headache is the physical distance from the server, which leads to problems such as poor network signal and consequently slow download speeds, or even timeouts, and ultimately the inability to download packages properly using a package manager. In this case, in addition to using a proxy as mentioned above, you can also use a mirror site. In the past, we had to manually modify a bunch of configuration files for different package managers. But now you can use a tool called chsrc
.
Gsudo: A Third Party sudo
for Windows
This section is for Windows users only. sudo
is a command in Unix-like systems that allows you to run a command as the superuser. Windows does not have a sudo
command, but you can use gsudo
as an alternative.
A common use case is when you want to use choco
to install a package, you run a command like choco install xxx
, but you may get an error because you don't have permission to install the package. In this case, you can use gsudo !!
to run the command as an administrator. (The !!
is a shortcut in zsh
that means the last command.)
TLDR: A Quick & Dirty Manual
On Unix-like systems, you can use the man
command to see the manual for a command. However, the manual is usually too long and hard to understand. I just want to know the basic usage of the command, but man
gives much more information than I need.
The tldr-pages
project fills this need. Running tldr xxx
will give you examples of how to use the xxx
command, covering the most common use cases.
I recommend using the tealdeer
client, which is based on the tldr pages projects, but written in Rust. It is much faster than the original tldr
client.
Vim & VS Code: The Two Editors
I use Vim & VS Code every day. I use Vim for quick and small edits and VS Code for large projects. Even in VS Code, I'm using the Vim extension to enable the Vim key bindings.
My Vim configuration is here.
To make Vim the default editor on Ubuntu, you can run the following command as root:
update-alternatives --config editor # and select vim in the menu
Version Control of the Environment
Here I'm not talking about version control systems like git
, but the version of the software you are using. For example, you may have Node 20
installed on your machine, but your project requires Node 14
. How to switch among different versions of the same software quickly and efficiently? These tools can help:
- Java:
sdkman
, etc. - Node.js:
fnm
,n
,nvm
, etc. - Python:
uv
,pyenv
,conda
, etc. (I also wrote a blog post about this).
In addition to the software-specific version control tools mentioned above, you can also use tools like asdf
or mise
to manage multiple software versions. Here is an example of using mise
to manage multiple Node.js versions:
mise install node@22
mise install node@20
mise ls # list all installed versions
mise use -g node@20 # switch to Node 20 globally
node --version # -> v20.18.1
mise use -g node@22 # switch to Node 22 globally
node --version # -> v22.11.0
If you're using scoop
as your package manager on Windows, you can also use the scoop reset
command to quickly switch versions, and here's an example of using it to manage Python versions (from the official wiki):
scoop bucket add versions # add the 'versions' bucket if you haven't already
scoop install python27 python
python --version # -> Python 3.6.2
# switch to python 2.7.x
scoop reset python27
python --version # -> Python 2.7.13
# switch back (to 3.x)
scoop reset python
python --version # -> Python 3.6.2
Dotfiles: Persisting your App Configurations
Many programs on Unix-like systems use files with names beginning with .
as their configuration files. For example, .bashrc
for bash
and .vimrc
for vim
. So you can save these files somewhere (like a GitHub repo) and sync them to your new machine. If you search for dotfile
on GitHub, you will find many repositories with a similar name. See dotfiles.github.io for more information.
My dotfiles are here.
Server Side Configuration: Linux Is Your Best Friend
On servers, Linux is the most popular operating system. So, in general, all you need to do is copy your Linux-based client-side configurations to the server side.
SSH: Connecting to the Server with Ease
SSH (Secure SHell) is a network protocol that allows you to connect to a remote server securely. It is widely used in the IT industry. You can use the ssh
command on your local machine to connect to a server. For example:
ssh username@hostname
By default, you must enter the password each time you connect to the server. You can omit this annoying step by using SSH keys. To do this:
- Use the
ssh-keygen
command to generate a pair of keys on your local machine. Run the following command and press Enter:
ssh-keygen -t ed25519
- Use the
ssh-copy-id
command to copy the public key to the server.
ssh-copy-id username@hostname
You will be prompted to enter the password for the last time. You can then connect to the server without entering the password.
Note
Note: I put the section about SSH in the server-side configuration, but the commands we use here are supposed to be run on the client side.
Summary
Configuring an efficient development environment is an ongoing process. Over time, you will discover new tools and methods to further optimize your workflow. I hope this guide has provided you with a good starting point and helped make your development process more efficient and enjoyable. If you have any questions or suggestions, feel free to contact me via email. Have fun coding!