Congratulations on the release! I was a asdf user for a long time before jumping to rtx (now mise) with the main reason being poor performance in some of the things mentioned in the article.
Should give the new version a try, because if now the performance is on par, I would be happy to drop all the features in mise that I don’t care about.
mise has added a short section “asdf in go (0.16+)” to its “Comparison to asdf” page. The section says that mise exec is still faster than asdf exec, but that performance is now only a “minor” reason to switch to mise. “The improved security in mise, better DX, and lack of reliance on shims are all more important than performance.”
When it comes to versions, .tool-versions is the lock file. When it comes to plugins, we’ve not yet implemented versioning/locking yet. But it’s on our radar and something that we’ve wanted to add for a while.
It’s not really clear to me how security is any better in mise. Mise and asdf both use plugins, with mise having support for a few languages built-in. Additionally, asdf never automatically installs plugins, whereas I believe mise does. That’s actually a big security risk for mise. It sounds like mise is working to address this:
By the end of 2025 I would like for there to no longer be any asdf plugins in the registry that aren’t owned by me.
But that’s a big maintenance burden, hence why we’ve stuck with the plugins model for asdf. We’re now approaching 1k plugins for asdf, so I don’t see how @jdx plans to replicate that on his own.
My next blog post is going to be running benchmarks against the new Go code. I want to see how the Go version and the Bash version compare. Go is faster by a lot.
asdf is going to be slower than mise at the time of execution because mise doesn’t use shims. But asdf is zero cost when starting your shell, whereas mise actually has to run code to compute the proper value for your PATH.
Have you considered doing mise’s strategy, now that computing that PATH should be way faster in Go?
Apart from optimizing either initialization or execution, any other remarkable difference? I’m imagining that the shell integration with shims should be way simpler than detecting when the PATH needs to be updated during the shell lifetime.
I’ve not considered it, no. I believe shims are better.
No need alter PATH on the fly in the users shell sessions
No risk of PATH growing out of control when dozens of tools are used
Only overhead occurs at shim execution time
Shims work everywhere for all programs, as long as they set the current directory properly
The biggest challenge with shims is regenerating them as needed, and the overhead of executing them. The rewrite greatly improves performance of these operations, and should allow us to make future performance optimizations as we have time.
I tried mise a while back, and the main reason I went away from it is like you said, it does too much. It tries to be asdf, direnv and a task runner. I just want a tool manager, and is the reason why I switched to aquaproj/aqua.
You misunderstood. The first project started in like 2005, the second in 2014. They both have over a decade of use and both continue to be used. Neither is gonna be renamed.
No. I didn’t misunderstand. Yes, both have continued to exist largely without problems, but the fact that we have two, independent, package managers named “asdf” is just stupid. In 2014, a quick google search for “asdf” would have easily found asdf for Common Lisp. Why’d we get here in the first place?
If it wasn’t another package manager, I’d be more inclined to not care. But, come on.
And yes, the ship has sailed for asdf — but my Lua will be a general - general scripting language! It’s not just a general embeddable scripting language… No. It takes scripting languages to a whole new level of general-ness!
edit to say: 2005 actually seemed too late. Turns out asdf is 24 years old.
It’s true that asdf for Common Lisp is not a package manager — it’s a build tool that… creates packages.
The other asdf swaps out “runtimes” … a so called “version manager” allowing you to ensure that the right set of tools are being used when you go to develop, build, etc. It can install runtimes, and it can remove runtimes. I mean, I don’t want to go against the wishes of the author… but if it looks like a duck…
But, I’ll choose to concede to your point that neither of these are de facto “package managers,” but it’s hard to argue against the fact that they are in the same general purpose space.
edit to say: 2005 actually seemed too late. Turns out asdf is 24 years old.
Yes, I remember circa 2008 or 2010 when Faré revamped it as asdf2. But what’s the point? So there’s a namespace collision across two systems. No Lisper is going to mistake it.
I will not claim to be a Lisper, but having used neither in anger I was for a time under the vague misapprehension that there was only one asdf and that the Lisp one could be (ab)used to install non-Lisp things, kind of like pip sometimes is.
I fully admit this was an entirely a me problem and if I ever tried to use either my confusion would have been resolved, but there is my sample of 1 on the confusion being possible.
The point is that if you’re starting a new project, maybe do a quick search to see if something else by the same name is already established? This isn’t hard. It’s common courtesy. I don’t see why it’s controversial?!
For kicks I checked Wikipedia: asdf has even had a Wikipedia page since 2007.
Sure, I agree and would do the same, but someone didn’t and they made free software and put it out there for other people to use and continued to maintain it. I can’t get my nerd rage on about the accidental reuse of a project name.
Wait until you find out that Java was named after a coffee which was named after an island. Or that Python was named after a comedy skit which was named after a snake. And don’t get me started on Go or Rust or Ruby! It’s a miracle that we can get anything done in the software world with all of this semantic ambiguity! May we discuss nothing else except this endlessly fascinating topic until the end of time! /s
Wait until you find out that Java was named after a coffee which was named after an island. Or that Python was named after a comedy skit which was named after a snake. And don’t get me started on Go or Rust or Ruby! It’s a miracle that we can get anything done in the software world with all of this semantic ambiguity! May we discuss nothing else except this endlessly fascinating topic until the end of time! /s
You really got me… I’ll give you another, the function car in Lisps always confuses me with the car that you drive on the road. Surely we must move to unique identifiers every time we need to name something! /s
Or, you know, you can just stop naming the two things in the same category of things the same name. That might work. The lack of common decency is crazy.
Or, you know, you can just stop naming the two things in the same category of things the same name. That might work. The lack of common decency is crazy.
Obviously taxonomies are arbitrary and subjective, and a runtime version manager is not obviously in the same category as lisp build tooling. You could argue that they are both in the category of “software” just like you could argue that Rust (programming language) and Rust (game), yet people on this forum don’t routinely drag that up in every post with the rust tag because there’s obviously no such moral prohibition against using pedestrian names across multiple software projects.
asdf is a package manager dedicated to installing multiple versions of the same software and choosing which version is active. The packages it supports installing are mainly language runtimes like python, ruby, node, go, and so on.
In any particular terminal with a particular working directory, running a tool such as ruby will run only one of your installed versions. asdf doesn’t just have a global setting for which version this is: it can dynamically choose the correct version based on files in the source code of a project. It might find the version in an ecosystem-specific file that contains the language version, such as .ruby-version, or in asdf’s own file .tool-versions.
asdf was created to replace similar tools that manage multiple versions of only a single programming language. Examples of these tools: nodeenv, nvm, n, rvm, chruby, rbenv.
This asdf is a totally different project from the Lisp asdf, as discussed in this sibling thread.
It’s a package/version manager for various development environments. For instance, you can use it to install different versions of nodejs, and switch between them. There’s a pretty wide array of plugins for it; most things you can think of are installable via asdf.
Congrats on the rewrite! I’m a user of https://github.com/asdf-vm/actions and can only switch my dev-side if my CI-side is also switchable. Is there any consideration for updating the actions repo? Or will it transparently switch over to the new version?
Congratulations on the release! I was a asdf user for a long time before jumping to rtx (now mise) with the main reason being poor performance in some of the things mentioned in the article.
Should give the new version a try, because if now the performance is on par, I would be happy to drop all the features in mise that I don’t care about.
mise has added a short section “asdf in go (0.16+)” to its “Comparison to asdf” page. The section says that
mise execis still faster thanasdf exec, but that performance is now only a “minor” reason to switch to mise. “The improved security in mise, better DX, and lack of reliance on shims are all more important than performance.”Having lockfiles in asdf would be great. Signature verification depends on the plugins anyway.
When it comes to versions,
.tool-versionsis the lock file. When it comes to plugins, we’ve not yet implemented versioning/locking yet. But it’s on our radar and something that we’ve wanted to add for a while.A proper lockfile should include the checksums of each tarball for each possible os/arch combination, imho.
A plugin could be signed/verified but trust a compromised source.
It’s not really clear to me how security is any better in mise. Mise and asdf both use plugins, with mise having support for a few languages built-in. Additionally, asdf never automatically installs plugins, whereas I believe mise does. That’s actually a big security risk for mise. It sounds like mise is working to address this:
But that’s a big maintenance burden, hence why we’ve stuck with the plugins model for asdf. We’re now approaching 1k plugins for asdf, so I don’t see how @jdx plans to replicate that on his own.
mise won’t use any third-party asdf plugins by default. I wrote this doc that explains how it works: https://github.com/jdx/mise/discussions/4054
And that doc was discussed here three weeks ago.
My next blog post is going to be running benchmarks against the new Go code. I want to see how the Go version and the Bash version compare. Go is faster by a lot.
asdf is going to be slower than mise at the time of execution because mise doesn’t use shims. But asdf is zero cost when starting your shell, whereas mise actually has to run code to compute the proper value for your PATH.
Have you considered doing mise’s strategy, now that computing that PATH should be way faster in Go?
Apart from optimizing either initialization or execution, any other remarkable difference? I’m imagining that the shell integration with shims should be way simpler than detecting when the PATH needs to be updated during the shell lifetime.
I’ve not considered it, no. I believe shims are better.
The biggest challenge with shims is regenerating them as needed, and the overhead of executing them. The rewrite greatly improves performance of these operations, and should allow us to make future performance optimizations as we have time.
Why is this a risk? As a nix user we’re often working with quite long and large PATHs and I’ve yet to notice a problem from them.
I tried mise a while back, and the main reason I went away from it is like you said, it does too much. It tries to be asdf, direnv and a task runner. I just want a tool manager, and is the reason why I switched to aquaproj/aqua.
Asdf seems a bit overloaded: https://asdf.common-lisp.dev/ vs https://asdf-vm.com/
My guy the more recent of the two is 11ish years old, you are simply too late.
I shall declare the name of my new scripting language, Lua! The last version of the other Lua was months ago! Surely there will be no confusion!
eyeroll
You misunderstood. The first project started in like 2005, the second in 2014. They both have over a decade of use and both continue to be used. Neither is gonna be renamed.
Hope that helped.
No. I didn’t misunderstand. Yes, both have continued to exist largely without problems, but the fact that we have two, independent, package managers named “asdf” is just stupid. In 2014, a quick google search for “asdf” would have easily found asdf for Common Lisp. Why’d we get here in the first place?
If it wasn’t another package manager, I’d be more inclined to not care. But, come on.
And yes, the ship has sailed for asdf — but my Lua will be a general - general scripting language! It’s not just a general embeddable scripting language… No. It takes scripting languages to a whole new level of general-ness!
edit to say: 2005 actually seemed too late. Turns out asdf is 24 years old.
If you didn’t misunderstand my comment then you misrepresented it. That’s worse. Please stop trying to score points on people.
Neither project advertises itself as a package manager.
It’s true that asdf for Common Lisp is not a package manager — it’s a build tool that… creates packages.
The other asdf swaps out “runtimes” … a so called “version manager” allowing you to ensure that the right set of tools are being used when you go to develop, build, etc. It can install runtimes, and it can remove runtimes. I mean, I don’t want to go against the wishes of the author… but if it looks like a duck…
But, I’ll choose to concede to your point that neither of these are de facto “package managers,” but it’s hard to argue against the fact that they are in the same general purpose space.
Yes, I remember circa 2008 or 2010 when Faré revamped it as asdf2. But what’s the point? So there’s a namespace collision across two systems. No Lisper is going to mistake it.
I will not claim to be a Lisper, but having used neither in anger I was for a time under the vague misapprehension that there was only one asdf and that the Lisp one could be (ab)used to install non-Lisp things, kind of like pip sometimes is.
I fully admit this was an entirely a me problem and if I ever tried to use either my confusion would have been resolved, but there is my sample of 1 on the confusion being possible.
Oh, good, it wasn’t just me!
The point is that if you’re starting a new project, maybe do a quick search to see if something else by the same name is already established? This isn’t hard. It’s common courtesy. I don’t see why it’s controversial?!
For kicks I checked Wikipedia: asdf has even had a Wikipedia page since 2007.
Sure, I agree and would do the same, but someone didn’t and they made free software and put it out there for other people to use and continued to maintain it. I can’t get my nerd rage on about the accidental reuse of a project name.
Wait until you find out that Java was named after a coffee which was named after an island. Or that Python was named after a comedy skit which was named after a snake. And don’t get me started on Go or Rust or Ruby! It’s a miracle that we can get anything done in the software world with all of this semantic ambiguity! May we discuss nothing else except this endlessly fascinating topic until the end of time! /s
You really got me… I’ll give you another, the function
carin Lisps always confuses me with thecarthat you drive on the road. Surely we must move to unique identifiers every time we need to name something! /sOr, you know, you can just stop naming the two things in the same category of things the same name. That might work. The lack of common decency is crazy.
Obviously taxonomies are arbitrary and subjective, and a runtime version manager is not obviously in the same category as lisp build tooling. You could argue that they are both in the category of “software” just like you could argue that Rust (programming language) and Rust (game), yet people on this forum don’t routinely drag that up in every post with the
rusttag because there’s obviously no such moral prohibition against using pedestrian names across multiple software projects.The melodrama and bike-shedding are crazy.
Yeah, I was confused for a bit. This asdf-vm, from my reading, it’s like SDKMAN combined with <your lang’s hacked up env tool here> built in.
This doesn’t really explain what ASDF is or does. Nor does the project web page.
I vaguely recall reading about it some years ago in the context of Lisp and Common Lisp, but this seems either to be something different or a sibling.
Can anyone explain what it is to a non-specialist?
asdf is a package manager dedicated to installing multiple versions of the same software and choosing which version is active. The packages it supports installing are mainly language runtimes like
python,ruby,node,go, and so on.In any particular terminal with a particular working directory, running a tool such as
rubywill run only one of your installed versions. asdf doesn’t just have a global setting for which version this is: it can dynamically choose the correct version based on files in the source code of a project. It might find the version in an ecosystem-specific file that contains the language version, such as.ruby-version, or in asdf’s own file.tool-versions.asdf was created to replace similar tools that manage multiple versions of only a single programming language. Examples of these tools: nodeenv, nvm, n, rvm, chruby, rbenv.
This asdf is a totally different project from the Lisp asdf, as discussed in this sibling thread.
Thanks! That was much clearer. I appreciate the explanation.
It’s a package/version manager for various development environments. For instance, you can use it to install different versions of nodejs, and switch between them. There’s a pretty wide array of plugins for it; most things you can think of are installable via asdf.
Thanks. TBH as a non-programmer these days I only understood a little of that, though…
Ah sorry, I didn’t read non-specialist as non-programmer. Sounds like you got it from the sibling though :)
Congrats on the rewrite! I’m a user of https://github.com/asdf-vm/actions and can only switch my dev-side if my CI-side is also switchable. Is there any consideration for updating the actions repo? Or will it transparently switch over to the new version?
Interesting, but:
Was one of those things spawning in the background? Sorry, I’m not familiar with asdf, so genuine question. I found when tasks are very parallelizable we can just let the OS handle running them all in the background so that to the user it looks like they’re done at once. Eg https://github.com/oanda/git-deps/blob/501a93e197f83275797a3f09d50f0e3f49de922c/git-deps#L98