Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Using Nix on macOS (checkoway.net)
131 points by gbrindisi on July 30, 2022 | hide | past | favorite | 114 comments


This post focused solely on the Nix package manager and Nix packages - for anyone that uses MacOS but is interesting in trying NixOS (or using it within a VM in MacOS), I definitely recommend Mitchell Hashimoto's NixOS repo: https://github.com/mitchellh/nixos-config

Honestly, doing that may be easier and a better option than using Nix packages in MacOS.


> Honestly, doing that may be easier and a better option than using Nix packages in MacOS.

Respectfully, I disagree. I’ve been using Nix on a couple of my Macs, including on an M1, and I’ve cutdown my dependence on homebrew almost to the point of its absence; I rely more on Nix packages, than on Homebrew packages.

Having said that, I still wouldn’t recommend anyone using Nix; steep learning curve, and too many rough edges.


> I still wouldn’t recommend anyone using Nix; steep learning curve, and too many rough edges.

I'd like to think there are roughly two camps of people:

Those who hear about Nix's declarative nature, with its reproducible/'pure' nature, and generational installation, all of which allow for some pretty neat UX. To this group, Nix sounds technically interesting.

The other group, those who want a tool that just works, that's simple to use, and already get their job done with other package managers. -- I think for this group, Nix is going to be a bad tool to recommend, even if they keep hearing about how neat Nix is.

Rather. Nix is wonderful 95% of the time. But the 5% of the time you run into some problem, it's much more difficult to get unstuck compared to other tools. (Other knowledge is necessary but not sufficient, the community is small so maybe harder to find a StackOverflow post, the documentation is fragmented, etc.).


I have exactly same problem using Nix package manager in Ubuntu. That's why for those other 5% you can usr usehomebrew or whatever other package manager you have in your system.

I am not sure what is the story of having NixOS as a server, but would not suggest to have it as a main OS. There a sometime cases when there are simply no package you want to install, or you install it but some functionality doesn't work. Yes, maybe one can fix/patch, but I simply fall back to apt-get in such cases, and don't spend my time on that. Usually I have problems like this with GUI application, ie: installed pdf editor, which can open pdf, but can highliting functionality doesn't work and the crashes.


> I am not sure what is the story of having NixOS as a server, but would not suggest to have it as a main OS

This was what I thought when I was learning nix. Once I used NixOS, I realised it's not quite that difficult. -- The two big differences: 1. Roughly, you only really need to care about the NixOS config about as frequently as you'd change system files in /etc/ in other Linux distributions. 2. Some programs (e.g. minikube) will download a binary automatically, and this doesn't work well with NixOS.

I've seen tools like distrobox https://github.com/89luca89/distrobox recommended as backups on NixOS, as well as the usual Docker / VMs.

I secretly suspect some of the reason NixOS is popular is it's less trouble than nix on non-NixOS. Whereas, nix on macOS, I've sometimes mixed compilers/libraries, which leads to difficult to discern problems.


Yeah, I switched completely to nix after being frustrated with homebrew constantly breaking things (any time I installed something. (Usually involving libicu being replaced with a different version.) And then had to pick up homebrew again for a couple of things.

I _really_ like being able to drop into a shell with a few additional packages installed. But nix does have a learning curve and some rough edges. I found it tricky to use things like libraries outside of nix's build process. And there is a bit of an impedance mismatch when trying to use languages that have their own package management.

So I've got nix for a bunch of software, a couple of libraries in homebrew, and native package management for various languages (cargo, ghcup, lake, idris).

I also reluctantly installed agda via homebrew because I can't get it to build. (Haskell mostly works on M1).


MacPorts is a better alternative to Homebrew, I never had any problems with it.


The only time things break for me because something is replaced by homebrew is because c/c++ projects seem to so overly rely on dependencies (headers, .a files, etc.) being installed by the os globally. Maybe this is better when the project uses Bazel instead of make/(auto)configure.


I switched to Nix because, unlike Homebrew, it does not include silent Google spyware.


Homebrew includes Google Spyware? Do you have a source? That's a huge opsec issue.


Homebrew puts a unique identifier on your system that phones home to Google with your unchanging unique ID and IP address every time you install a package.

Because client IP is coarse geolocation, this unique tracking ID allows Google to see your travel history.



Nix is one of those rocket-powered chainsaw tools that you run into, and while it still scares me (and I often worry about accidentally cutting off a limb), it's much nicer to use than Homebrew. The only caviat is that your Nix store can get enormously huge, which is a big problem on Apple devices where storage comes at a premium.


I would naively expect that if you run garbage collection on a regular basis that it should take no more space. Is that not true, or is running it on a regular basis the sticking bit?


I suppose you could, but Nix (and NixOS) defaults to keeping packages for an insane amount of time. 3 months of regular Nix use can accrue ~300gb of packages, which is definitely not what you'd have on something like Homebrew.


By default don't they keep old generations (and thus previously-installed packages) literally forever?


Does nix and NixOS ever run the GC for you? I’ve always found that I have to manually run it at a time and place of my choosing.


Check out the option 'nix.gc.automatic'. It's set to false by default.


Can't you just run nix-collect-garbage?


I recently had tried to use Nix again after a hiatus. I wished to use Nix to replace Homebrew, but also for managing versions, of like Ruby or dotnet.

Sadly, it's not quite there for my needs, but it's getting better. Flakes are more fleshed out, the CLI is improving in it's user experience. I still don't feel like I understand the language works and build my flakes off of copying/pasting the one that works.


> I’ve cutdown my dependence on homebrew almost to the point of its absence

What are the advantages of that?


I use Nix for the advantages it provides, and use other package managers (homebrew, etc.) for things that are not available in nixpkgs.


Nix on MacOS is fine. I've actually experienced less stability running VMs and Docker than I have with Nix on MacOS. nix-darwin is the missing piece of the puzzle, providing NixOS-like functionality.

NixOS is pretty great too, but there's no need to run a VM to use it. NixOS generally solves OS problems. Adding a VM just adds complexity.


Seconding the rec of Nix-Darwin! Great way to use Nix declaratively on macOS, not just for managing packages but also services like on NixOS.


For all of my personal machines, I use NixOS (both hardware and in cloud machines). But for work, we have a soft-MacOS mandate. On that m1 macbook pro, I run nix-darwin for the mac specific settings I want, and packages that I run in macos, but everything else in a NixOS VM similar to mitchellh/nixos-config.

I use UTM (a nice wrapper around qemu), but the rest is just standard nix config, of which, nearly all of it I reuse from the configuration for the rest of my machines.


Thanks for pointing out mitchellh/nixos-config. Do you have a config published for nixos with UTM? I’m having a heck of a time getting the screen resolution and font sizes where I want them and I’m kind of lost.


Yep. Note that there's nothing you need to do to configure display resolution in UTM / qemu. You do need the spice guest tools installed in your nixos vm though. The only thing you should need to do is set the resolution in whatever display manager you use in nixos. For me, I run the sway window manager. My display manager is kanshi.

Here's my config: https://git.sr.ht/~averagechris/dotfiles

Here's a branch that I has some aarch64 specific things in it that I'm using for my guest vm config (I will merge it into the main branch when I get an hour or two so this link might die at some point) https://git.sr.ht/~averagechris/dotfiles/tree/aarch64-work-v...

Here's the link to my display manager config https://git.sr.ht/~averagechris/dotfiles/tree/aarch64-work-v...


> I’m having a heck of a time getting the screen resolution and font sizes where I want them and I’m kind of lost.

    services.xserver.videoDrivers = [ "qxl" ];
    services.spice-vdagentd.enable = true;


I just tried that and it resulted in a black screen. I suppose there is more to using that video driver than just that line in a nix configuration?


Hey! I was misinformed, try removing:

   services.xserver.videoDrivers = [ "qxl" ];
Then you're only left with the spice line. I think qxl requires other configuration.


hi, nix on macos user dropping in to deliver a PSA for the non-nixer macos users amongst you reading this article:

* you are correct to be terrified

* you are correct to think “this is a demented amount of busywork; who in their right mind would do this to themselves?”

* you should know that this is a highly atypical setup that does a staggering number of things by hand for no discernible reason

* normal people just install https://github.com/LnL7/nix-darwin on top of standard nix and enjoy about the same lack of janitorial work as macports/homebrew users, relative to whatever the hell this guy is doing

* please don't be scared off nix by this article


Do you have a more real world example of a darwin-configuration.nix? I want to see how this looks like and maybe hear about experiences with it longer term.


i would just link you mine but this is a pseudonymous account; however:

most nix-darwin users i know have a darwin-configuration.nix that's nearly identical to the one the installer plops down for you, with the exception of more items under `environment.systemPackages`, and using nix-darwin solely as a declarative alternative to nix-env is totally viable

other than a few built-in service configurations and plist defaults, darwin-configuration.nix typically grows much as configuration.nix does on nixos. define or modify a couple packages here and there, shove them into `pkgs` by setting `nixpkgs.overlays`, etc etc. the ux is intentionally very similar to that of nixos

what this means is you can look at a lot of people's nixos config repos and get some idea of what you can do just as well with nix-darwin

i can, however, offer you my anecdote:

nix-darwin has let me completely forget that brew and macports exist, and even let me get away without installing xcode at all -- it's perfectly competent at “getting a suite of dev tools onto a macbook”, but what really sold me on it was just how straightforward adding a new package is:

  mypkgs $ bc <<<$(cat *.nix | wc -l)/$(ls | wc -l)
  32
that's an average of 32 lines to go from “obscure thing that literally nobody packages” to “bona fide part of my system”, and that includes meta blocks with homepage/description/etc, because i periodically try and get some of this stuff merged into mainline nixpkgs

the language itself is a little quirky and the evaluation model of the module system is somewhat fraught with fixed-point knot-tying fuckery, but between the process of packaging being so nice and brew/macports pissing me off, i found it easy to drink enough koolaid to get to grips with those aspects

i've been using nix-darwin and for almost exactly one year, and replaced all my linux installs with nixos, and i have not looked back whatsoever


This is a pretty unusual set up. The title should probably be "how I use Nix on macOS".

For folks unfamiliar with Nix, this is a fairly atypical and complicated setup. It's honestly pretty smooth sailing normally.


That seems like a hell of a lot more work than just using Home-Manager and flakes. Flakes add a lot of boilerplate, but this seems excessive in comparison. And Home-Manager is quite easy.


Yeah this post is basically how to build your own wrapper around nix to manage your Mac user environment because you didn't like some of the decisions the nix maintainers made. It's easier to just install nix following its directions and then exclusively use nix-shell or nix develop (with flakes) to activate development environments with specific tools. Kind of like a python virtual environment on steroids. Forget entirely about managing your user's global tools and packages unless or until you want to do that, you could just keep using homebrew!


Even managing global/user packages is fine, if you want parity with a normal package manager. nix-env is pretty simple to get started with.

Managing that declaratively is slightly more challenging. That’s when you need to understand the Nix language and use something like home-manager or the file approach in the blog post. But at this point, Nix is competing against something like Ansible/Puppet and not a standard package manager.


This blog post follows IanTheHenry's method for declarative environments via nix-env, which was produced when Ian was following a methodology for learning Nix that deliberately eschewed engagement with the Nix community in favor of relying only on the official documentation. So it doesn't use flakes or any unofficial community tools that could make setup 'easier' in the sense of being a bit more ready-made.

Anyway I don't think there's anything really wrong with it. There are also other options for people who are hesitant to try flakes or home-manager if they don't like this one for some reason, though. The most common one is a named package based on buildEnv in your packageOverrides or in an overlay. (There's an example of this on the unofficial NixOS wiki, in the FAQ.) And of course home-manager is usable without flakes.


I mean.. it sounds wrong[0]. I don't think flakes are really mandatory given that the status quo is stuff like brew, but home manager actually does "the thing" that Nix people are talking about. Without something like home manager or NixOS, you really are only halfway to what the actual pitch is for nix.

(Aside: I can't imagine figuring out how to use nix just from the official documentation. Those documents are a total mismatch from what the audience needs, focusing way too much on how to write your own custom modules, and not nearly enough on actually consuming them or decent patterns for it)

[0]: people are allowed to do what they want. But the path chosen by this author is not the easy path


> I mean.. it sounds wrong[0]. I don't think flakes are really mandatory given that the status quo is stuff like brew, but home manager actually does "the thing" that Nix people are talking about. Without something like home manager or NixOS, you really are only halfway to what the actual pitch is for nix

I agree— I really like NixOS-like module systems and how they merge together different bits of config to bring the benefits of Nix to configuration management. Being able to configure the whole OS or a big chunk of it via Nix, including running services, managing users, pre-configuring various programs, and more, from a unified interface in a simple language like Nix is awesome.

Declarative package management is great but the broader configuration/service management stuff is even better.

> Aside: I can't imagine figuring out how to use nix just from the official documentation.

That's part of what makes Ian Henry's blog series on the topic compelling! Nobody really learns it that way, and so he's putting the docs to an unusual and much-needed test. Definitely check it out :)


I really like Nix's configuration language too. It seems to hit some sweet spot where it manages to be simple, expressive, versatile, and maintainable, all at the same time. So I find it sad when I see people almost instinctively dunk on the language. I wonder if recent efforts around documentation can improve things.


I think people just (understandably) have little patience for new DSLs in general.

Another thing that I'm realizing is awesome about Nix as I'm getting my feet wet with CUE (also an interesting configuration language) is that in a way, the power of Nix makes it easier to learn than it otherwise might be.

So much of what we actually do with Nix leverages functions and libraries that are written in Nixlang, stored in the same monorepo as all of our build recipes. This means that once you get more familiar with Nix-the-language from using it in your own configs, exploring the implementations of the tools you use in building your packages and environment becomes easier and more natural. And Nixpkgs is then an awesome one-stop-shop for countless examples, and even kind of a quick reference for how a bazillion different pieces of software can be configured.

Maybe it's an acquired taste, idk. But I feel like the language is great at being simple when it can and surprisingly flexible when it needs to be. And Nixpkgs becomes a great resource for users, once they learn some of that relatively simple language.


There's nothing wrong with it, but also I think it would be worth making it explicit that things are done the hard way. It's a bit like writing a programming on macos post with "so first we need to craft a xnu message by hand". For people arriving from search that's not a great impression.


Something not mentioned here is that each and every single macOS update will break your Nix install too. This is, by far, the most frustrating part of using Nix on macOS.


This is true, but in my experience it has mostly been pretty easy to deal with. Generally it's just a matter of re-linking /etc/zprofile and friends to the ones from the nix-darwin installer (if you're using nix-darwin, which I would recommend).


Could you elaborate on what broke when you updated macOS? Granted, my Nix installation is a single-user installation (so it doesn't have the edited /etc/bashrc and /etc/zshrc that get overridden), but it worked without any issues after I updated from Big Sur to Monterey, so I'm curious about your experience.

The only things that broke for me after the update were the xcode command-line tools, which break for everyone[1].

[1](https://stackoverflow.com/questions/32893412/command-line-to...)


I imagine GP is talking about every macOS update forcibly overwriting /etc/zshrc.

They bothered writing a system capable of dropping the conflicted file in Relocated Items for us to optionally use--but they appear to be only using it for /etc/bashrc, and not /etc/zshrc. So, people who use zsh by choice or default get dumped on a bit :/

Some background in https://github.com/NixOS/nix/issues/3616


This hasn't been true in my experience. I've been running Nix on macOS for nearly a year without problems.


I was surprised recently when upgrading from Catalina to Monterey and all the nix stuff just kept working. It was the first time a major macOS hasn’t broken nix.

Does anyone know if this update was a fluke?


> Usually, your terminal emulator will create a login shell by default when you open a new terminal window. (Apple Terminal and iTerm2 both do.) And that’s generally the only time you create a login shell.

On a Linux system, login shells are only invoked when you actually create a new session which doesn't come from an existing session belonging to the same user. In other words, you get the when

  - you switch to a 'real' TTY and log in manually
  - you log in via your GUI session manager (GDM, SDDM, etc.)
  - you log in remotely, e.g., via SSH
But not when you open a new terminal emulator window. You can't just run `login` as your normal user inside a terminal emulator and get a new session either. You can check this with `finger` or `loginctl list-sessions`.

On macOS, those things do get you new sessions which are shown by `finger`. I wonder whether the difference reveals a macOS quirk or a Linux quirk.


Wow I don't know what's crazier... that OS X still has finger or that it's had it this whole time and I never noticed. I remember fondly the early days of the internet when "finger `cat /etc/passwd`@remotehost" and other similar types of exploits had ridiculously high hit rates. And of course no shadowed password files yet.


I think this is because launchd+getty and systemd+agetty are doing something similar in those circumstances? They're both opening pseudo-terminals with the login command. That is to say, opening Terminal.app connects to a 'network' PTS much like SSH does, afaict.


Yeah but I wonder why. (Invoking `login` at the CLI in Terminal.app yields the same result as opening a new tab on macOS.) Trying the same on Linux says you have to be root, and does not log you in.

Anyone got a Linux distro configured differently that they can explain, or a *BSD they care to try and compare on? Is there any reason (security, 'correctness') to prefer one way over the other?


Perhaps what is missing is the book "Nix - The good parts". Not saying Nix is not good overall, but getting a condensed description what is worth knowing, leaving out what can be ignored or is obsolete, would be quite valuable.


Here you go:

- don't use nix-env ever

- enable and use the new nix command (nix3)

- enable and use flakes

- use home-manager

- if on macOS, use nix-darwin

- with flakes, freely use nixpkgs unstable (stable is still useful, but flakes provide their own stability through pinned versions).


I’m looking at nix-darwin but there is no explanation on what it actually does

https://github.com/LnL7/nix-darwin


It's like a system-wide home-manager alternative for Darwin systems. Or the other way - a NixOS-like whole system management that works on top of Darwin.

For some examples: you can manage your homebrew packages, set keyboard preferences, trackpad settings, updates, finder defaults, etc through the nix config.


As a NixOS user, this sounds awesome! Thank you


Check out its manual to discover all of the configuration options you can set.

https://daiderd.com/nix-darwin/manual/index.html#sec-options


And you do this to install MySQL?


That argument can be weaponized against anything and everything, really.

"Oh, Ubuntu is too complicated"

"It's easy. 1. Don't use dpkg, ever. 2. Use the apt command. 3. Avoid Snaps. 4. Well, forget about locking dependencies, this isn't Nix. 5. No Home Manager equivalent exists, so I don't know, use Ansible? 6. If on macOS, you're out of luck. 7. Make sure to download the latest release."

"And you do this to install MySQL?"


It’s a lot of upfront work sure, but afterward installing any package (including MySQL) is just appending the package name to a list in your config file. The powerful part is that uninstalling the package is as simple as deleting it from that list.

Or if you don’t want to install the package permanently and just want it for a one-off job, `nix-shell -p mysql` starts a shell with mysql on your path, which will disappear as soon as you exit the shell.


I hope Docker is not the final answer to reproducible and isolated processes because it’s a bit too complex and slow on anything other than Linux, IMO.

Linux virtualization almost became a mandatory feature of a modern OS because of it.

I wish there was something that would run on any POSIX, but that’s probably not enough ground to cover complete reproduction.


I don't think Docker is particularly reproducible. It has less understanding of dependencies than a Makefile. Not only does the cache rarely save build time, it is also very unlikely that two developers running the same Dockerfile end up with the same bytes in their generated image. (The classic example is "FROM ubuntu:latest; RUN apt-get update && apt upgrade". No clue what's going to be in that image, it's different every time. You can pick a particular well-known build of the Linux base, but there is no lockfile that controls what apt upgrade is going to do. Even if you avoid that, esoterica like build tools that put the current time into binaries will bite you. Other build systems have a sandbox that lets you fake those tools out, so if your control file says the build time is 10 PM on Friday, then the next time you build it it's also 10 PM on Friday.)

Docker also conflates too many concepts; layer generation, image distribution based on layers, registries and tags (mutable! wtf?), cgroups, PID namespaces, network namespaces, storage namespaces, etc. I'm sure it was a godsend for a certain type of workflow (one that depends heavily on the OS base; shelling out to utilities, using programming languages with poor dependency management systems, etc.) but for the average modern codebase, it seems like a detriment to me. I see people doing full builds of their app every time they want to test a change (often downloading 100s of packages from the Internet), simply because that's how Docker does things, and that honestly isn't right. They're throwing their time away for no good reason.


My hope is that a lot of the difficulty in getting reproducible builds is caused by outdated libraries and techniques. For example, assuming that your code is in /usr/bin or /usr/lib, so any package manager has to emulate that.

My hope is that eventually, you can just run `cargo build --reproducible` or `meson build --reproducible` or `make --reproducible`, and if your architecture is the same, the dependencies will be the same and the output will run exactly the same. Even going as far as to install an older cargo or meson or CMake if that's what's needed for backwards compatibility. And if you want to be safe, you can create a sandbox or "jail" and libraries will know how to deal with it instead of just crashing when they try to access something outside.


I don't think that will ever really work reliably for something like cargo or meson. They don't really go to any effort to ensure clean build environments, enforce dependencies, sandbox builds etc.

You need something like Bazel for that really.


cargo build --locked

There is a lockfile, even if it's not respected by default. Doesn't help with build.rs being able to do whatever it wants but it's better than default


“Docker but it’s just a chroot”?


Yeah, you kid, but you know, it would solve a lot of the most common problems. Like a parent mentioned, most of the time you're just not linking to the right libraries. That’s it. Do we need to ship a whole kernel, have terrible IO and jump through a lot of hoops just for that?


I’m not kidding! I hacked together a bunch of env vars, carefully ordered tar unpacking, and some chrooting for dev envs at Airbnb years ago. It’s effective.


Before docker was invented, I worked on chroot based dev environments at work too (linux host), and I loved it.

But I’ve never really touched Mac OS. Does Mac OS natively support this style of development?

Do you know of anyone that’s blogging about it?


It doesn’t. My hope was if Apple and Microsoft provided this feature, we could build a common foundation on top.


I'm wrong, turns out, chroot works on the Mac after all.

Nice, that's a first step. I'll try to play with the idea


Thanks for double checking. I really appreciate it. :)


Sorry, sarcasm is hard on the web.

I think you were/are into something. I though about it but never managed to build it.


Christ that's a lot of work, just to start working on work. I really want to like Nix, but the UX is frankly offputting. I really hope it improves to the point that it can be mindlessly installed.


I wouldn’t take this one blog post as gospel about how to use Nix.

I’m not denying that it’s complicated, but doing declarative package management is not the only way to dip your toes into Nix. You can use it pretty much as a conventional package manager with none of the upsides of declarative package management (but none of the complexity either).

On the surface level for people migrating from existing package managers, nix-env is approximately as complicated as something like pacman. You just need the command for installing, removing and updating (well, the 2 commands for updating, but that’s the only extra complexity).


People say that but yet nobody linked to a post explaining the “right way” of using nix on macOS


Here is the official manual page for Basic Package Management. No blog post necessary. This covers the majority of it, but I’d say if you read the entire section on Package Management, then you’ll get an idea of how it works and be able to install, update and uninstall things (as well as a bit more).

https://nixos.org/manual/nix/stable/package-management/basic...

Also, there is no “right way”. What I suggested was the way to get parity with standard package managers. There are many different ways to use it, because it is a very flexible tool. There’s no reason to learn every single one to get started with it.


This doesn’t tell us how to install it, which is what we’re griping about.


https://nixos.org/manual/nix/stable/installation/installing-...

This worked for me. I think MacOS installation was a bit hands on due to Mac weirdness (when I did it ~2 years ago), but I think it is better now.


Yes, this is what I tried too. What you describe as “hands on” is precisely what my original complaint is about. It was even more difficult (impossible?) for me due to the case-sensitive FS setting being enabled on my Mac.

Everything about first contact with Nix is off putting. I really wish it weren’t so :/


So what’s the simplest way to start using nix on macOS?

Again, I am convinced Nix is a superior way to write software, and I would love nothing more than to have a working installation in a few minutes.


> Christ that's a lot of work, just to start working on work.

If you already have a Nix based development environment, it's much less work and more reliable than patching something worse up with homebrew.


Totally, this post is doing a disservice to Nix.


I think that's a bit unfair to the author, whose goal is clearly to document their own setup on a didactic way rather than to say

> here, paste this into your terminal for the easiest way to get up and running with Nix in a fashion that's representative of community common practices

I think it's a good blog post which, carefully read, teaches lots of useful things about Nix in a pretty concise way.

It's totally fair to point out that this doesn't represent a path of least resistance to enjoying the benefits of Nix. But I don't love the way your short comment kinda frames the blog post's job as doing something for Nix, either, you know?

I don't like the idea of this guy or anyone else feeling punished or chastised when their Nix-related blog posts become visible because those posts don't function as good marketing for Nix. Having a post about your Nix journey blow up should yield encouraging responses from fellow Nix users, right?


I don't know if it should. Like this is neat and all but it's incredibly overcomplicated and for any readers unfamiliar with the tooling (which is most) it's off-putting.

If the audience was Nix users, then it would be different.

It's kinda like if you bought a fancy new camera and demonstrated your process but all your photos were out of focus, framed badly and lit poorly because you're into that for some reason. Would fellow fancy new camera enthusiasts cheer? Would folks who don't know about your fancy new camera think it's a good camera?


The post directly says that the easy path is more complicated, which just isn't true. It will dissuade new users from even trying Nix. That is a disservice.


Why hasn’t anyone built a clone of npm/npx UX that uses Nix under the hood? I hear so much about how ideal the Nix model is, and how bad NPM is. It seems like this should be “easy”. What gives?


Have you seen pnpm[0]? Has some similarities.

> Files inside node_modules are cloned or hard linked from a single content-addressable storage

Also (IIRC, it's been a long while) it's lockfile contains enough information to translate it directly to a Nix derivation[1].

[0]: https://pnpm.io/ [1]: https://github.com/nix-community/pnpm2nix


They're talking about a frontend for Nix that uses a simple subcommand interface with a UX focus, but which is about Nix, not seeking a Nix-like backend for NPM.

(I misread their comment the same way as you did the first time :)


There is absolutely no way I can recommend using this at work. Nix is way too complicated. Its already bad enough being the git goto person. Nix is so complicated it somehow makes git look simple.


I completely disagree. It took me a while to work through the peculiarities of NixOS and get my OS setup, but the benefits are immense now that I'm using it. And I'm using it as a daily driver at a large tech company developing and maintaining mission critical systems.

It's really no different from Vim in this respect. Most people will bounce off due to the learning curve, but once you get past it, the benefits are too great to go back to a more crude system. In fact it was easier to learn and setup than Vim for me.


This has been my experience as well. I was nervous to start depending on NixOs for my work, but when I started at a new company ~2 years ago, I decided that was a good time to dive in. I have absolutely not regretted it. My setup is far less troublesome than any of my coworkers managing a bunch of different python versions for various python applications on macos.


> benefits are immense

Such as?


Rolling release; entire config stored in git, allowing for reproduceable setup - I can get a new machine the exact same state in 30 minutes with a few KB in config. Super easy rollback if I break something. Never wondering if something is gonna break with an update. Never wasting time trying to figure out how I set something up before, because it's explicitly declared in config. Standard config language for everything across the system. Ability to roll your own OS in any shape you like. Much easier package creation than RPM or debs. Decentralized composable config - you can pull from many git repos to build your system. Ability to have multiple versions of packages and libs installed at once. Immutable file system except for home folder and a few other paths. Ability to set up temporary dev environments and package installs.

With every change I make, the system only gets more stable, predictable, and reliable, which is the exact opposite of every Linux distribution I've ever user before, which had to be wiped and reinstalled every couple years, after which I'd have endless struggle sessions getting everything set up. I'll never go back.


Says the only person using vim


Every complex tool is complicated, like planes with a lot of dashboard, buttons, levers and other stuff. But if you learn it you can achieve awesome success. Nix is same if you use right way after some learn, for example, to create reproducible dev environment.


Nix is like Javascript. It's really simple under the hood, so everyone ends up rolling their own "framework".

(Not a bad thing, just be aware that Nix is for when you need DIY development environment infrastructure and don't have the budget to keep a team of seven k8s specialists for the job.)


I'm actually trying out Nix on a fresh Mac install since this week, but I'm not yet sure if I enjoy it. When things work it feels pretty great, documentation feels lacking though so when I want to do something I haven't done yet I generally try to find examples of something similar. I do think I'm beginning to understand the language better that reading the source nix files almost become the docs for me.

The main problem I have is when I try to install a package that fails to install, usually it has to compile. Like today I tried watchexec on my M1, doesn't work. Luckily I can just download a binary watchexec build to get around it but it would be nice to know how to get it working. Worked with homebrew. (but homebrew has it's own problems)

The other thing is that I like the idea of using nix-shell for projects, but I hoped they would be more isolated than they appear to be. It's possible for example to have files in a user directory which will be accessible to all projects and package versions I'm using. It hasn't become a problem yet in my testing so far though.

Reading other comments I decided I will also play with running things in a VM with NixOS. Maybe I'll end up with a mix of local Nix for some basic stuff and then a development VM.


Nix is fundamentally a source-based package manager, so it'll try to build packages from source. However, since Nix packages are reproducible, it'll check the official binary cache first to see if it has already been built on Nix's infrastructure and download from there it's there. That's why Nix acts like a binary-based package manager most of the time. However, if a package fails to build or does build but isn't available on the binary cache yet, it would inevitably fall back to source builds. You'd occasionally run into this if you use the unstable channel of Nixpkgs. You can check https://status.nixos.org/ to get a sense of how high the chances are of missing the binary cache. Basically the chances are high if the channel build is failing.

While source builds aren't completely avoidable, you can alleviate much of the pain with a combination of declarative package management and dependency locking. It's what long term Nix users most likely end up using:

* nix-darwin for managing system-wide configuration

* Home Manager for managing user-level configuration

* Nix Flakes for locking dependencies

Once you have a working config, the same config would run anywhere, anytime. You can then use GitHub Actions to automatically update dependencies and check if they all build before merging. Also as a last resort, you can always revert to a previous config if something goes wrong.


Nix shell isn't supposed to provide file system isolation. It is a package manager after all, so what it does best is give a consistent dev environment with isolated dependencies. At that point if the program access mutable state and you want to prevent it (to a reasonable degree), you should use Docker or do it through the command line (like making $HOME point to somewhere else).


Oh yeah are definitely right there, I honestly don't know where the expectation came from because it makes perfect sense that it doesn't do that. Why would it. I think it was more me saying "would've been nice.".

I'm coming from homebrew + asdf, but so far Nix appears to be working fine for me. I think asdf has a lot of custom config to try and isolate version-specific shared files/modules etc. I can replicate it by setting some environment variables myself in nix shell file though. I've got my basic home manager setup (still need to migrate some manually managed files to nix config) and every project I work on is now running with their own shell.nix file. No huge problems yet, aside from the mentioned watchexec failing.

Not yet sure if I'll keep it in my regular workflow, it's been an interesting experience and I would be happy to not need homebrew anymore. (Might just try ports too). I'm also curious to see how fast new versions of software will be added/supported, so I'll have to at least keep this running until that happens.


> Luckily I can just download a binary watchexec build to get around it but it would be nice to know how to get it working.

Using steam-run, nix-autobahn or using buildFHSUserEnv yourself.


Those solutions won't work on macOS, though.


This is my approach: running NixOS on macOS using UTM. https://youtu.be/8gytY4ITSDA


I've been using a NixOS VM through VSCode's remote SSH extension for almost a year for all my dev work, and it's been working more or less flawlessly. I haven't had the need to install homebrew in the host macOS yet. Here's my approach: https://calcagno.blog/m1dev/


very nice! I stumbled on your post right after submitting this, thanks a lot for sharing I’m gonna try this out


Nix as a home brew replacement without using homemanger/nix Darwin is not a great sell to me imo.

Using flakes and using it for project dependencies though is amazing and quite easy to use imo.

We decided to use it at my job for a new project and it's been pretty amazing https://link.medium.com/DwIGVmRZ6rb


The best way to use Nix in MacOS is through qemu and utm in my opinion.

Then again, I don't like much about macs except the touchpad and macOS annoys me.

So this advice might not hold as true if you actually like OSX. Maybe checkout:

https://github.com/LnL7/nix-darwin

I'd also advice using flakes to simplify a lot of this.


I agree. I've mentioned this elsewhere in this thread, but I just wanted to second that I've found running nixos as a vm through UTM has been a flawless experience for me. I have a fairly complicated setup for a bunch of different machines that I am able to manage through one flake. I have no desire to ever go back to a not-fully-declarative setup again.


Or I can just use Homebrew with a Brewfile. Sure, not nearly as powerful, but does the job..


I have tried using nix for weeks on macOS and it’s been a really painful experience. I’ve pretty much given up. I don’t think they care much about user experience tbh.


Did you use an approach like the blog or one with nix-darwin, home-manager, and flakes?

Not trying to convince you to try again since you seem done, but want any prospective nix users to know which approach you found painful.

And if you don't mind, a list of the most painful things that should be improved.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: