It's amusing that nixpkgs contributors have spent thousands of human-hours to craft a module system suitable for patching and wrapping any piece of software to accept static configuration, but NixOS, home-manager, and now json2dir end up producing an activation script which litters the filesystem with said configuration.
Everything runs just so much better if the binaries in your profile are wrapper scripts that essentially run "program --config /nix/store/<hash>-program.config". Each file that needs to be copied or symlinked to a "blessed" location in the global mount namespace via an activation script is a failure opportunity, which breaks the atomicity of profile activation and leaves you (or some complicated logic in NixOS/home-manager) to clean up the mess.
Even in the case that a program cannot be patched to run this way, it is easy these days to bind-mount into a clean namespace via bwrap or similar. Alas, shared libraries are kind of the Achilles' heel of this approach.
This is a legitimately hard problem (as an `emacs` user on NixOS I see both sides of it and their merits).
NixOS is directionally the future but the implementation is self-crippled by ideology in a few important places. There is absolutely no reason why `buildFHSEnv` couldn't come by default rather than `/sw/` or `/run`: links into the store are links into the store, putting them in a place that breaks everything? That's incompatible by design and you know it's intentional because symlinks are cheap you could just do both!
Ditto `nix-ld` being necessary, it's a great piece of work but the dynamic linker should be in the normal place and know about all the libraries on the system by default. It's possible to do this in my NixOS modules? `uv add flash-attention-blah`? Works without any trouble on my machine. But it was a super pain to set up that most people won't put up with.
`home-manager` is awesome, it pioneered a bunch of great stuff, but it's not maintained with the vigor it once was, and some dated ideas got wired in really deep. I still run it, and I probably will forever because it slays at some stuff, but that's the nice thing about symlinking into a a store! I can use it where it works well, and use other stuff where it's trouble. This is the magic of NixOS. The next thing I'm trying is https://github.com/outfoxxed/impurity.nix, which comes highly recommended by heavy Nix people I know.
I think it's time to just update NixOS to run things properly by default. It can be done with zero sacrifice on real pure builds and caching/substitors working properly and all of that. I sometimes call Nix "advanced alien technology that was badly damaged on crash re-entry". @jade is a boss and says kind of the same thing a different way.
But again, the beauty of NixOS is that you can do this yourself, an overlay is a pure function from the world as it is to the world as it ought to be.
EDIT: I know talk is cheap and code wins arguments, and I know this is about a year overdue and not released yet, but it's got beta testers now, it's coming: https://gist.github.com/b7r6/721f62d6431c77b64592a55706d87fd...
> Ditto `nix-ld` being necessary, it's a great piece of work but the dynamic linker should be in the normal place and know about all the libraries on the system by default.
Isn't that part of the point of having NixOS? Dynamic linking into whatever seems best from the nix-store sounds handy until you realise it's just going back to a regular mutable distro where the state is whatever and build instructions start looking like "install all these libraries and cross your fingers just in case" and "works on my machine"™ reigns.
There's a range of options on this and numerous good mental models for it: flakes are "dirty", Haskell does things in a very granular regime of mutability bounded context combinators, NixOS has to cope with changing hardware (NixOS modules at the absolute apex of "official"-ness escape hatch it, you have to be pretty explicit to get a reliable pin of the kernel, I'm running `linuxPackages_testing` on this machine I'm typing from because I'm setting up a 5090 and need "the newest one" on everything: 2 months ago? 6.16-rc3, today: I think it's 6.17-rc1 or something, haven't looked).
So, much like a `nix flake check` might fail and you want your CI to flag that, a `nh home switch .` might be necessary to get the editor you need to fix the fail. Functional programming has decades of consensus on every possible variation of this.
There are any number of things you could do here (and the message linking you to the `nix-ld` website is an improvement over `libstdc++.so.6 not found blah`). But breaking a library that statically links everything NVIDIA ever wrote precisely so that it will run anywhere because you have a canonical `CC` in your own `NIX_` environment variable prefix set and you just refuse to let grubby ubuntu software see it?
That's incompatible by design. // hypermodern // nixos has a principle that I realize isn't in the `README.md`: it's never incompatible by design for no upside.
I agree and worry about that idea https://fzakaria.com/2025/07/07/home-manager-is-a-false-enli...
Meanwhile, more and more software are turds that insist on overwriting their own config files :-(