My developer workflow using WSL, tmux, and VSCode
8 November, 2022 | 6 min read
WSL 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.
Windows Terminal 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.
I use a Nerd Font called Caskaydia Cove Mono in the terminal. I switch between the Campbell and One Half Dark themes.
I use Z Shell, aka.
I was a huge fan of Powerlevel10k for Zsh, but moved to Starship 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.
I use an array of CLI tools to make me more effective. Here's a rapid-fire list:
- Lazygit for accelerated git workflow
- Exa as a better
- gh (GitHub CLI) for faster GitHub workflow
- tmux for awesome multi-tasking in the terminal
- nvm to manage node versions
- Multiple Zsh plugins (see below)
- Lazydocker for accelerated docker workflow
- Brew for package management
- Act for running GitHub Actions locally. Save yourself the painful embarrasment of pushing ** commits and waiting for CI to fail while you're figuring out how to do X and Y in your CI
- Ni so I don't have to care whether I'm in a Yarn / NPM / pnpm project
This is my favorite way of interacting with git. My git capabilities and speed has probably 10x'ed after I started using it.
Jesse Duffield, the creator of Lazygit, made a great video showcasing 15 features in 15 minutes. I highly recommend that you watch it to see how it might accelerate your workflow.
Git-delta is a great tool for visualizing changes.
Commitizen helps me write conventional commits, which is makes it easier to manage versions with semantic release when creating either node packages, Obsidian plugins, and other software where it makes sense to use that kind of versioning.
- Install Lazygit: GitHub - jesseduffield/lazygit: simple terminal UI for git commands
- Install git-delta: Use cargo and do
cargo install git-delta.
- Install commitizen: Use a node version manager to install node and do
npm install -g commitizen.
Great replacement for
I use a few aliases here:
alias ll="exa --long --group --icons --git --header" alias llt="exa --oneline --tree --icons --git-ignore" alias ls="exa --icons --git"
To install, use cargo and do
cargo install exa.
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 createto create a new repo.
--privateto make it private.
gh repo view --webto 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 -dto 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
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.
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.
I'm using the following plugins:
- git adds nice git aliases, but I prefer Lazygit now
- zsh-z so you can jump around directories much faster
- gh adds completion for the gh cli
- rust adds completion for the rust compiler, rustup, and cargo
- zsh-autosuggestions adds autosuggestions
- tmux adds QoL features for using zsh & tmux together.
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.
z dot takes me to my dotfiles folder, no matter where I am.
It learns from your usage, so it gets better over time.
I use Visual Studio Code as my editor.
I've dabbled in Neovim, 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 use the following extensions:
- Vim, becase I find it greatly improves my efficiency.
- Error Lens, because it makes it easier to spot errors. Can lead to clutter, though.
- GitHub Copilot is a serious productivity game-changer, especially when using frameworks or languages you aren't used to.
- Tailwind CSS Intellisense is great for working with Tailwind CSS.
- Import Cost is great for spotting when you are importing too much.
- ESLint in combination with...
- Prettier for formatting.
- ES7+ React/Redux/GraphQL/React-Native snippets, mostly for React snippets.
- vscode-icons for nice icons.
- WSL for working in VS Code through WSL.
- GitHub Pull Requests and Issues for working with GitHub PRs and issues. Great in combination with the
And language specific extensions for the languages I use.