I have to admit: I am feeling lazy typing today. Therefore, I will go directly to the point.

But I will try to bring in some context.

Getting Started with Elixir

A few weeks ago, I started playing around with Elixir. There’s even this post from when I was playing around with tree traversal in Elixir.

Back then, I was programming on MacOS and had no problem, aside from the fact that setting up Elixir on Mac and making it work took me a full day.

However, currently, I am using Windows - of all the platforms I hate developing in. It is a disaster, or so I thought.

Aparently, getting started with Elixir is simpler on Windows since you just download an installer and you are done.

The installer got everything working out of the box, just like magic. I was up and running without much trouble, not like on MacOS.

The Phoenix Framework

But then, after understanding a few concepts and the syntax, I felt ready to try the famous Phoenix Framework. Phoenix, as I am aware, is very interesting.

Starting my first project in Phoenix was as simple as running a single mix command: mix archive.install hex phx_new 1.5.1, and then creating a new project with mix my_project.

I followed a few guides and familiarized myself with the project outline. It was easy. Until it was not.

Implementing Authentication in Phoenix Framework

Naturally, web applications are supposed to grow from simple to complex. But I decided, instead of my project growing slowly, I should start with authentication and then work on the other features. That way, from the onset, I will be sure what is exposed and what is not, at least for security reasons. It is just how I think.

So, I started searching for the right way to implement authentication in Phoenix.

I was convinced Guardian is way better than the others. It looked capable and promising.

I followed the guide to add guardian to my project, set it up and finally ran mix phx.server. Everything went completely berserk!

Guardian recommends you use Argon2_elixir to hash passwords. And Argon2_elixir was the culprit.

Argon2_elixir’s Compilation Issues on Windows 10

The following error showed up when I ran mix phx.server:

Generated elixir_make app
==> argon2_elixir
could not compile dependency :argon2_elixir, "mix compile" failed. You can recompile this dependency with "mix deps.compile argon2_elixir", update it with "mix deps.update argon2_elixir" or clean it with "mix deps.clean argon2_elixir"
==> tracker
** (Mix) "nmake" not found in the path. If you have set the MAKE environment variable,
please make sure it is correct.

I ‘knew’ the problem must be common, and so went online to look for a solution.

A commentor on a similar issue suggested that the error could be resolved by installing C++ build tools (choco install VisualCppBuildTools).

C++ build tools were already in my system because I had Visual Studio install those a few weeks back when I wanted to do something else I can’t recall now.

Another commented that one needed to add nmake to the environment variables. I looked for nmake.exe and found it in four different places, I had no idea which to use:

  1. C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.25.28610\bin\Hostx64\x86
  2. C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.25.28610\bin\Hostx64\x64
  3. C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.25.28610\bin\Hostx86\x64
  4. C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.25.28610\bin\Hostx86\x86

I am sure that if I looked a little longer I would have found more :).

I experimented adding all those to the path, adding one, then removing that and trying the next, but still, the project failed to compile with a different error:

argon2.c argon2\src\argon2.c(18): fatal error c1083: cannot open include file: 'string.h': no such file or directory

It was at this moment that I cried for missed interpreted languages like JavaScript and Python. Boy, they just work in my experience.

Then I found the following comment on Argon2_elixir’s github issues page:

I think it’s definitely something to do with Windows. I’ve opted to use Pbkdf2 instead of argon2 and bcrypt as this seems to be the only working dependancy

Replacing Argon2 with P whatever didn’t sit well with me, because, I have OCD alright. Pbkdf2 and bcrypt are way weaker than Argon2 according to this.

WSL to my Rescue

So, at last, I weighed my options. One of those was go back to MacOS. another was to give up and choose Pbkdf2. But there was no way I could give up Argon2 having known it won the Password Hashing Competition!

But then, it hit me.

In one of the comments on the topic of Windows being weird when it comes to compiling native code, Linux was mentioned as being well organized, and that compiling native code there as opposed to on Windows is way more certain, breeze.

And I remembered I had already downloaded and installed Ubuntu onto my Windows 10, that is, Windows Subsystem for Linux (WSL) was fully set up. You can see how to get started with/install WSL in Windows 10.

A few weeks back, while setting up WSL, VS Code had even recommended that I install Remote - WSL. I didn’t even know what it was used for, and I found no use, but still kept it installed. Alas! Remote - WSL is an awesome extension.

I opened the terminal within VS Code and fromt he terminal’s drop-down menu, I selected select default shell and then chose wsl.exe. The WSL terminal loaded and mounted my project folder.

Installing Elixir and Its Tools in WSL

But up to now, I had only been coding in Windows and there’s nothing in WSL. So I had to install Elixir and all its tools on the bare WSL. But trust me, it was as simple as pasting the following commands in the wsl.exe terminal one by one (though, of course, Google was kind because not all of them were in the same place):

wget && sudo dpkg -i erlang-solutions_2.0_all.deb

sudo apt-get update

sudo apt-get install esl-erlang

sudo apt-get install elixir

sudo apt-get install build-essential

mix archive.install hex phx_new 1.5.1

sudo apt-get install -y inotify-tools

curl -o- | bash

nvm install --lts

Just as a reminder, I did all of these right within VS Code. Isn’t that amazing!?

In case you need to access the postgres that you installed inside Windows, you can do:

sudo apt install postgresql-client-common

sudo apt-get install postgresql-client

psql -h -p 5432 -U postgres

When I ran mix phx.server again, I could not believe it! It just worked. Everything compiled 100%. Remember, my postgreSQL is inside Windows, not within WSL, but it just worked. I don’t know what magic Windows devs did there, but I think I am now sold.


I had sworn I can never develop on Windows, I had no idea that VS Code makes it trivial to have your files within windows, and yet, your dev tools and environment lives withinn WSL. It is still mind-blowing how simple.

Thank you for reading. Feel free to leave a comment.

comments powered by Disqus

You might also like