We see bias with most discussions.
Only cons with Guix I see is, lack of infrastructure and less volunteers to work on guix eco-system. If its solved, I can imagine guix can improve exponentially.
We see bias with most discussions.
Only cons with Guix I see is, lack of infrastructure and less volunteers to work on guix eco-system. If its solved, I can imagine guix can improve exponentially.
Edit: Just to provide a measurement, on my Framework 13 with AMD Ryzen 5 7640U, a `guix pull` which pulled in 1 nonguix commit and 64 guix commits took 2m10s, and a subsequent no-op `guix pull` took 1m18s.
> My goal was to take my Unchartevice laptop with its strange Zhaoxin x86_64-compatible CPU...
> Sure, this is a laptop with a CPU broadly equivalent to old Intel Atom CPUs...
Yes, guix pull is slow, but the author is using some old/exotic hardware. The last time I tried guix on a 5th gen dual core i5, the initial pull was not that slow. And as other commenters have pointed out. The first pull is the slowest by far.
Nix is pathologically recursive, lazy, and uses fixed points, things that are very apt to changing something that cascades through a bunch of dependents. Nix's runtime is not magic. Guile should be able to expose a language and evaluate it in a similar way.
For my part, I've not opted into Guix because it's a GNU project, and I've decided to avoid anything in the FSF sphere of influence. Their orthodoxy turns off contributors and they have a history of taking insular hard-liner approaches that are utopian. Outside of coreutils that are about to be fully subsumed by rewrite-it-in-Rust (which has a community that is not a fan of the GPL), what has had FSF backing and been successful? Linus starts two of the most influential pieces of software in human civilization and RMS wants to name the awards. The pragmatic culture that shifted away from the FSF has I think largely adopted Nix, and it shows. Nix is open for business, available on lots of platforms, has commercial entities built around its success.
The article focuses on a comparison between GUIX _system_ and NixOS. It would be interesting to see an equally thoughtful comparison that just focuses on GUIX vs. NIX as package managers used on another Linux distribution (e.g. Debian.)
In this case, GUIX might fare better as you won't have to worry about the complexities introduced by binary blobs needed for boot, etc.
If you forgo the built-in WiFi, the ThinkPad T440p (Haswell) works fine without any blobs (speaking from experience). I think all newer gens need iGPU blobs, sadly, but I wanted to point out a viable middle ground between modern Nvidia gamerware setups and Librebooted X200s that can barely browse the web.
> The thing is, I'm not actually sure if Guix's better documentation helps smooth the onboarding in any way because you have to already know Scheme, which is a more complex language than Nix.
LMAO absolutely not. Nix-the-language is the worst programming language I've ever had the misfortune to interact with. I picked up Scheme in about 1 day during a class in college. It's night-and-day different.
GCC is still indispensable. I doubt it will be rewritten in Rust any time soon.
Nix-the-language is just a subset of Javascript with built-in laziness and a slightly different syntax. An absolute bog-standard and mainstream way of thinking about programs in 2025.
That said, Nix-the-language also suffers from all the same birth defects that manifest themselves in frontend development.
I feel the same.
The multi-line strings and string interpolation are both really nice. Unfortunately a lot of the text being munged is bash and usually already ugly, so the result is double-ugly.
The functional aspects are okay. However, as an expression language and being primarily used in a declarative way, it is frequent to have almost no idea what's going on in Nix. Reading the code and understanding the evaluation are extremely far apart.
callPackage... It's something I thought would be cool in a language until I actually experienced the depth of disorientation it can cause.
The remaining syntax has a lot of "but why?" where it just seems to do its own thing relative to other languages, which makes it harder to get into a rhythm.
Some of the subject matter is the real culprit. The cross compiling sliding window thing... I've studied it several times. If I had to actually do something with it, straight to the LLM. Compilers have targets.
That must be it. The GP's comment really resonated with me, in that learning scheme felt like no task at all whereas I STILL feel uncomfortable with the nix programming language and ecosystem despite using nixOS exclusively on my personal laptop for two years and on my work machine for about half a year now. I've always fumbled over frontend / javascript development though, and avoid it as much as I can at work although I still end up working in it every year or so.
Nix only won out for me because of the mac compatibility, without which I can't really use it at work
- flake inputs are not fetched lazily.
- flakes are somewhat restrictive in that you can't override an input with an arbitrary value. This matters if you want to pass in, say, a specially configured nixpkgs object. In practice, for non trivial use cases, flakes fail to solve the problem they set out to solve. Most flakes expose lib functions for these advanced use cases but that's pretty much equivalent to what you get with non-flakes.
While that may be true, it is particularly the case for nixpkgs; i.e., you may imagine a contender to nixpkgs that is less tangled.
I’ve recently enjoyed reading on research into simpler alternatives; GrizzlT’s deep-dive into nixpkgs design patterns, and nrdxp’s atom format:
Highly doubtful to happen anytime soon.
In each case, development is the work of the developers, and they themselves deserve most credit. But the FSF and the GNU project have certainly been involved with lots of software that is important, widely used, and works well.
GNU software is still responsible for huge and often critical chunks of the stack in most Linux distros.
Annoyingly both fail at basic stuff like falling back the graphics card, something Debian had solved 10 years ago, no configs needed, no matter Intel/NVIDIA/AMD. Even without the correct driver or firmware falling back to VESA or fbdev should be a given. Never had so many black screens as now. Even Windows has done better job at giving you a basic resolution while you install the drivers
Or maybe it's just the state of the Linux ecosystem, with the introduction of Wayland and NVIDIA open drivers, causing regressions
Also the unintuitive inverse of traditional package management, where if you want to update one package, all the system updates by default
Which increases the amount of bugs, having frequent updates to a stable system
To make it better you can add 2 channels, and call them nixos-stable v24 nixos-latest v25, keeping most of the system one version down increases stability a lot
Of course the incorporated Grub boot build choices is great to revert back to a working system
I really like the the separation Guix makes on having close source being a concern of a separate project
But both of them are equally easy to install open source only or include proprietary
Like what?
My list of Nix language nits is relatively small, would like to understand.
One thing that seems under-developed is smart merging. There is // at language level, but then if you want datatype-specific merging, you use functions. That itself is just the power of functional programming. But as it is with untyped languages, you end up doing the same thing slightly different in several places, and a fractal of accidental complexity starts to appear.
> I had to use nonguix to get internet working on the machine, which had very immediate technical effects that bring me to
Stuff like this will
The main reasons I’m interested in guix:
- it uses a known-good language (lisp)
- IIRC it is more repeatable (the contents used in derivations play into the hash).
- It has a full source bootstrap
Maybe someone with a focus on improving UX needs to build one of these afresh.
Lean and agile theory says that quality is improved and efficiency gained by going upstream and eliminating the things that are producing poor quality in the first place.
Llm code tools may be useful to give syntax tips, but like a thoughtless dev on a team, likely introduce more work than they get done.
Maybe https://codeberg.org/amjoseph/infuse.nix would be useful? (I find it intriguing, but haven't yet faced a use-case that seemed worth learning it)
I've heard people say "JSON with functions", but I think this is much too generous.
- Functions can be called without delimiters
- AttrSets have lots of delimiting, very explicit syntax
- Lists have absolutely no delimiters again
foo 1 2 is a function call, right?
So if I need it in a list, I can just write: [ foo 1 2 ] right?
Note, we pathologically put spaces around lists in Nix because we are subconsciously sure that something is about to bite us.
[ foo 1 2 ] is a list of three elements, not a function call.
I forget which terrible thing I was doing, but I had a variation of this syntax trap in my code after naively moving the expression into a list. The error message was, as usual, from the Turtles in Time dimension.
The mixture of super explicit and implicit delimiting as well as borrowed ideas like \\ and invented ideas like with and import just make Nix feel like it's all over the place, inconsistent, and doing its own thing when we already had a lot of functional languages to work with.
The evaluation model is completely appropriate for the problem yet pretty unique in programming generally. It has a lot of new ideas that throw even seasoned people well off track. Each new idea is not much, but they compound into not having any idea what we're looking at and watching 50k nixpkgs evaluate just fine while not being able to read any of that code at all.
I'd prefer something like Haskell, Lisp, or Clojure, but please just one. Using Scheme in Guile is a great choice. It's so much easier to read. Hopefully the macros can be developed to bring the best of lazy evaluation into Scheme and fix the runtime issues.
Check out the spice: https://users.rust-lang.org/t/im-shocked-the-rust-community-...
Ultimately we're taking inputs, making derivations and calling some nix specific library functions.
It feels like we should be able to do that with a Python library that would have the major advantage of being step debuggable.
The problem is that you're very rarely exposed to it directly. You are always multiple layers of abstractions away from it. Most of these layers are completely undocumented.
Two major and immediate reasons why the pulling is slow are clear and fixable:
1. Guix will try to substitute from unreachable caches for a LONG time before giving up, and Guix infrastructure is less developed than Nix. When I kept experimenting after this post I set up https://mirror.yandex.ru/mirrors/guix/ eventually which fixes the substitute problems for me (Guix mirror on bigcorp infra).
2. Guix by default pulls its channel from GNU Savannah which, for some reason, is incredibly slow in serving git. The project moved over to Codeberg, and setting the URL to there significantly speeds up pulling.
In NixOS, channels (esp. the unstable ones) advance when CI finishes building a certain subset of packages successfully (this is what https://status.nixos.org/ shows). CI populates the binary cache, so this means that a channel HEAD always has a large number of packages available in the cache. Guix has no such guarantees, so updating to any latest commit might even yield one where you end up rebuilding all of its Scheme from scratch or whatever. Picking a commit that's a few days old helps with this.
I eventually switched to a laptop with a "normal" Intel CPU, and pulling did not magically turn fast. In fact, some of the slowest stages (there's one where it says "Computing Guix derivation") don't seem to exercise the CPU much at all. I haven't spent time looking at why (yet).
Guix System does a lot more per-user stuff than NixOS by default, which means that you'll likely end up pulling multiple times.
Pulling remains a much slower operation than Nix evaluation in any case.
There's a few ways to make this all more palatable (e.g. the `guix time-machine -C $channels` setup), but those might be for a follow-up post in the future.