Eiko Wagenknecht
Software Developer, Freelancer & Founder

WSL for Tauri Development on Windows

Eiko Wagenknecht

I recently had some trouble with my Windows development environment (a Claude Code bug that only affects Windows), so I went down the rabbit hole of setting up Windows Subsystem for Linux (WSL) instead. This post is a short how-to guide on how I set up WSL.

I’m developing a Tauri application in a GitHub repository with VS Code, so my stack looks something like this:

And related tools:

I’ll try to describe the different parts separately, so you can easier adopt for other usecases.

I’ll also assume you have a working Windows development environment (git set up and configured, VS Code installed, etc.), because we’ll migrate some of those settings over to WSL.

Table of Contents

Why would you do that?

There are a few reasons why you might want to use WSL instead of a native Windows development environment:

Installing WSL

If you don’t have WSL v2 installed yet, you can do so by running the following command:

wsl --install

This will install the latest version of WSL and the default Ubuntu distribution, which is fine for development purposes.

Setting up WSL

There’s not much to set up here, but if you are also using Docker Desktop, you might need to run the following command to set the default distribution correctly:

wsl --set-default Ubuntu

Docker Desktop will sometimes steal this back, so you might need to run this command again after an update.

Updating WSL

As always, you should keep your distribution up to date. To do so, first start your WSL terminal:

wsl
Note

All future commands in this post will be run in the WSL terminal, unless mentioned otherwise.

Then run the following commands to update your distribution:

sudo apt update && sudo apt upgrade

Installing Node.js

For Node.js in WSL, I recommend using nvm (Node Version Manager) to manage your Node.js versions.

To install nvm, you can run the following command:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash

Then restart your WSL terminal so teh new environment variables are picked up.

To install the latest LTS version of Node.js, run:

nvm install --lts

You can verify the installation by running:

node --version

If you want to update to the latest LTS version later, you can run nvm install --lts again, and it will install the latest version and set it as the default.

And while we’re at it, let’s also update npm to the latest version:

npm install -g npm@latest

Installing pnpm

To install pnpm, you can use the following command:

corepack enable pnpm

Installing Rust

Just do as the official Rust installation guide says:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

You can use the default installation options, which will install Rust to ~/.cargo/bin.

Installing Tauri Dependencies

For Tauri, you need to install some additional dependencies. You can do so by running the following command:

sudo apt install libwebkit2gtk-4.1-dev \
build-essential \
curl \
wget \
file \
libxdo-dev \
libssl-dev \
libayatana-appindicator3-dev \
librsvg2-dev

Installing git

Technically, git is already installed by default, but Ubuntu’s version is quite old. To install the latest version, add the Git Core PPA and install git (and git-lfs if you use LFS):

sudo add-apt-repository ppa:git-core/ppa
sudo apt install git-lfs
sudo apt update && sudo apt upgrade

Migrating your git configuration from Windows

If you already have a git configuration on Windows, you can just copy it over to WSL:

cp /mnt/c/Users/[your-windows-username]/.gitconfig ~/.gitconfig

As an example, my ~/.gitconfig looks like this:

[user]
        name = Eiko Wagenknecht
        email = [email protected]
[commit]
        gpgsign = true
[core]
        autocrlf = false
[filter "lfs"]
        required = true
        clean = git-lfs clean -- %f
        smudge = git-lfs smudge -- %f
        process = git-lfs filter-process

Setting up commit signing with GPG

This part assumes you already have a GPG key set up. If not, GitHub has a guide on how to create a GPG key.

First, save your GPG key to a file on Windows, for example C:\Users\[your-windows-username]\gpg\private.pgp.

Then import it into WSL:

gpg --import /mnt/c/Users/[your-windows-username]/gpg/private.pgp

Make sure to delete the file again afterwards, so it doesn’t linger around in your Windows file system.

You can verify that the key was imported correctly by running:

gpg --list-keys --keyid-format=long

You can see the key ID in the output (it looks like rsa4096/<16_CHARS_HEX_KEY_ID>). If you haven’t set up your GPG key for signing commits yet, you can do so by running:

git config --global user.signingkey [your-gpg-key-id]

This adds the key ID to your global git configuration, so all commits will be signed with this key by default.

[user]
        name = Eiko Wagenknecht
        email = [email protected]
        signingkey = 47A66A462AFC685D

If you’d try to sign a commit now, you’d get an error: “Inappropriate ioctl for device”. This is because the GPG agent is not set up to use the correct pinentry program in WSL yet.

There are two ways to fix this:

  1. Use the terminal to sign commits: echo 'export GPG_TTY=$(tty)' >> ~/.bashrc && source ~/.bashrc This will set the GPG_TTY environment variable to the current terminal, which allows GPG to prompt for your passphrase in the terminal.

  2. Use the Windows pinentry program: This is the recommended way, as it allows you to use the same pinentry program as on Windows, which also works in VS Code’s sidebar: To do so, download GPG for Windows (it’s called “Simple installer for the current GnuPG”) and install it. Then tell the WSL GPG agent to use the Windows pinentry program by adding the following line to your ~/.gnupg/gpg-agent.conf file:

    echo 'pinentry-program "/mnt/c/Program Files (x86)/GnuPG/bin/pinentry-basic.exe"' >> ~/.gnupg/gpg-agent.conf

If you want to be asked for your passphrase less often, you can also set the default-cache-ttl and max-cache-ttl options in the same file (in my example, I set them to 12 hours):

echo "default-cache-ttl 43200" >> ~/.gnupg/gpg-agent.conf
echo "max-cache-ttl 43200" >> ~/.gnupg/gpg-agent.conf

After that, make the GPG agent reload the configuration:

gpg-connect-agent reloadagent /bye

Authenticating with GitHub

To authenticate with GitHub, the easiest way is to use the GitHub CLI. You can install it by running the official installation script:

(type -p wget >/dev/null || (sudo apt update && sudo apt install wget -y)) \
 && sudo mkdir -p -m 755 /etc/apt/keyrings \
 && out=$(mktemp) && wget -nv -O$out https://cli.github.com/packages/githubcli-archive-keyring.gpg \
 && cat $out | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
 && sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
 && sudo mkdir -p -m 755 /etc/apt/sources.list.d \
 && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
 && sudo apt update \
 && sudo apt install gh -y

Then run the following command to authenticate with GitHub:

gh auth login

It will ask you a few questions, like which authentication method you want to use. You have to open the URL it provides in your browser yourself as the WSL terminal does not support opening links directly. After that, you can verify that you’re authenticated by running:

gh auth status

This adds configuration options to your ~/.gitconfig file, so you can use the GitHub CLI to interact with your repositories. This is added:

[credential "https://github.com"]
        helper =
        helper = !/usr/bin/gh auth git-credential
[credential "https://gist.github.com"]
        helper =
        helper = !/usr/bin/gh auth git-credential

After authenticating with the GitHub CLI, you can just run git commands as usual, and it will use the GitHub CLI to authenticate with GitHub. Try it out by running a command like git fetch in a repository that you have access to (see the next step).

Copying the repository to WSL

Now while you could just open the repository in WSL using the Windows file system path, I recommend copying it to the WSL file system instead as the performance is much better. You also avoid potential issues with file permissions which can be very nasty to debug.

To do so, I find it to be easiest to first remove all temporary files and directories from the project folder. You can do so by running git clean -fxd in the repository root directory on Windows.

Warning

This will delete all untracked files and directories, so make sure you don’t have any important files in there that you haven’t committed yet or need for your local configuration!

To copy the repository to WSL, you can then use the following command in your WSL terminal:

mkdir -p ~/repos
cp -r /mnt/c/[path-to-your-repository] ~/repos/[your-repository]

I recommend keeping a copy of the repository in your Windows file system as well, so you can switch between the two environments. This way, you can still run the application on Windows if you need to test it there.

Accessing the WSL repository from Windows

If you ever want to access the repository in the WSL file system from Windows, you can find it in the \\wsl$\Ubuntu\home\[your-wsl-username]\repos\[your-repository] path. The performance when opening the repository from Windows is okay, but for file heavy operations, I recommend using the WSL terminal instead. I use this sometimes to view the repository with Sourcetree from the Windows side. Git will need an additional git config --global --add safe.directory \\wsl$\Ubuntu\home\[your-wsl-username]\repos\* command to allow access to the repository from Windows, though.

Testing if it works

Now is a good time to compile your app to see it everything works as expected.

First, you need to reinstall the dependencies. Just cd into the repository directory:

cd ~/repos/[your-repository]

Then let it install the dependencies to recreate the node_modules directory:

pnpm install

It’s important to not copy over the node_modules directory from Windows, as the dependencies there are compiled for the Windows environment and will not work in WSL, leading to all kinds of weird errors.

Now you can build the Tauri application:

pnpm tauri build

If there are any errors, now’s the time to fix them.

Setting up VS Code for WSL

To use VS Code with WSL, you need to install the WSL extension. Besides that, you can just open the repository in VS Code by running this in your WSL terminal:

code .

This will open the directory from the WSL file system in VS Code, but in “Windows mode”, meaning it will use the Windows file system for the VS Code settings and extensions. To use the preferred WSL mode, run the “WSL: Reopen Folder in WSL” command from the Command Palette (Ctrl+Shift+P) to open the repository in WSL mode.

Now you might notice that a lot of your extension are not enabled any more. This is because many extensions need to be installed inside the WSL environment to work correctly. VS Code does not automatically do that, so you need to go to the Extensions view (Ctrl+Shift+X) and install the extensions you need in WSL with the “Install in WSL: Ubuntu” button.

Installing Claude Code

To install Claude Code inside WSL, you can use the following command:

npm install -g @anthropic-ai/claude-code

Then inside a WSL terminal, you can run it with:

claude

When setting up your account, you need to open the URL manually in your browser, as the WSL terminal does not support opening links directly.

Running the Tauri application in WSL

When you run the Tauri application in WSL (pnpm tauri dev), it will not run in the Windows environment, but in the WSL environment instead. This means that it will not only use the WSL file system, but also the WSL browser to display the application. This can lead to graphical glitches (happened to me on my notebook with an Intel GPU where a lot of elements had an “X” striking them through, but not on my desktop with an AMD GPU), so you might want to do more exhaustive testing in your native Windows environment.

For reference, I could fix the graphical glitches by running the following command in WSL:

export DISPLAY=:0
export LIBGL_ALWAYS_INDIRECT=1
export XDG_RUNTIME_DIR=/tmp/runtime-$(whoami)

If it helps, make sure to add these lines to your ~/.bashrc file, so they are set automatically when you start a new WSL terminal.

No Comments? No Problem.

This blog doesn't support comments, but your thoughts and questions are always welcome. Reach out through the contact details at the bottom of the page.

Support Me

If you found this page helpful and want to say thanks, you can support me here.