The perfect Windows 11 dev environment setup (with Wezterm, WSL2, and Neovim)

Nicholas D
9 min readDec 12, 2023
(DALL-E go brr)

So, there I was, just another 20 something feeling the total ineptitude of not being an utter Chad 10x dev who can move entire mountains with a singular vim motion. Will I ever get there? What will I need to sacrifice to get there? As it turns out… nothing! I will have my cake and eat it too! It took me a weekend to get just right so here I am, your Mosses coming down from the mountain to share my wisdom (accumulated googling).

Ehem, okay… now that that’s out of my system, lets begin!

NOTE: All 3 parts of this guide are independent of one another, meaning you do NOT need to be on windows to follow the Neovim set up or the Wezterm setup as both are available and valid on other systems.

Part 1 — Setting up WSL2

So, as it turns out the best Windows dev environment is Linux. Yep, it’s that simple. Apart from some things, overall a Linux environment allows you to have full access to the bash command line which enables you to solve complex tasks with a few commands and pipes. The downside though is that if you’re main OS is Linux you tend to miss out on a lot of creature comforts and software support… Introducing Windows Subsystem for Linux 2!!! WSL2 is the follow up to the success of WSL from Microsoft. They experimented with WSL which had its uses but, WSL2 takes this to a new level giving it’s users a nearly full Linux OS experience on Windows with complete integration into your Windows file system as well.

Okay enough background info, this IS a guide after all.

Step one, we need to get WLS2 on our system. Todo this, simply run the following command in CMD (command prompt):

OptionalFeatures.exe

This should open a window that will allow you to enable WSL on you system. Simply select and activate the “Windows Subsystem for Linux” option.

NOTE: Windows 10 OS’ will NOT be able to use WSL2 only WSL and as mentioned before that comes with some major tradeoffs. I highly suggest you upgrade to Windows 11.

Now that WSL is enabled on your system, we need to install a Linux OS. There are two ways todo this. Via the command line or via the Microsoft store. To make this as simple as possible we will be doing it via the Microsoft store as via the CLI we can encounter a few snags.

Simply open up “Microsoft Store” on your system by searching it in the start menu. Then search at the top “wsl”. We will want the option with the beautiful little blue penguin on it issued by Microsoft Corporation.

Once that is installed then we need to pick an OS. Luckily, this is available right on the same page we just searched! There are many options to pick from but, I recommend the Ubuntu LTS 22.04 release as its the most recent long term stable version. Simply click the one you want, and add it.

Now, even though we have added WSL and our OS, we still need to let the os install. The easiest way todo this to just search the OS’s name from the start menu and open it up, it will automatically begin installing. ie: search “ubuntu” in the start menu and click the OS logo to launch

AND BOOM!!! We now have WSL2 installed on our system. Before we get into updating our OS and installing Neovim. We will want to take a step back and focus on our terminal experience. Microsoft does have their own Terminal app but, to be honest it sucks when compared to the awesome amount of customization (and more importantly speed) available through other software.

Part 2 — The Terminal (Wezterm configuration)

The terminal we will go with is called Wezterm. It was built by a guy called Wez and it’s pretty bonkers good. It’s fully available on all platforms so if you’re here for just the Neovim config side of things, you can still give this a go if you like it!

To start off with you can download Wezterm from Wez Furlongs website, here. (full link: https://wezfurlong.org/wezterm/index.html)

Just open up the executable and follow it’s instructions. There is not much else to it as Wez kept things simple for us and its not 2008 where every installed comes with 20+ addon software's.

Now Wezterm, like Neovim has taken the route of allowing its users to custom configure it’s settings using LUA and has built a massive library with solid abstration choices! This is great as it lets up do powerful modifications using very simple code and lets you go as deep or as simple as you want in configuring it.

The fist thing todo is create an environment variable called HOMEthat resolves to C:\Users\your username here

You’ll also want to add the XDG_CONFIG_HOME that resolves to C:\Users\your username here \.config

Note: Make sure those directories exist

Todo this in windows run in cmd:

rundll32.exe sysdm.cpl,EditEnvironmentVariables

You can do this on Linux by adding them to your .bashrc file. Follow this guide for more info on environment variables in Linux.

Now we will want to add/create our Wezterm config file. Todo so, type %XDG_CONFIG_HOME% in you file explorer or just go to C:\Users\username goes here\.config\. Once there make a new folder called wezterm . Inside of it create a new file called wezterm.lua

I’m going to start off by just giving you my wezterm.lua. You can see what things do by reading the comment lines (always comment your code and configs).

-- These are the basic's for using wezterm.
-- Mux is the mutliplexes for windows etc inside of the terminal
-- Action is to perform actions on the terminal
local wezterm = require 'wezterm'
local mux = wezterm.mux
local act = wezterm.action

-- These are vars to put things in later (i dont use em all yet)
local config = {}
local keys = {}
local mouse_bindings = {}
local launch_menu = {}

-- This is for newer wezterm vertions to use the config builder
if wezterm.config_builder then
config = wezterm.config_builder()
end

-- Default config settings
-- These are the default config settins needed to use Wezterm
-- Just add this and return config and that's all the basics you need

-- Color scheme, Wezterm has 100s of them you can see here:
-- https://wezfurlong.org/wezterm/colorschemes/index.html
config.color_scheme = 'Oceanic Next (Gogh)'
-- This is my chosen font, we will get into installing fonts on windows later
config.font = wezterm.font('Hack Nerd Font')
config.font_size = 11
config.launch_menu = launch_menu
-- makes my cursor blink
config.default_cursor_style = 'BlinkingBar'
config.disable_default_key_bindings = true
-- this adds the ability to use ctrl+v to paste the system clipboard
config.keys = {{ key = 'V', mods = 'CTRL', action = act.PasteFrom 'Clipboard' },}
config.mouse_bindings = mouse_bindings

-- There are mouse binding to mimc Windows Terminal and let you copy
-- To copy just highlight something and right click. Simple
mouse_bindings = {
{
event = { Down = { streak = 3, button = 'Left' } },
action = wezterm.action.SelectTextAtMouseCursor 'SemanticZone',
mods = 'NONE',
},
{
event = { Down = { streak = 1, button = "Right" } },
mods = "NONE",
action = wezterm.action_callback(function(window, pane)
local has_selection = window:get_selection_text_for_pane(pane) ~= ""
if has_selection then
window:perform_action(act.CopyTo("ClipboardAndPrimarySelection"), pane)
window:perform_action(act.ClearSelection, pane)
else
window:perform_action(act({ PasteFrom = "Clipboard" }), pane)
end
end),
},
}

-- This is used to make my foreground (text, etc) brighter than my background
config.foreground_text_hsb = {
hue = 1.0,
saturation = 1.2,
brightness = 1.5,
}

-- This is used to set an image as my background
config.background = {
{
source = { File = {path = 'C:/Users/someuserboi/Pictures/Backgrounds/theone.gif', speed = 0.2}},
opacity = 1,
width = "100%",
hsb = {brightness = 0.5},
}
}

-- IMPORTANT: Sets WSL2 UBUNTU-22.04 as the defualt when opening Wezterm
config.default_domain = 'WSL:Ubuntu-22.04'

return config

Okay I know that looks like a lot but, all you really need to know is that we set up Wezterm to mimic some simple features, adjusted things for image backgrounds and set WSL as the default environment to use.

If you want to go really in-depth into configuring Wezterm I highly recommend reading this article post first. As well as the official Wezterm quick start guide.

Now, apart of this I set up a NerdFont to make the terminal text look better. I suggest you do this to as NerdFonts are a REQUIRMENT to use Neovim. It is important to note though, WezTerm includes Nerd Font Symbols Font as a default font fallback which means that these special symbols are available even without requiring you to use a patched font.

To get Nerdfonts overall though, just goto https://www.nerdfonts.com/font-downloads and download the desired font. Extract it, then highlight all the files, right click and select install. You can alternatively install them by dragging and dropping them into the Font Settings section of windows (just search it in start menu). Once done you’ll see the fonts have been added.

NOTE: I have heard of issues using “ — Nerd Fond Mono” versions with Neovim so I would avoid them to start out.

When it’s all done, if you open Wezterm you should see something along the lines of this:

Low key flex

NOTE: .gif file backgrounds on Windows seem a bit buggy when I try to use them others have had success, try at your own peril.

Part 3 — Neovim Time

Okay so lets get into the fun stuff now. Step one is to get Neovim. There are alot of ways to skin the cat but this will be the simpilest.

Install & Configure NeoVim

Open your WSL terminal and run:

# add the repo
$ sudo add-apt-repository ppa:neovim-ppa/unstable
# update & install
$ sudo apt-get update
$ sudo apt-get install neovim

EZ PZ.

Now the hard part. You have the coice to configure Neovim however you want todo so. I personally recommend following along with this Youtube video:

The reason I recommend building it a few times from scratch and encountering some hiccups along the way is to let you REALLY learn what is going on with Neovim before just installing Nvchad and calling it a day. But if you want just go ahead and do it, Nvchad is great but you’ll be lost in what all there is if you just use it with no understanding.

You can find my dotfiles here if you want to just copy and paste my configs, it’s a more updated and working version then the video as that has some broken things in it and his dotfiles are borked too (w/o some tweaks).

Before we finish off let me leave you with a break down of what is in the video as a sort of paired guide:

  1. Take your time with this, seriously just breathe.
  2. Use nvim when following this, he has a bash alias set up so that when he types vim it really means nvim
  3. Vim has MODES. N means Normal, Visual, Insert, and Command mode. You don not need to worry about it but we aware of them. When you open a file to start editing it, get into Insert mode by clicking i
  4. To exit Neovim just exit inset mode by pressing esc and then :q or :wq to write to file then quit
  5. Packer is the package manager. Think of it like apt or yum or homebrew or the part of the appstore that tells you what needs updated etc. We add the plugins to be installed by using them in packer.lua then we run packer to install or update them with :PackerSync.
  6. When editing adding remaps know that C-x in remaps means Ctrl + [KEY] when typing will do action. In most cases these are just calls to the vim api (what makes vim and neovim so great).
  7. You can command line command within vim by just doing :! for exaple if you are editing a python file and want to test is just do :!python3 main.py and it’ll run. Same thing once you install the Fugitive plugin you can even do all your git actions right there in the editor super fast just :G to run any git command with ease.
  8. Once you finish the video you can call it done OR go and add more things like nvim tree to see a file tree or add tabs and auto complete etc etc etc. Sky is the limit so have fun with is once you have your berings!

--

--