Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

In 2023, you shouldn’t be using nix-env or niv or shell.nix but rather just use Nix Flakes. It’s listed in the notes but this has long been where everyone has moved for a couple of years now (why it’s still “experimental” is a different question). If this is “Nix-powered”, why is everything done in the mutable shell instead of actually setting up the pure derivation so others can consume the build? Looking at opam-nix from Tweag might be a better route here. Also, why would anyone put a text editor in their devShell?

Question to others: as someone with Nix experience and interested in learning OCaml but hasn’t quite bit the bullet, what does dune actually offer me if I’m using Nix to manage dependencies already? It feels like adding an unnecessary layer of LISP when Nix and opam should already cover everything.



For a feature that isn't enabled by default, "just use Nix Flakes" hardly qualifies as best practice or even commonplace.

I've used Nix/NixOS for years and still don't have a use case for flakes. I only enabled it this week to restore some functionality to the nix command, which is still a work in progress.

Getting there was painful and required a deep dive into the documentation. In the end, it was as simple as adding this line to my configuration.nix:

  nix.settings.experimental-features = [ "nix-command" "flakes" ];
The flexibility of Nix is one of its main selling points, so it's impossible to say that "everyone" uses it in a similar way. Flakes are a welcome, but disruptive, enhancement. Hopefully, the experimental phase will end soon.


I've got a simple use case: reproducibly building a random derivation from someone's Git repo.

If they haven't pinned nixpkgs, I have no idea at what point it _was_ building successfully. It's just dumb luck whether my system's channel is a compatible nixpkgs.

If it's pinned, great, I can use that pin until I'm bothered to bring it back to mainline. At that point I'll override the nixpkgs input and bear the cost of updating and maintaining it.

Flakes make managing pins those easier, through a nice(r) CLI, and a standard format for them.


Most hardcore Nix users/developers I have met have been suspicious for Flakes for several years, so your point rings true.

That said, it feels like they are slowly coming to terms with it and just accepting it as default. Here are two examples of maintainers eventually accepting flake support on their repos after initial hesitation [1][2].

[1] https://github.com/tpwrules/nixos-apple-silicon/pull/47 [2] https://github.com/NixOS/mobile-nixos/pull/404


Counter anecdote: all of the hardcore Nix users/developers convinced me it was worth it to switch to Flakes now. They even helped me move my NixOS config as well.


It sounds like a python 2 vs python 3 kind of deal, which intuitively makes me think that you should just use flakes


I'm a relative newcomer too— started about two years ago with a Flake-only workflow on Nix 2.3. My sense in observing the debate over this time is that about 20% of the objections are technical in nature, while 80% are around governance— feeling that the feature was smuggled into the main repo as a prototype, despite there being existing external projects (niv) that were trying to accomplish a lot of the same things.


Where does it say you shouldn't use nix-env, niv or shell.nix in 2023? I would argue that there is extensive documentation and functionality for that already and it's not like it's getting deprecated. I've used Nix/Nixos for the past 4 years and still haven't looked into flakes - all the Nix stuff I use works great so I just can't really be bothered to spend time learning more, though I don't doubt it has some advantages.


I've been using Nix for about a decade, and not bothered with flakes yet. However, I also avoid nix-env and channels, as the parent suggests:

- Instead of channels, I use fetchGit with pinned revisions

- Instead of managing installed software via nix-env, I use buildEnv to collect everything I need in a single derivation. If I'm on NixOS I'll put that in systemPackages; or otherwise (e.g. on macOS) I'll use nix-env to only install that one package.

These have the advantage of being declarative files, which can be tracked in git; rather than imperative commands.


> Where does it say you shouldn't use nix-env, niv or shell.nix in 2023?

It's not in official documentation but the biggest reason is it's not reproducible by default and a new user could easily not pin nixpkgs, then think "wait... Nix isn't reproducible".

nix-shell and niv or otherwise pinning nixpkgs is pretty good, though there are some reproducibility advantages flakes has over nix-shell + niv such as:

- not allowing access to files not tracked in the git repo - forcing the user to lock their inputs with flake.lock whereas pinning/niv are optional

Also see: https://nixos.wiki/wiki/Flakes#Making_your_evaluations_pure


Meanwhile, much of the Nix world is using the composable and standardized system of Flakes so they can easily share their derivations. Flakes are behind a flag, but are a part of `nix` and all of these other tools are adding dependencies and complexity to your system. The Nix Flake shells also start up much quicker. It's really worth a look because it can simplify your setup and make it easier for others to read your Nix code and not run into something unexpected or nonstandard.


Why would I give up on shell.nix if flakes API isn't stable yet? I've got my own patterns around default.nix and shell.nix that provide better ergonomics than flakes.


Flakes have a lock file (flake.lock) which means you get to decide explicitly when to update the software. nixpkgs does not have precise rules on what updates are allowed, so nix-shell can give surprising results unless you make the effort to stick to one version of the whole nixpkgs explicitly. With flakes you can combine packages and versions explicitly.


> you make the effort to stick to one version of the whole nixpkgs explicitly.

the "effort" is just pointing to a particular checkout from nixpkgs repo

> With flakes you can combine packages and versions explicitly.

it's the same thing with default.nix/shell.nix, just having a separate lockfile changes nothing in the underlying `builtins.fetchGit` / `builtins.fetchTarball`


For your personal use, it sounds like it won't make sense.

In a team setting, enforcing that everyone has to follow purity best practices because nothing else is allowed is great.


> In 2023, you shouldn’t be using nix-env or niv or shell.nix but rather just use Nix Flakes

I've found quite a few articles on alternatives to nix-shell in the flakes world, but I haven't found one for this usecase (which is also my main Nix usecase).

Particularly, how do I have a flakes equivalent for nix-shell that isn't pure? It is convenient to be able to run git, or SSH or whatever from my development shell, and those things shouldn't be in my project build setup.


I'm not very familiar with Nix but Dune is a build system not a dependency manager. You would need it regardless.


Nix is a build system + dependency manager. So wouldn't that cover the use case? I know some packages use a Makefile with ocamlbuild or the like. I want less moving parts and less things to learn if I can.


While it might be possible, it's not very practical.

The original Nix thesis [0] talks about using Nix as a low-level build system in Chapter 10.1. And the author of opam-nix* has made an attempt to use Nix as a build system [1]. However, dune is a complicated bit of software that's not easy to replicate, and Nix isn't particularly well suited to the task.

[0] https://edolstra.github.io/pubs/phd-thesis.pdf

[1] https://gitlab.com/balsoft/tumbleweed

*Which is essentially functionality to use Nix as a dependency manger with opam-repository.


I see nix as a partial build system. It’s a more evolved makefile that will call bash scripts or other build systems to really build things in different languages. For OCaml you’ll need dune to build your projects, and that’s what nix will end up calling after setting the dependencies for you.


How would you provide incremental per-module compilation for your Nix derivation of the app?


I don't know; that's why I'm asking. Maybe buildOpamPackage already does it? https://github.com/tweag/opam-nix#buildOpamProject There's a buildDunePackage in the same region of the docs that runs `dune build` but that to me implies that dune is not needed(?). I haven't read too much into the project yet. The example (https://github.com/tweag/opam-nix/blob/4bb1a4c372f639f44fc67...) would indicate that everything is configured from just the ${PROJECT}.opam file, but I don't have enough info on the toolchain to know if it's incremental per module or what... or if ocamlfind more complicated to work with than dune.


It does run `dune build`, but the unit of persistence within Nix is defined as `buildDunePackage`, i.e. the Nix store will only know about the package rather than individual modules and a change in a single module will cause a cascading rebuild of the entire package to update the nix store.


There are tools out there for other languages that _can_ handle incremental & per-modules builds, such as purs-nix for PureScript, so if opam-nix doesn't now, I'm sure it will in the future as a lot of projects are asking for this feature.


> what does dune actually offer me if I’m using Nix to manage dependencies already?

purs-nix is a good example that even if per-module compilation is made into derivations, the rest of the remaining heavy-lifting of constraints resolution is done by the external build tool. You can think of Nix as a dependency manager, but only with a huge caveat that it doesn't actually manage constraints that come with those dependencies, especially transitive ones.


That's a good read but I'm still unclear on dune vs. ocamlfind/ocamlopt. Is dune not using those under the covers like Nix could?


While you can _build_ OCaml projects without Dune (although I wouldn't want to do that), _editing_ OCaml code I wouldn't recommend, as the OCaml-LSP depends on dune. If you're an Emacs user: Merlin AFAIK doesn't need dune.


I see. I wasn't aware that Nix was a build system and probably should have investigated a bit more before responding. Truthfully I don't use OCaml professionally but just in a hobby capacity. I believe you could roll your own using Make but the compiler invocations (which you can get dune to spit out if you want) become more complex over time the more features you add like PPXs, or `ctypes`, and unit testing, the more time you will save by using dune. tl;dr running ocamlopt directly works but will become cumbersome the bigger the project becomes


That’s still great feedback though—especially when you mention PPX support which is pretty common.


Nix can replace opam, which is the dependency manager supporting isolated ocaml environments. I generally try to use Ocaml now without opam, and just using Nix.

You'll still want dune, though I could see an argument for generating the dune files from nix expressions.


Isn't opam read upstream for the public package registry? It seems like opam is the one you need.


Dune doesn’t handle dependencies for you, you just use it to build your ocaml projects with a list of dependencies (often without specifying dependency versions, which is why dune doesn’t really work without nix)


Do you know about nix-shell --pure?


It's a good improvement, but still not as pure: https://nixos.wiki/wiki/Flakes#Making_your_evaluations_pure




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

Search: