My developer workflow using WSL, tmux, and VSCode

Technology

On this page
  1. Terminal
  2. Shell
    1. Prompt
  3. CLI tools
    1. Lazygit
    2. Eza
    3. GitHub CLI
    4. Tmux
    5. nvm
    6. Zsh plugins
  4. Editor
    1. Extensions

Windows Terminal

WSL (opens in a new tab) has made development on Windows machines much better.
Especially with the release of WSL 2 it is now easier and faster than ever.

This post documents my workflows and tools for software development on Windows.
I will update it whenever I find a better way to do something.

I use the Ubuntu distribution for WSL. This is also the OS I use (or derivations thereof: PopOS) when I’m on Linux.

For configuration of the mentioned tools, look at my dotfiles (opens in a new tab).

Love finding new tools? Check out my tool stack!

Terminal

Windows Terminal (opens in a new tab) is a non-negotiable for me. I have not found a better terminal emulator for Windows.
It has tabs, great customizability, and it’s pretty powerful.

Recently, I have been exploring Warp Terminal (opens in a new tab). You have to run it through WSL (currently: no Windows build), which isn’t as nice as running it natively.
It’s a great terminal emulator and has a lot of features that makes the experience more powerful and enjoyable.
I could point to individual features, but what makes Warp great is how all features combined makes it feel. It’s just good.

I use a Nerd Font (opens in a new tab) called Caskaydia Cove Mono in the terminal.
I switch between the Campbell and One Half Dark themes.

Shell

I use Z Shell, aka. zsh.

Managing zsh can get kind of trivial, so like Oh My Zsh (opens in a new tab) has been essential to my workflow.
It makes configuration (opens in a new tab) and plugin management easy.

Prompt

I was a huge fan of Powerlevel10k for Zsh, but moved to Starship (opens in a new tab) because it has a clean and minimal default look.
Starship is very easy to set up and provides a nice developer experience in my opinion.

CLI tools

I use an array of CLI tools to make me more effective. Here’s a rapid-fire list:

Lazygit

This is my favorite way of interacting with git. My git capabilities and speed has probably 10x’ed after I started using it.

I have configured my Lazygit to work with git-delta (opens in a new tab) and commitizen (opens in a new tab).

Jesse Duffield, the creator of Lazygit, made a great video showcasing 15 features in 15 minutes (opens in a new tab). I highly recommend that you watch it to see how it might accelerate your workflow.

I even made a tool called bunnai (opens in a new tab) for having ai write commit messages for me in lazygit. It’s been very useful!

Git-delta is a great tool for visualizing changes.

Commitizen helps me write conventional commits (opens in a new tab), which is makes it easier to manage versions with semantic release (opens in a new tab) when creating either node packages, Obsidian plugins, and other software where it makes sense to use that kind of versioning.

Eza

Great replacement for ls.

I use a few aliases here:

alias ls="eza --icons --git"
alias l='eza -alg --color=always --group-directories-first --git'
alias ll='eza -aliSgh --color=always --group-directories-first --icons --header --long --git'
alias lt='eza -@alT --color=always --git'
alias llt="eza --oneline --tree --icons --git-ignore"
alias lr='eza -alg --sort=modified --color=always --group-directories-first --git'

To install, use cargo (opens in a new tab) and do cargo install eza.

GitHub CLI

I mainly use this to create and configure repos.
Often also do gh repo view --web to open the repo in my browser.

  • gh repo create to create a new repo. --private to make it private.
  • gh repo view --web to open the repo in the browser.
  • gh repo clone <repo> to clone a repo, e.g. gh repo clone chhoumann/dotfiles. No need to prepend your own username to the repo name (given you own the repo).
  • gh pr merge -d to merge the PR for the branch you are in and delete the branch.

One of my most time-saving combinations comes into play when I’m initializing a new repository.

# Make project folder and cd in
mkdir project1 && cd project1
# Initialize new git repository
git init

# Many project-starters like `npx create-next-app@latest` will create a folder for you
# And sometimes even init a git repo. That's why the command below is great.

# Create a new GitHub repository and push local repo up
gh repo create project1 --private --source=. --remote=upstream

# Alternatively, if you just want gh to create an empty repo and clone it to a folder:
gh repo create project1 --private --clone

Tmux

I’m still learning tmux, but even the basics have accelerated my workflow.

Creating and killing panes, splitting panes, and switching between them is very fast and easy.

This seriously helps when, e.g. you are running npm run dev in one pane, but need to commit something.
You don’t want to stop the dev server, so you just split the pane and commit in the new pane.

nvm

I basically just do nvm alias default lts/gallium (current LTS version). This sets the default node version.

nvm use --lts or nvm install --lts is very helpful.

Sometimes you want to play around with other versions (e.g. latest or previous), so it helps with that as well.

Zsh plugins

I’m using the following plugins:

If you choose nothing else, I highly recommend zsh-z. It’s a game changer.
You can CD into a directory from anywhere by just writing part of it.

For example, z dot takes me to my dotfiles folder, no matter where I am.
It learns from your usage, so it gets better over time.

Editor

I have been using Visual Studio Code (opens in a new tab) as my editor for a long time.

Recently, I have been moving towards using Cursor (opens in a new tab), which is VSCode, but completely integrated with AI. Given how much LLMs empower my workflows, this has been a great change. No switching to ChatGPT to ask questions and then back to VSCode. Just ask directly in Cursor. Copilot++ in Cursor is fantastic as well.

I’ve dabbled in Neovim (opens in a new tab), but decided I’d rather spend my time doing other things than tweaking my Neovim config.
I have a tendency to fall into rabbit holes, especially ones that look like shiny new tools.

Using VS Code is a good way to get a lot of functionality without having to spend a lot of time configuring it.
This also makes setup much easier when switching computers.

I do have some settings and keybindings that I prefer. You can find those in my dotfiles (opens in a new tab).

Extensions

I use the following extensions:

And language specific extensions for the languages I use.

I use GitHub Dark (opens in a new tab) as my primary theme. I’ve also taken a liking to poimandres (opens in a new tab) and poimandres-alternate (opens in a new tab).

Search and commands

Keyboard shortcuts

Go to

gh Home
gb Blog
gl Books
ga About
gn Newsletter
gt Tools

Move

jk Next / previous item — or scroll
hl Left / right in the book grid
du Half page down / up
gg First item · top
G Last item · bottom
Open focused item
Open in new tab

Search

/ Search — books filter or palette
K Command palette
? This panel
esc Close · cancel · blur