techhub.social is one of the many independent Mastodon servers you can use to participate in the fediverse.
A hub primarily for passionate technologists, but everyone is welcome

Administered by:

Server stats:

4.9K
active users

Spent a couple hours tonight learning to try it out as a build system and have completely and utterly failed.

I understand some of the package management aspects, but I still don't understand `nix-build` or how any of the standard files connect together.

I wanted to get a basic "Compile a TypeScript NPM package" workflow but can't find any examples or documentation of such a flow that isn't just running `npm run build`. I was hoping to use this as a *build system*, not a development environment.

I feel like Nix does so many things that trying to learn how to do any one thing is overwhelming without solid templates to start from. I really need a "Hello World" Node app, and I'm just not finding one which does what I want. Maybe I just have the wrong mindset or something?

@develwithoutacause I am new to nix, too. here's what's helping me:

* nix is just really heckin hard. don't give up. Or give up but come back to it when convenient.
* avoid flakes until you've mastered the other stuff. Pretend there's just mkShell and mkDerivation, and things that call those, pretty much.
* you'll probably end up with a function that calls mkDerivation but is specialized for TS or Node or something, but try to maybe at least get a sense of how you'd do it with just mkDerivation

Doug Parker 🕸️

@webbureaucrat Waaaay ahead of you on avoiding flakes. 😅

I get the concept of `mkDerivation` but honestly I was struggling to even get `nix-build` to run the derivation I want, is there any good documentation which explains how these files (`default.nix`, `build.nix`, `shell.nix`, etc.) are resolved?

@develwithoutacause: generally, `nix{-,}shell` is the thing that looks foe a `shell.nix`. I havent used tge "old" tooling in a while, but I *think* `nix-shell` will fallback to a `default.nix` iff a `shell.nix` isnt found (and only installs some of the inputs? I dont rightly recall)

`default.nix` is the "regular" entrypoint. It can used like `init.js` or `__init__.py`, as you can sort of define namespaces with it by exporting an attrset. But it doesnt NEED to do that (which is why this is confusing). It cal also be a "callPackage style" nix file (but this isnt generally done at top level), or a module, or an overlay, etc. These are all different conventions and none of them are defined to have a dedicated "place". It can be frustrating. Rather than focus on the NAME OF THE FILE, i suggest you understand the content you should be putting there.

Like...what should go in ANY entrypoint file passed to `nix-shell` or `nix-build`? You can put just about ANYTHING in a `default.nix`, but the shape of the thing is much more important

@BryanBennett I guess I'm confused what `nix-build` actually *does*? I was expecting something like `nix-build -A foo` to call the function `foo` at the top level of `build.nix`, but it seems more complicated than that? You can name derivations, but I don't follow how those are referenced and used.

@develwithoutacause
I missed this reply. Sorry!

I would have to go and read the docs about all of this again, as i haven't used the "old" style interface in quite a while. If i remember correctly, it build the derivation named `foo` from `default.nix`. I'm not sure i know where you got the idea that `build.nix` gets directly involved, but i don't think it does? (You may obviously import it, but i don't think the top level nix tooling uses it for anything by default?)

@BryanBennett Ok, it seems like I'm not that far off at least. The docs I saw do mention a `build.nix` file (might have been some library), but maybe that was imported into `default.nix` and I just didn't see it.

@develwithoutacause: im googling for where `build.nix` might be mentioned and I just cannot find it...

@BryanBennett It might have been a JS library I was trying to use? That or I'm hallucinating and turning into an LLM. 😅

@develwithoutacause: I'm really not trying to dunk on you, for the record. Learning nix is much harder than it l should be, so one thing I try and do is act as an "oracle" (though far less accurate) so that others don't have to spend nearly the time I did to learn this system. If we can find where you got this notion, I hope to help you (and that project) fix up the misunderstanding somehow. It could result in doc updates or simply a better understanding of the ecosystem on my part so that I can better help in the future.

@BryanBennett I appreciate that, I've definitely heard Nix's reputation of being hard to learn. Once I have a chance of getting back into it, I'll see if I can find where I got `build.nix` from...

@develwithoutacause: without judgment of you or your position, the idea of nix being complex coming from someone at the company that is using Bazel so heavilyis funny to me 😅

@BryanBennett Oh I'm more of a Bazel-stan than you might realize 😅.

I'm too knowledgeable about Bazel and not enough about Nix to provide an objective opinion here, I'm just too biased.

Part of my goal here is to find a build system which is easier to learn and use than Bazel. I'm hoping that's Nix, but can't say yet.

While I can't say Nix is harder than Bazel, I'm not yet convinced it's easier. We'll see if my feelings change as get more familiar with it.

@develwithoutacause: I think that the concession that Nix makes that Bazel simply cannot afford to make is that the Nix ecosystem does not try (nor does it really care to try) to interact with non-nix packaged things other than by assimilation. Bazel's outputs (if I understand it all right - which is a big if) are "just normal things" (tarballs etc). Nix's are KIND OF that way - but are engineered in such a way that their assumptions are baked in to the output (they link against the nix store, for instance).

That being said: I have had a much better time learning nix flakes than "old-style" nix. It isn't perfect, but flakes actually have a schema, which is invaluable in learning something new. (Flakes being "experimental" is really in name-only at this point. The recent Nix user survey showed that 85% of respondents dependened on them in one way or another.) They have rough edges to be sure, but they're downright more predictable than the old-style stuff. YMMV of course.

That being said: Nix boils down just a thing that runs functions that get stuffed into JSON-style dictionaries. It looks goofy if you're not used to FP and laziness is sometimes hard to reason about, but it does get easier pretty quickly, especially if you're used to opinionated tools like bazel that try to solve similar problems.

@BryanBennett Bazel does just "output" files and folders. The management of dependencies is done at a distinct layer. Nix does seem to have a slightly higher level abstraction here, but I'm not totally sure how that works yet.

I've done some Haskell so I don't mind the FP aspects and am reading the syntax ok at least, it's the semantics I don't yet understand.

Would you suggest learning flakes as part of the initial process or coming back them after learning the "old-style". My rough understanding was that flakes pin dependency versions, which is definitely important for a real build system, but also not urgent to a learning journey, so I had been avoiding it. Would it be better learn flakes more directly?

@develwithoutacause: i don't really know, honestly. The pinning is a part of it, but not the whole point. The "inputs is an attrset; outputs is a function mapping the input attrset to an attrset of this vague shape" is maybe MORE important and why people have added functionality to flakes (unofficially extending the spec).

In case it helps to make your decision, I have a working knowledge of old-style nix, but a much deeper knowledge of flakes and their associated tooling and I dont feel like I am missing much.

@BryanBennett Interesting, thanks for that perspective. We'll have to see where I land when I get time for another attempt.

@develwithoutacause Hm. Your shell is sort of a separate thing, so your build should just be a matter of your default.nix `callPackage`ing other files, right?

I'm not the best person to ask, I'm still a beginner, too unfortunately.