Quick write-up of how I manage Haxe versions under Linux

@fullofcaffeine asked how I managed various versions of Haxe, so here’s just a quick core dump.

For all these commands, rather than sprinkling sudo everywhere, I’m going to assume your user owns the /opt directory. You can affect that ownership with:

sudo chown $USERNAME:$USERNAME /opt

I untar various versions of Haxe in /opt/ – any of the following will do:

cd /opt/
curl -sL https://github.com/HaxeFoundation/haxe/releases/download/4.0.0-rc.1/haxe-4.0.0-rc.1-linux64.tar.gz | tar -xz
curl -sL https://github.com/HaxeFoundation/haxe/releases/download/3.4.7/haxe-3.4.7-linux64.tar.gz | tar -xz

Ok, so this untarred some long directory names – I want them to be short and descriptive:

mv haxe_20180221160843_bb7b827 haxe-3.4.7
mv haxe_20190201170222_1fdd3d5 haxe-4.0.0-rc.1

Great, now I have /opt/haxe-3.4.7 and /opt/haxe-4.0.0-rc.1

Now I’ll create a symlink of /opt/haxe to whichever version of Haxe I want to be the globally installed one. And I’ll symlink the haxe and haxelib binaries to /usr/bin to make them available to all users (typically just me):

cd /opt
ln -s haxe-4.0.0-rc.1 haxe
cd /usr/bin
sudo ln -s /opt/haxe/haxe .
sudo ln -s /opt/haxe/haxelib .

Ok, and we’ll do the same setup for neko (though it appears you might not need neko if you’re only working with Haxe 4+):

cd /opt
curl -sL http://nekovm.org/media/neko-2.1.0-linux64.tar.gz | tar -xz
cd /usr/bin
sudo ln -s /opt/neko-2.1.0-linux64/neko .

Now, Haxe can sometimes auto-detect the following, but I find it’s safest to just specify it. I often put these in my ~/.bashrc, though they could/should go in /etc/profile.d/haxe.sh to truly be part of the “system-wide install”:

export HAXE_STD_PATH=/opt/haxe/std
export NEKOPATH=/opt/neko-2.2.0-linux64

Ok, if all went well, I have haxe and neko installed:

> haxe -version
> neko -version

And changing the system-wide version of Haxe is as easy as changing the symlink:

cd /opt
rm haxe
ln -s haxe-3.4.7 haxe

(Or, if you’d rather remember these args, you don’t need to rm haxe first:)
ln -sfn haxe-3.4.7 haxe

And check it:

> haxe -version

Great. So that’s the system-wide install.

But note that I can, for one (shell) session or one script, override the system install by placing the other version on the front of my PATH (which then overrides the binaries in /usr/bin), and overriding HAXE_STD_PATH.

For a shell session, I can simply type:

export PATH=/opt/haxe-4.0.0-rc.1:$PATH
export HAXE_STD_PATH=/opt/haxe-4.0.0-rc.1/std

Now for the rest of that shell, I’m using the specific Haxe version.

If I wanted to use these variables for one single command only, you can prefix those env variables to the command:

PATH=/opt/haxe-4.0.0-rc.1:$PATH HAXE_STD_PATH=/opt/haxe-4.0.0-rc.1/std haxe my_build.hxml

But that’s quite a mouthful. Let’s make an alias for that (you can save this in ~/.bashrc or in /etc/profile/d/haxe.sh):

alias haxe4='PATH=/opt/haxe-4.0.0-rc.1:$PATH HAXE_STD_PATH=/opt/haxe-4.0.0-rc.1/std haxe'

Excellent. Now the haxe4 alias invokes haxe 4, even if haxe 3.4.7 is my system-wide haxe. So I can type:

> haxe -version
> haxe4 -version

Some will argue that a system-wide installation of Haxe is bad / singleton-esque. Meh – I want “the typical” version installed and always ready. If a project needs a specific version of Haxe, I’ll either switch my shell (shown above), or setup some docker CI scripts and a .travis.yml for that project (using all the commands you just learned above!)

If you learn about environment variables, symlinks, and docker, you’ll have an extremely powerful set of tools in your belt!


Nice technique :+1:

As an alternative to owning the full /opt directory which is probably not the best idea, you can own /opt/haxe for instance, or installing haxe in your home directory.

I don’t think you can access aliases in shell scripts (would have to check) so an alternative to it is to make an haxe4 script in /usr/local/bin/:

PATH=/opt/haxe-4.0.0-rc.1:$PATH HAXE_STD_PATH=/opt/haxe-4.0.0-rc.1/std haxe $@

and don’t forget the chmod +x /usr/local/bin/haxe4 to make it executable.

Also worth noting that since haxe 4 (would have to check which rc) you don’t need to specify HAXE_STD_PATH anymore, it default to looking next to the haxe executable.


Using system-wide compiler as well here and lousy scripts :slight_smile:

On Mac (should work the same on Linux) I just install Haxe compiler and when my environment is working I can move the Haxe binary to a versionned folder, e.g.:

$ mv /usr/local/lib/haxe /usr/local/lib/haxe_3.4.7

Then I have a set-haxe bash script to create a symlink to /usr/local/lib/haxe folder:

echo $TARGET
if [ -d "$TARGET" ]; then
  echo "Set Haxe version $1"
  rm /usr/local/lib/haxe
  ln -s $TARGET /usr/local/lib/haxe 
  echo "Error: Haxe version $1 not found"

And I can set the compiler like:

$ set-haxe 3.4.7

I also have a script to get the nightly build as version “latest” (note: using httpie.org)

http --download http://hxbuilds.s3-website-us-east-1.amazonaws.com/builds/haxe/mac/haxe_latest.tar.gz
tar -xvzf haxe_latest.tar.gz
rm haxe_latest.tar.gz
mv haxe_* haxe_latest
mv haxe_latest /usr/local/lib/haxe_latest

So I can run:

$ set-haxe latest

Great info! Now which command-line wizard shall I follow? :slight_smile:

I’ll cleanup my repo with haxe scripts and post it here asap :slight_smile:

I use a slightly different approach:
I have a shell script called haxe4.env in /usr/local/bin/, containing:


export PATH="/opt/haxe4:$PATH"
export HAXE_STD_PATH=/opt/haxe4/std
export HAXEPATH=/opt/haxe4

A fresh command line shell will default to Haxe 3.4.7, because that’s what is installed through a .deb package as system default. So for Haxe 3 I don’t have to do anything.
If I want to switch to Haxe 4 I simply source that script e.g. with . haxe4.env (or source haxe4.env) and now that shell is a Haxe 4 shell, everything launched from there will use Haxe 4 (I typically use shells to launch everything, even VSCode).

Ok, here it is: GitHub - kLabz/haxe-manager: Easily download and switch haxe versions

It contains:

  • hx: a haxe version switcher using fzf (bundled with the repo when needed)
  • hx-download: a haxe downloader, supporting official releases and dev releases
  • hx-select: use it to switch to a specific haxe version (hx-select 3.4.7)

I added extra optional scripts in extra/:

  • ++haxe: haxe wrapper, formatting errors with haxe-error-parser from npm (old screenshot using it in webpack)
  • hxfzf: list all hx files in your project, including dependencies (I use it as input for fzf when switching files in vim, for example)
  • rofi-haxe: graphical haxe switcher using rofi
  • current-haxe: display current haxe version (I use it in i3bar, and run rofi-haxe on click)
  • watch-haxe: wrapper for haxe, which re-runs when a file changes in a folder (however deep) in your classpaths changes

Note: absolutely not tested on macOS, I have no idea how compatible it is.


Nice writeup, thanks a bunch guys! :heart:

I currently use Lix, but been considering alternatives because it has some issues with eval-debugger.

Among the approaches shown here, do any of them support isolating haxelibs per project folder as well? Any way to do that? I’ve heard about local haxelibs repos but it’s not clear how to use them.

haxelib newrepo (or just creating the dir yourself) will create a .haxelib folder inside your project (similar to node_modules).

When this directory exists, haxelibs are read/written there instead of the global scope.

I tend to add **/haxelib/* and !**/haxelib/.keep in my .gitignore (and add the .keep file) to make sure the project will be using a local repo when cloned.

As for installing dependencies, I maintain a install.hxml with exact versions (specific haxelib version or git url + tag or commit reference) to be used with haxelib install --always install.hxml.

1 Like

Thanks Rudy!

It seems the problem Lix had with vshaxe’s eval-debugger extension has been fixed (seemed to be an eval-debugger issue). I’ll keep using Lix for now, but I appreciate knowing exactly how the alternatives work now, in case I need to fallback in the future.

1 Like

I used to just install all Haxe versions using official installer and configure HaxeDevelop to store the Haxe version. This works good enough if you’re the only dev and keep using Windows.

For me it didn’t work when I wanted to use Haxe in automatic deploys etc (on Linux), or when a developer on Mac wanted to contribute to my project. Also my haxelib dependencies were a mess. That’s when I decided to switch to something that works across different OS-es and is easy to install for anyone. So now I use lix too.

I don’t install lix globally, but always per project (global installation kinda messes up installations), so it’s always added as local dependency. It’s great when you do * lots * of projects like me and want have haxe/haxelib versions locked (so it still works after years without figuring out which git version you used at the time)

Lix is super nice; switch Haxe versions just by changing it in the .haxerc file.

Getting started with lix is as simple (assuming you have node installed):

md myproject & cd myproject & echo {"scripts":{"lix":"lix","haxe":"haxe"}} > package.json & npm install lix --save-dev & npm lix scope create & npm lix use haxe stable

Then compile using npm haxe ... instead of haxe. This is of course something you should configure in your IDE.

1 Like

Tip: lix install haxe (stable | latest | nightly | version | sha) (or use instead of install, if you want to switch between already downloaded versions … you can use lix haxe-versions to see these).


That. So good.

Lix is super nice;


As much as I appreciate knowing how people have their homebrew solutions to switching Haxe versions and isolating haxelibs per project, now that the recent quirks with vshaxe have been fixed, I’d really recommend Lix to anyone reading this topic.

It’s analog to conveniently bundling (no pun intended) bundler + rbenv (if you’re used to the Ruby eco-system) in a single tool with a good CLI interface that provides a very good UX.

Being able to quickly install haxelibs from git hassle-free up to the specific commit hash I need is one of the features I love about Lix. It’s very easy to build a snapshot of haxelibs + haxe compiler version without the need to bundle everything in the repo.

I do git submodule add https://github.com/Kode/Kha.git Kha in every project to manage my Haxe versions.