After a lot of hesitation and energized by a work incentive, I tried Nix last week.
I've followed the official docs, had to resort on Google et al. quite quickly to solve mundane problems (installing a channel is not on the default path of the docs for the new learner), and after much wandering and trial and error, I evenrially went to the discourse and asked what I should use between flakes, nix shell or develop... Every single answer was 1/extremely informative and nice 2/ crystal clear that Nix was in a confusing, in-between stage in its life cycle.
I very much appreciate the community and efforts but I work for a company that cannot afford the commitment that Nix requires right now. I will happily come back in 2 years and reevaluate.
I am working on the Nix project; resolving this "in-between stage" is our highest priority at the moment. I'd like to better understand two independent things:
1. What were the drivers and motivators for you to try Nix? What did you hope to achieve?
2. Was the current experimental status of the new nix CLI and flakes the primary cause of the confusion?
Thanks for your interest, it really confirms the interest I've received from the community in general.
1. I'm leading some Platform Engineering projects at my company and one is focused on Developer Experience. We have a wide variety of configurations on the engineer's laptops and the development environments are not normalized. That causes a lot of noise and pain, as one knows. Nix is, or seems to be, an opportunity to take back control on how engineers run the applications locally.
2. I'd say it has many factors. The official documentation and guides are not yet suitable for a zero-knowledge newcomer. As an example, since channels are still recommended in the docs, the command to add the default channel is not in the "Install" page. Things go from `curl <(...) | bash` to `nix-shell`, and it fails (on a M2 Mac) unless I navigate somewhere else on the docs to find that I should add the default channel first.
Second point is about the terminology. Derivation, Flakes... are quite arcane terms. At least to the layman (me).
Third, community blogs etc are covering outdated versions, some rely on flakes, others not, it's understandle but also understandably disorienting, especially when you're after some guidance that the official docs could not provide.
Fourth, the API. `nix-shell` is not a shortcut for `nix shell`. Wait what?
---
When I'm saying I'll come back in 2 years, I mean that it is clear that the situation is changing rapidly and dust needs to settle. Maybe the direction is not clear yet, and that would be fine. My one and only advice would be to only ship a feature that is properly documented.
Reading something like "We recommend to use flakes, they're the future, but the APIs are in flux, but if you're wary and want stability, here are our stable APIs" would have saved me a ton of time.
It's not about ‶controlling the machines″, it's about running `nix-shell -p our-project` and having the same setup on my OpenSuse than Jack on his Arch, Herman on his mac, Johann on her Debian, and our prod environment on RHEL.
That's a force multiplier in dev & prod, not a hindrance.
> Developer machines are not something for you to “have control” over.
That's exactly right - you want developers to set there machines up however they want. You also want a controlled enclave inside that, that is automatically set up and works consistently to make engineers lives easier and more consistent.
One approach people have taken for this is to use docker - a container with all the tools built in. Run the build commands inside this, problem solved. Using Nix achieves something similar, but with some benefits over the docker approach.
You're right -- but it's even worse DX to have to check a ton of different files, parse the outdated english documentation, guess, ask people, and hope that deps were frozen. Especially for old, mostly abandoned projects.
I've started using direnv to switch node versions for projects, based on already-existing CI configuration files, and it's fantastic. Having a full, working, stable development environment that can be shared among the team (amd future teams doing software archaeology when something breaks!) is my holy grail. I'm really excited about the future of nix.
But you're right that at the end of the day, devs should retain control. I think having clear, machine readable instructions for how to set up the environment enables that control. Forcing them to use the blessed config is not necessary. HAVING the config lets you know what you need to set up, your own way.
The only place such strict control needs to happen is in CI/CD, which just falls out of having the dev setup done.
Maybe I phrased poorly, but you didn’t try either.
Believe it or not, but the project emerges from the devs themselves, it was not even an idea before they spoke up and we had to make it a project, to support them.
a) First was a personal use to carry my dotfiles/home config everywhere (office mac, home mac, virtual machines). Ended up configuring a flakes based home-manager setup.
b) Second is trying to get good devshell experience for the whole team. Especially in a monorepo setting with multiple languages and tools. Right now there is tons of setup required including installing right versions of java, python, nodejs, lots of instructions to get right python version, poetry install, setup aliases etc.
2. No, it is not. It didn't take much of research to conclude flakes are the way to go. Honestly, I am confused by so many responses about confusion between flakes and non-flakes as I don't think it take much effort to realize flakes are the way to go even if it is experimental.
Though, to be fair, it does hurt that two of the recommended resources - nix.dev and nix pills - do not cover flakes.
Disclosure, I tried it in passing about 2 years ago.
> 1. What were the drivers and motivators for you to try Nix? What did you hope to achieve?
(a) Reproducible dev environments. I worked in a company back then had a big mix of different projects: Elixir, PHP, Java, JS, C#. We wanted everyone to just `cd` into a directory and have identical tools, versions of languages / DBs, everything.
(b) Ability to do transactional-like upgrades or downgrades of various pieces of software.
(c) Isolate software that usually pokes deep in the guts of the system or the user's home directory. PHP and JS were the main offenders here, especially with PHP on Linux (and Apache2 integration) you had to modify a good amount of files in various non-home-dir places. And JS is, well, JS, NPM's global `node_modules` directory is a horror to behold as we all know.
The experience was mixed. While we had one guy who was super invested in Nix and made sure to help us all install it and set it up, the day-to-day experience was lacking and people had to find ways to "repair" their setup after a few small upgrades of software. It felt like a chore. Sorry I can't give you more details but for us back then the main goal was to reduce the chores, not invent a different kind of them.
All in all, I'd say points (a) and (b) worked somewhat okay, while (c) we definitely didn't feel it did so we just migrated to Docker for some of our workflows.
> 2. Was the current experimental status of the new nix CLI and flakes the primary cause of the confusion?
Again, my take is outdated, but as a burned out senior dev my criticism boils down to the following:
I don't want to care about "flakes" at all. I want all tools to dispense with the cutesy pun-y terminology already and realize that people use them for work.
Give me one `nix` command with subcommands and good help outputs (and good centralized docs website). Reference: the `borg` backup program, also `git`. Before Nix gets into that state I'll not recommend it anyone.
---
I am in no way attacking you or disparaging yours and others' work but to me and my team back then it felt like Nix simply replaced one complexity with another. What drew us in was the promise of less complexity and that did not materialize.
I feel the general user experience is often lost on maintainers because they live and breathe their tool and to them the workflow is second nature. That's why I wrote this reply. Hopefully it brings some perspective.
> 1. What were the drivers and motivators for you to try Nix? What did you hope to achieve?
I wonder how many people would honestly admit "I see it mentioned in a lot of comments/headlines from articles posted on HN and I assumed if it is good enough to be mentioned, it'll probably solve a problem I didn't know I had"
I don't disagree, but where do you draw the line from "curiosity" to "I'm letting the herd think for me and anything they dictate as interesting, I am a victim and I must investigate it because they said so"
As a developer, in my personal activities, I don't draw the line.
As a developer, in my work, I work with others to collectively agree to be on one aide or the other of the line. Even when we're retrospectively wrong. Sometimes, you can't know.
I'm hesitant to write this as I don't know if you'll see it but I feel like what I have to say is different to the opinions that have been voiced so far. I will only answer for point number one.
I personally feel that Nix documentation and community blog posts sits on a gradient of theological meanderings about functional purity to actual praxis.
For one, I'm a systems engineer. What drew me to Nix was that I wanted a next-gen Ansible. A piece of software that can be used to reproduce a hosts OS state in an immutable way. For now, my homelab and laptop is all NixOS driven. I use deploy-rs and flakes to configure hosts. I can code but am not really a software engineer by trade. This is where I'm coming from.
Within the context of my established skills, Nix's documentation is awful. There were/are actions I want to accomplish that sit outside of the paradigm of Nix and when I try to accomplish those actions I feel lost.
For example, my main homelab machine has a Nomad server installed. The default Nomad package from Nix packages just installs the binary. So I needed to handle creating its data directory, its configuration, and laying down a systemd unit file. Where I got stuck was creating the data directory. I could accomplish the systemd configuration and the configuration file easily enough but I don't know how to create a directory outside of a derivation. I also don't know if a derivation is even needed.
But I also don't really know how to fit a derivation in my current flake setup so that it's processed when I change host state. I ended up solving the problem by having systemd manage a StateDirectory and creating the unit file/Nomad conf in configuration.nix for the machine. I also don't known if a derivation would even be what's needed. Do I use an overlay to extend the Nomad package? Can I ad-hoc create directories and then shove that into a module?
My point being is that system administrators, network engineers, release engineers, etc are all different types of engineers that would be interested in Nix... but they are NOT functional programming enthusiasts. I think Nix gets attention from a lot of people who are comfortable with Linux, package management, build processes, and configuration management systems like Ansible. But there is no clear runway for those types of engineers. Hell, NixOps seems to be an abandoned repo that has no documentation whatsoever for it's 2.0 release and there are dozen different projects for remote deployment to hosts.
If I took a sysadmin and told them "please codify OS state using Ansible" then they're likely to come back with a solution that could satisfy a technical need within an organization. If I took that same sysadmin and told them to use Nix to solve the same problem then they're likely to get lost for weeks.
It seems this is where a better description of what NixOS (and it's module system) is. My suspicion is that by starting with NixOS it is harder to be introduced to the simpler concepts. It is best to think of the NixOS modules as a domain-specific-language on top of Nixpkgs which is itself a large set of conventions on top of the fairly simple Nix language. I think people should be introduced from the bottom up.
> having systemd manage a StateDirectory and creating the unit file/Nomad conf in configuration.nix for the machine
Seems like you did get what you needed working; my best advice to understand that the key abstraction being created is the activation script. Perhaps we never clearly describe all of its moving parts and how it works?
> ... but they are NOT functional programming enthusiasts
I believe the key is for the Nix community messaging/marketing to focus less on the theoretical elegance and more on the practical benefits.
> Nix was in a confusing, in-between stage in its life cycle
That's what everyone says about software that is just too complex.
I tried Nix for the first time yesterday and had a similar experience - it was just too buggy, too brittle, and too difficult. It's absolutely not worth it. The software was built to solve a difficult problem, and maybe it does that, but it became a difficult problem in itself.
For example, if you Ctrl-C while its downloading an update, you get in a weird state where nothing works. Ok, so just uninstall and reinstall right? Well, there's no uninstall. You have to manually delete everything and remove the /nix mount. Its 2023, why am I having to hunt all this down? Sure, if you reinstall it it tries to do that, but it fails every time, or it just misses things. I just don't have time for this. Nix is not even close to ready for production.
> For example, if you Ctrl-C while its downloading an update, you get in a weird state where nothing works. …
There is a new Nix installer from Determinate Systems, a company heavily invested in Nix, which should make installing Nix more atomic, reversible, and thus easier:
Interrupted updates don't do that. In single-user mode you could maybe ctrl-c it during the final activation phase, but that's a small fraction of a second -- it's just replacing a few symlinks.
In the default multi-user mode, you can't even do that.
Yes. This is like a major benefit of nix(os), updates and everything is basically atomic. If you interrupt an update you will just have a few more downloaded folders in your nix store folder, which are trivially GC-d on the next run. This is unlike pretty much anything else.
> For example, if you Ctrl-C while its downloading an update, you get in a weird state where nothing works
Heh? Oh you mean like during installing it for the very first time? Like, what do you expect from a bash script? Is bash not ready for production? That’s quite a strong statement when you didn’t even manage to install the thing… like, at least give it an honest try before you reach such a conclusion.
To be fair, I don't think it's such a huge sacrifice from the maintainers to put a check for leftover artifacts at the start of the installation script and nuke those from orbit before proceeding.
It can be put behind a confirmation Y/N terminal line as well.
But yeah, usually bash install scripts are almost never idempotent. I feel the maintainers of those scripts just give up and IMO they really shouldn't.
I don't know if this is what the GP experienced, but you can definitely get some inconsistency if you ctrl-C out of Nix while it's in single-user/daemonless mode. My sense is that single-user is really only meant as a toy and for use in unprivileged containers— in basically every other situation you want to be talking to the nix-daemon, which maintains proper state and won't get interrupted.
My problem space (building ROS packages for robots) is difficult enough that it was worth it getting over that hump for me, but I totally understand this perspective.
I'm hopeful that in two years, the community will be much more aligned around flakes, and the docs (at least the onboarding parts) will have a much clearer "happy path" oriented around accepted workflows like direnv and home-manager.
Nix is simple to the people who made it because they won't get confused and make mistakes. If you make a mistake, you can put it in a completely broken state. That is not a simple piece of software. Its overengineered and brittle.
Homebrew is an example of a simple piece of software. It just works.
> Homebrew is an example of a simple piece of software. It just works.
But, it doesn't. I've had many packages fail to build from homebrew. Also there's a recent quote I remember:
> At some point I got frustrated with homebrew because I felt like it was spending too much time upgrading when I installed new packages, and so I thought – maybe I’ll try the nix package manager!
Previously, Nix installed its packages using 'channels'. You would add and update a channel, and then you could install packages from a channel. (This is roughly analogous to apt repositories). -- The CLI user experience for this channel-based approach is pretty terrible.
Nix flakes are a new feature where a project has a `flake.nix` file, which follows a standard format for declaring what packages a project provides. -- The CLI experience is much nicer, and has several other benefits over pre-flake Nix.
Flakes are still (for various reasons) labelled as "experimental". Much of the documentation has not been updated for flakes.
In 2 years, you'd hope that: the documentation improves, and there's less friction for adopting the technology.
The people you are talking to are either being too modest or are overly picky about what "ready" means. Flakes are 100% the way to go for new users and are production ready. They work well.
As someone who recently picked up Nix and isn’t using flakes the reason for that is that none of the official documentation seemed to be saying it was a good idea, and all I could find to the contrary was random blog posts, none of which actually explained what on Earth a flake is. I think I vaguely understand them now, but I’m hesitant to rip out the setup I’ve eventually got to and replace it with the new hotness just for the sake of it.
It is pretty old for being the "new hotness". It allows me to idiomatically and completely encapsulate my system declaratively in config. Nix isn't complete without this IMO.
You could do the same before with Niv. The new flake.nix format is pretty awful too (why do I need to declare every supported target triple separately?!).
I've followed the official docs, had to resort on Google et al. quite quickly to solve mundane problems (installing a channel is not on the default path of the docs for the new learner), and after much wandering and trial and error, I evenrially went to the discourse and asked what I should use between flakes, nix shell or develop... Every single answer was 1/extremely informative and nice 2/ crystal clear that Nix was in a confusing, in-between stage in its life cycle.
I very much appreciate the community and efforts but I work for a company that cannot afford the commitment that Nix requires right now. I will happily come back in 2 years and reevaluate.