I made yet another Zig version manager, sorry

I searched for one I’d want to use, but they all had at least one of the following dealbreakers (for me):

  • not written in zig
  • no support for installing zls
  • tries to switch zig version based on project’s build.zig.zon

so I made my own: zig-installation-manager (zim)

any feedback or feature idea/request is welcome! thanks

ha and I also have a question: currently I prioritize using the community mirrors to download zig; does that make sense or should I prioritize the official download instead so the download speed is more consistent?

3 Likes

you should prioritize mirrors, following these instructions Community Mirrors ⚡ Zig Programming Language

concidentally we are are being ddossed right now (or some vibecoded ai crawler is misbehaving, hard to tell the two cases apart nowadays) so prioritizing mirrors would give your users a better experience

10 Likes

I thought you does not check signatures, but turns out you rolled your own minisign. FYI there’s GitHub - jedisct1/zig-minisign: Minisign reimplemented in Zig. · GitHub

Imo one thing most Zig version manager woukd profit from is enhanced shell completion. Since, in a best case scenario, you won’t use these commands too often, fast an informative completion is really helpful.

Before 0.16.0 was released I found myself often running zig any list-installed and then manually copying a version number into the next command prompt…

1 Like

Yes, I did see it but I wanted to stay dependency free so I rolled my own.

1 Like

Interesting idea, unfortunately the bash system for doing auto completions is quite annoying. I could add a zim completion command and so you can add a completion script that just calls to it.

I see thanks. I did follow the community mirrors instructions they were very helpful.

I wonder if there is a good way to check the download speed of the mirrors so it can pick a not-too-slow one. Maybe a ping and checking the latency would be fine enough.

You could do command-line completion with cligen, like I did for zig (https://codeberg.org/anthon/zigclc) and zine ( https://codeberg.org/anthon/zineclc ). This doesn’t require any changes to the program you complete for.

For getting the list of possible version numbers you can do something similar like I do for getting the build steps, project options and system integrations ( https://codeberg.org/anthon/zigclc/src/branch/main/_ext/zig_dynamic_build_steps.yaml ), in your case you would have to
create a restriction that calls the command to get the list of versions in some form, parse the output and and calling sc.normal() for all the results. That will actually filter out those result that don’t match the partial result the user typed for you. ( i.e. if 0.1<TAB> was input it will filter out 0.9.0 for you and let through 0.15.2 and 0.16.0 etc.) You may have to cache the parse result if getting the list is slow.

I think it would be nice to have a command that lists what versions you have currently installed, akin to bob, that way if someone is not sure if they have a particular version installed, they can check before fetching it again.

If I do ls /opt/zig/0* on any of my systems, that gives me (on my macbook)

/opt/zig/0.9@    /opt/zig/0.10.0@  /opt/zig/0.11.0@  /opt/zig/0.13@    /opt/zig/0.14.0@  /opt/zig/0.15.1@  /opt/zig/0.16.0@
/opt/zig/0.9.0@  /opt/zig/0.10.1@  /opt/zig/0.12@    /opt/zig/0.13.0@  /opt/zig/0.14.1@  /opt/zig/0.15.2@
/opt/zig/0.10@   /opt/zig/0.11@    /opt/zig/0.12.0@  /opt/zig/0.14@    /opt/zig/0.15@    /opt/zig/0.16@

what more do you need when you know what the base directory is where you install the zig versions?

Somewhat off-topic, but it’s maybe worth taking a look at Mise, for inspiration if nothing else.

It doesn’t meet the “written in Zig” requirement, but it also doesn’t fall into most of the pitfalls of shim-based solutions either. I’ve been pretty happy using it to manage my Zig versions so far (it uses mirrors by default!)

When active on a shell, it checks your cwd (and its parents) for a mise.toml file, and references it to perform actions like add folders to $PATH (this is how it performs directory-dependent executable versioning). This updates every time the terminal prompts.

It also has a built-in command to quickly install and use specific versions of zig, zls, python, node, and several others either globally or in the current directory, as well as providing shims that use the program’s cwd if you need a static path.

1 Like

That’s true, and I wasn’t saying it was a feature that is absolutely necessary, but it is already a fairly established command that a lot of version managers have. I also like having a consistent interface, so if I want to check, I don’t have to remember where zig is installed or run a different command. It’s really just a nice-to-have.

I’m using zig-master-bin on arch now.

paru -S zig-master-bin

I prefer anyzig because it just looks at your project ,sees which version you need and downloads it for you.

only downside indeed is no zls is downloaded with it. Although the code is there, it’s just not enabled

We are deep, deep, deep into mise now. Mise is incredible and improving rapidly. I predict that soon it will be the standard for tooling on dev machines. Possibly production as well. Mise replaces asdf, direnv, dotenv, make, and zillions of homebrew 1-5 line scripts. We use it for go, npm, python, ruby, rust, & zig across all projects now.

Dev/vps machines can also use mise to easily install tools like age, bat, gitleaks, rg, watchexec, and many others.

Not totally sold on mise tasks yet, so we include just = "latest". Just is great too, not quite ready to switch yet.

1 Like

Does that support anything else than the “Totally Obfuscated Markup Language” by now?

It still uses toml as the configuration file format.

However, I’ve generally found that unless I’m doing complicated things with with it (which I try not to do and generally don’t need), I barely need to use the less readable parts of the toml spec. They also have a bunch of CLI commands that will modify the config for you, as long as you’re doing something common (ex: mise use zig@0.16.0 will create or modify a mise.toml file that adds Zig 0.16 to $PATH inside the current working directory).

When I do need something more complicated, I’ve been implementing the functionality as mise plugins instead, so I can script it in Lua rather than declare it in toml. So far, I’ve only done this to expose system libraries/headers installed via linuxbrew.

2 Likes