lambdanil / nix-problems

The many issues plaguing Nix

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Introduction

Let’s talk about some of the issues with Nix and NixOS, and how Guix does these things better. I’ll say upfront that you shouldn’t expect tons of examples - this is a fairly quick writeup, though I might come back later to revise sections and add more points.

Internal design issues

Internal inconsistencies/issues

Build system issues

Guix uses so called build systems - these ensure consistency in how packages are actually built across different toolchains and language ecosystems.

  • Each package ecosystem has its own build system. These define certain dependencies and standard procedures used for handling packages within that ecosystem.
    • Examples would include the Maven and TeX Live ecosystems.
    • This ensures consistency within these ecosystems.
  • All of these build systems are in a single place (see points below) - this helps keep the different build systems consistent in behaviour.
  • Combined these ensure global consistency in the approaches used for handling different toolchains across all the definitions.
  • Nix does have build phases, and even something similar to build systems, but…
    • These build systems aren’t documented anywhere, at least as far as I could tell.
    • They are scattered all over nixpkgs.
      • This makes the entire point about consistency void.

Language issues

  • All Guix package definitions are written exclusively in GNU Guile - a Scheme implementation
    • While system calls do need to be invoked for certain builds, it’s done exclusively with Guile too.
      • There is a mature and well documented set of different build utilities used to do this.
        • These also make package transformations more straightforward using the flexibility of Scheme macros.
      • For example rather than calling a sed within a shell script like what Nix definitions sometimes do, Guix uses the procedure substitute* instead.
        • This keeps build scripts consistent with a single set of build utilities and a single language.
  • Now for the Nix language.
    • It’s poorly documented.
    • The tooling is lacking, in part because it’s used pretty exclusively for Nix.
    • It isn’t particularly good as a DSL (note: domain specific language). Why?
      • A proper DSL is not flexible enough for functional package management, so it was an uphill battle from the start.
      • It’s too complicated - the main point of DSLs is to simplify configuration.
      • Quote from the “inventor” of the language 1:

      TLDR: the Nix language has all the problems of a general purpose language (namely too much expressiveness, allowing people to build new abstractions that make it harder for other people to understand their code, and making evaluation slow), while not having the features you would expect from a general purpose language, and at the same time not having many domain-specific features (indeed string contexts are one of the few). So it’s not that great as a DSL or a GPL.

    • It isn’t good as a general purpose language either (no libraries, no interest in using it outside of Nix).
    • There exist attempts to address these issues with different languages, for example Nickel has such aspirations.
      • I recommend reading this blogpost, it goes over some of the issues of Nix.
    • Guix addresses these issues by using a language that’s properly general purpose and more flexible with its very powerful macro system.
      • Guix’s init system, GNU Shepherd is also written in Scheme, along with the entire CLI interface and every other part of the Guix system, aside from the daemon - further proving it’s capability as a GPL.

Debugging

  • Nix is also known for being rather difficult to debug (see discussion here).
    • Recursion is used heavily - in practice this makes stuff like copying objects rather difficult.
      • Infinite recursion can be difficult to debug and is rather easy to introduce - see below.
    • https://nix.dev/anti-patterns/language

Package QC issues

  • Nixpkgs commits aren’t signed - see NixOS/rfcs#100 (at least it’s being worked on… slowly).
  • Overall quality of definitions in Nixpkgs isn’t always great - many R packages are autogenerated and thus broken.
    • Many packages also aren’t bootstrapped properly, instead patching and repackaging .deb packages and the like.
    • These is a ton of patching going on to resolve FHS incompatability issues (Guix is also affected by this).
  • Nixpkgs is unreliable - this speaks for itself…

Missing features

First of all grafts. What are they?

Grafts are Guix’ way of not rebuilding the world when an important security is rolled out. Basically, they allow you to build and link against old versions of a library while running the program against a new one. Traditional distros do that all the time and you don’t even notice, but on Guix you actually have two versions of that library still lying around. The ungrafted one and the grafted one. – Guix documentation

To my knowledge Nix has no such thing.

Nix also doesn’t have an equivalent to ~guix pack~.

  • Nix does in fact have nix bundle now as a part of the flake CLI (thanks again to dali99 for the correction).

User experience issues

Documentation

nix-env

  • nix-env is considered bad by a big part of the community (1) (2). Yet the documentation doesn’t mention any of it’s shortcomings and it doesn’t exactly have a great replacement.
    • nix-env has a problem with RAM usage, it’s extremely inefficient.
    • What should we use instead?
      • flakes are experimental and not all too well documented (1).
      • nix profile isn’t quite a 1/1 replacement and lacks documentation (1).
      • home-manager? Has it’s own issues. It’s also not well documented.
        • besides that, some people don’t want to use it - using an entire complex system like this to replace nix-env is silly.

Generally bad UX

  • Many tools are considered deprecated, yet are kept around for legacy compatability and referenced in the documentation, or they don’t have good replacements (see nix-env section above).
    • Searching for packages can be done using nix-env - but it’s extremely slow as it lazily evaluates the entire package database.
      • There’s a new experimental method, it’s better as it uses caching but it’s far from perfect.
      • Guix has a proper search implementation.
    • The CLI experience is bad (this issue is closed, but it’s far from resolved in practice) - many different tools all behaving differently, all with their own pitfalls and “gotcha”s.
      • There’s usually multiple approaches for one task.
      • There’s third party tools trying to clean the experience but many of these only make the issue worse by further splitting the efforts. (1 2 3)

Conclusion

WARNING: opinionated conclusion!

Overall Nix is a very flawed piece of software and far inferior to Guix. Years and years of technical issues plague the project and there seems to be little interest in actually resolving these issues. Guix is comparatively much newer, yet the UX is much better and there are constant improvements in many areas. It also has the advantage of being built from the ground up with a clear design mind.

This isn’t the complete document, I might come back and add more - for now I have already spent too long on this, and I think I outlined many of the issues rather clearly. If you find incorrent information please contact me and I’ll be happy to correct myself :)!

About

The many issues plaguing Nix

License:GNU General Public License v3.0