Hacker Newsnew | past | comments | ask | show | jobs | submit | JamesSwift's commentslogin

Yes, for me it was 2 or 3 rounds of "its just not clicking" before it did and then there was no looking back. Ive heard the same anecdote from lots of others as well.

Sibling comment does a good job of going into flakes, but to answer this

> Do you install a package or a service

A package is like the raw software installation. So eg the bash package is just a wrapper around building bash from source (theoretically from source at least... you can also define a package as being a binary distribution as long as you specify the content hash). The service (actually the _module_) is for everything else around software installation. So, eg, the bash _package_ will build bash and have it available for you to put in your path but the bash _module_ might also configure your .bashrc and set it up as your users shell. It would also generally refer to the bash _package_ so you can do all that plumbing but specify a certain version of bash you want to use.

Another common example: a plex package would again build the plex software but a plex module would perhaps create a plex user, setup systemd units, open your firewall, and create a media directory.

EDIT: the next layer of confusion is that modules (which sort of are a secret-sauce of nix and so naturally you will want to use them a bunch) are specific implementation details of multiple subsystems in nix. Meaning, nixOS and home-manager and nix-darwin all have "modules" but they are not compatible. Each has its own "idea" of what modules are and nix itself doesnt provide this natively. That means things get a little more complicated/involved when you use those ecosystems together. Its not too bad but it is annoying.


Not only is it composable, but it is generalizable. So yes there is also chef, ansible, apt, uv, nodeenv, etc... or there is just nix. It is able to be the "one tool" to rule them all, often with better reproducibility guarantees.

Just a note that if you are on nixOS you can configure things to run in an FHS compatible wrapper (https://ryantm.github.io/nixpkgs/builders/special/fhs-enviro...)

I was already happy with my big ball of nix config for various servers, but claude does shave off a bunch of rough edges and make it more pleasant to interact with. I also resolved a couple nagging issues that had been around for a while.

It does tend to hallucinate but thats the great thing about nix... if it builds its probably right!


The UX is the big benefit, especially on teams who may not even know what nix is. I held off on exposing my nix setups for a long time, but devenv has made it possible to check things in without losing a ton of time to tech support.

Generally something like

  languages.javascript.enable = true
  languages.javascript.package = pkgs.nodejs_24

24 != 24.14.0

If you care about the _exact version you are pinning_ (even though you will guarantee the pin between team members without needing to do this step), you can either pin nixpkgs repo to the state that had that version, source the target version directly, or for some ecosystems (eg ruby) you can just specify a version with a number and it has tooling to resolve that using "traditional" approaches.

In general though when working on a team, you dont really care about the _exact semver version_, you care about the major and handle version bumps by bumping the pin of nix packages.


But that doesn’t pin to a specific version?

It does, in combination with a pinned nixpkgs commit, which you can find like this:

    ~/repos/nixpkgs$ git log --grep='nodejs.* 24.14.0' -1 origin/master
    commit 9c0e2056b3c16190aafe67e4d29e530fc1f8c7c7
    Merge: d3a4e93b79c9 0873aea2d0da
    Date:   Tue Feb 24 16:53:40 2026 +0000
    
        nodejs_24: 24.13.1 -> 24.14.0 (#493691)
    ~/repos/nixpkgs$ nix eval nixpkgs/9c0e2056b3c16190aafe67e4d29e530fc1f8c7c7#nodejs_24.version
    "24.14.0"
    ~/repos/nixpkgs$

It does, but its implicit (and so may not be the exact patch version you have in mind). See my other comment for how to handle if you _do actually care_ about pinning to a specific version explicitly.

Doesn't that pin me to a particular versions of nixpkgs? That's fine if I only care about nodejs, but if I want to maintain particular versions of different tools, it won't work.

Again, generally in other systems the full semver pinning is more of a crutch to get some 'reproducibility' that nix gives you out of the box at a much higher level. So, in general, people just pin to the major version in nix. But if you _really_ want the full semver pinning there are multiple options that I lay out in the other post. You can even patch the _actual nodejs source itself_ in reproducible/version-pinned ways.

I do want exact version pinning of individual packages. (As I said in my initial post, I’m aware that Nix advocates think that I shouldn’t want this.)

I’m not sure what other post you’re referring to. There’s one where you describe some approaches in broad terms, but as far as what the relevant devenv.sh config would look like, I’m none the wiser.


You still are pinning to exact versions of packages (and in fact are pinning to specific shas / content hashes of the packages) but you are doing so implicitly by going this "path of least resistance". The only thing that will change what _exact sha_ you are pointed at is an explicit update by someone. There is no risk of someone running install on one box and someone running it on another and them getting different _exact versions_ (or likewise, in CI it also will be the exact same). And in general thats what people are trying to achieve on teams by pinning to full semver. So thats what I mean by its generally not needed on nix.

However, to actually address your question it would be something like this (with ruby also added for comparison of whats possible depending on the language ecosystem you are using)

  ```devenv.yaml```

  inputs:
    nixpkgs:
      url: github:cachix/devenv-nixpkgs/rolling
    nixpkgs-node:
      url: github:nixos/nixpkgs?rev=9c0e2056b3c16190aafe67e4d29e530fc1f8c7c7
    nixpkgs-ruby:
      url: github:bobvanderlinden/nixpkgs-ruby
      inputs:
        nixpkgs:
          follows: nixpkgs

  ```devenv.nix```
  
  { inputs, pkgs, ... }
  
  {
    languages.javascript = {
      enable = true;
      package = inputs.nixpkgs-node.nodejs_24;
    };

    languages.ruby = {
      enable = true;
      versionfile = ./.ruby-version;
      // alternatively
      // version = "3.2.4";
    };
  }

Thanks for the code.

Pinning by version number isn’t a crutch; it’s more a question of mental models. Most people find it more intuitive to identify a world by describing the things in it than to fix the states of the things by identifying the world where they have those states. Nix sometimes feels as if someone read Kripke and missed the passage about possible worlds being a figure of speech.

In other words, many of us don’t think that version numbers are a crutch to be used in the absence of a totalizing hash of the entire state of the universe. We actually think that version numbers are, for many practical purposes, better than that.


I dont mean to imply its a crutch. Im merely pointing out that even though people say they want to "pin to a specific version", there are usually two different motivations:

- one group of people who want guarantees that what they install on their machine matches on their colleague/CI/prod machines. For this group, the nix happy path basically serves all their needs really well. It can capture nearly any sort of software dependency they have regardless of ecosystem and it pins to actual content hashes in most cases. They only care that the high level versioning is met, because again its reproducibility that they care about

- one group of people want guarantees of specific software versions. Nix still handles this, but its "more work" because nix is by default a snapshot of the entire world, of which your target software is only a slice of. And most nix snapshots of the world are "what were the most recent versions of each software package at this point in time". So you generally need to compose together multiple snapshots of the world. It works fine, its just more work (and more disk space).

In practice, again, I think most teams are served better by being in group one, but dipping into group two when they either need an "unreleased" version for software they depend on or when they need an older/unsupported version of software they depend on (or a nix release breaks their workflow). Then nix shines by being able to mix and match between different snapshots in composable/reproducible ways.


Thats how I learned to program : D

Hand typing sheets that my buddy printed because we didnt own a transfer cable.


Haha, same origin story as me. Messing around on that calculator was where I started to understand programming

I really hate its tendency to leave those comments as well. I seem to have coached it out with some claude.md instructions but they still happen on occasion.


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

Search: