 They're hidden I'm gonna leave this mic on you're the first of the day Test test cool Do we have anyone that knows how to operate a projector never mind All right, so this is where I'm gonna stop wasting all y'all time and We're gonna get started even without the amazing slide deck that we've designed for everybody So first of all welcome to Nixcon North America for the first time I'm tingling. I mean when we were thinking about this last year We said Nixcon in North America 21 years has passed. We can legally think here now so maybe I guess it's a good time and We kicked it off. We kicked it off with a lot of ambition a lot of volunteers and Honestly, we didn't know if it was gonna be us five more peoples and maybe four folks. I got lost from scale or this so Wherever you all came from the trips you took to take here Huge. Thank you. This is just really exciting to open up a new conference in a new continent for the first time So thank you all we should probably introduce ourselves My name is Zach. I was in charge of putting together the program And this is Ron We both work at flocks flocks purple But honestly, this was something that I wanted to do just because I got to go to Nixcon last year for the first time And it was awesome. It was nerdy. It was full of weird stuff and it was great So I wanted to bring that here So there's a couple of people we need to thank for helping us put this together So there's Ilan Rabinovic Dep he's one of the scale organizers and this would not have been possible without them Also, Catherine Saunders was somebody that helped us do a lot of the administrative work One day we'll get the projector working Who knows when that day will be? So yeah, we're obviously running a little bit So everyone that took part in being volunteers because there's a huge list of folks that just made this happen Can you guys like raise your hand for a second? Come on. Come on. Raise your hand. Don't be shy. If you did anything Raise your hand and that's a huge This was made in three months by a group of folks was just passion like nothing else So so we're expecting a lot of things to break. We hope there's a lot of patience And you're gonna see yellow lanyards. Those are folks you can ask questions and they'll try to help you or try not Yes, that's how it looks like so and again a giant thank you to scale We decided to co-locate with scale I won't bore you with the whole story of how we got here, but you can find us. We can talk about it We can have beers so going through the deck that we do not have Hand it off to Zach That assumes that I remember what's on the deck So yeah, you want to just show the laptop to me so I can read off of it We have a great slide full of sponsors That hey, you know what that makes sense Yeah, this one says welcome to Nixcon North America cool Yeah, just show us the screen for now. We're just gonna we're gonna do it live That's today the most important part of today though is karaoke today At 9 p.m. At the boulevard you'll guys will have that information in a sec when we hook something up It's a bar 10 minutes from here karaoke. There are some karaoke stars in here that I highly recommend to come and see Do it? Tomorrow tomorrow we're doing actually half a day of talks There we go We did it here's the list of volunteers all these people made this possible huge. Thank you Like I like Ron said we threw this together in three months Tom do not touch your laptop Okay, so leave it here Session eyes. This is the app we use to put the whole schedule together and stuff like that This is a progressive web app that you can install to your home screen It has a schedule for the talks which rooms they're in stuff like that It's very very nice very helpful You can also like favorite talks so you can you know say oh I'm gonna be in the hallway track for most of the Day except for these couple of talks very useful, so definitely grab that Okay, yeah, so here's the agenda so we have a couple of workshops today, so we have rock and tom up first They were supposed to start a few minutes ago. It's fine Okay, so on to the next slide Karaoke like we said that's tonight at 9 p.m. Gonna shred that stage On to the next slide No, go back go back Yes, they were really nice to us like that was only 100 sure come on over. Yeah Yeah, so that's before the karaoke your choice Are you are you buying Yeah Okay next slide Other than the fact that you know be nice be cordial We are going to be doing an ICO today just like we did in September What that means is why we're gonna unleash a Nick's point. It's all sponsored by Yoko. Don't worry about it But on reality there's an amazing individual in the crowd here. His name is Ross Turk and he technically handmade with a machine Nick Ponds So If you ask cool questions and you do cool things over the next few days, you're gonna be given Nick's pot Can they buy you something not yet? yet Yet, but maybe at some point. There are also denominations of these five white is the first one Okay, last thing we do before we get started It's my mom's birthday. So you're all going to sing her happy birthday So her name is Laurie. It's not on a slide. Don't worry Tom You all are gonna sing her happy birthday her name is Laurie Ron take the mic. I'm gonna operate the camera Did I just start the karaoke now, oh Wow Nick's gone North America for the first time. Thank you guys. Thank you everybody. There's a survey It's gonna be up. Tell us what you think that's what's gonna make next year happen and one final shout out This person on stage organized the first Nick's con ever and now he's gonna tell you how to do Nick's which I think is pretty cool Tom's all right as well. He'll introduce himself. All right, and with that we're gonna hand it over. Thank you guys apologies wait Dan Yeah, come on funnel start funneling in cool And if anybody wants to be part of the leading and on conference See me outside. We're gonna do a little on conference workshops and the hacking Outside Thank you. I know he's just telling that there's a seat next to him Yeah seats over here Sits over here There's like five more seats seven more seats over here If you want to come in while we wait Hello, whoa, that's loud Okay, Walter technology doesn't mix Yeah Welcome also from from our names. I'm rock Flew too long to come here. Well, but I definitely say it's worth it Yeah as Ron said I Organized the first Nick's con it was in Berlin 2015. I was still without a great beard Basically, it went like this that I was I met up somebody regularly in a kebab shop in Berlin You use Nick's I use Nick's. I know 50 people. He knows 20 people. Let's organize the conference and that was basically it so the first workshop we have is how to basically welcome those who you those of you who are Are new to Nick's To walk you through all the hurdles you might have so yeah Tom well, so yeah, sir Okay, welcome to Nick's con. This is awesome. Thank you so much. This is great So the first thing I want to start with is say, yeah We're gonna try to kind of do this whole conference as a way to get a lot of incoming excitement a lot of Beginners that was the whole focus for how we kind of put this together was focus on this kind of new Arena focus on the people who are trying to Kind of show up and learn about this and so for that that's kind of what all the workshops are kind of a bit more geared towards As the talks are gonna be geared towards so the first thing I kind of want to ask is Who already is comfortable with using Nick's give me some hands higher Higher higher. Okay. Okay. I see some people who I know are lying higher higher higher keep them up No, no, keep them up keep them up. Okay. Okay. Okay. Everyone who doesn't have their hands up. These are people you should ask questions to Thank you for volunteering. Thank you for accepting the responsibility of introducing Nick's to all the other people Sure, why not so Actually mean this seriously like there's a lot of people here who are like we just heard about this We just showed up. We don't know anything about it. And well, we also have people here who know a lot of things so talk to each other interact and Yeah, you saw the hands. So thank you for volunteering All right. Yeah, so I'm Tom Breckney You might know me as Tom Breck and we're gonna try to give you just kind of get you started kind of figure out how this whole Crazy thing that works while we're dealing with technical difficulties Okay So You heard about Nick's somebody told you it's cool reality this Very so you will as we all did Fall into the trap of Nick's it promises us a lot. It actually delivers a lot of those things, but it's really hard to get there This talk this workshop The main focus is we know about those traps Will bring them will basically go together through them We won't discover all the traps. You'll find some of them yourself But basically what we will get is of course We'll talk about a bit first trap is ecosystem Where is what how do you get access? What are all those names? That you'll hear the second thing will go together and install Nick's yes, please Yeah, so the we have a bit of a problem with recording is being the slides The slides will be public and recording is happening there. Hi mom No, birthday. No, no need to sing yet so Yeah Where was I installing Nick's it's as much as Nick's should be easy to install They are problems as with any software, but once you're having it, you know, everything gets easier Well, next thing will go through over some basic commands some pitfoils that we have we are improving things Of course in the next ecosystem, but there are still some Things that you're used to from other tools that maybe work differently than expected We'll go together through them. Then we'll have we'll talk about flakes No, it doesn't matter if you know about them or not will explain them Nick's language That's a hurdle you see where it comes it's where it becomes really steep that's That point and then we'll go how do you use it the next language to create your own development environments? We'll go we'll look That's an advanced topic, but we'll still just briefly look at it Just give you a hint how to create a custom package And at last we'll just Unwrap the basic let's say concepts or keywords some reference points Yeah, so that's that's going to be the whole journey today. So let's go you want to take this one Okay, so one of the first things a lot of people sometimes come to the ecosystem and there's a lot thrown at you You kind of have all these terms that might be a little bit weird There's all these different projects there's all these use cases and you have a particular use case in mind or you might have a conception or you don't even have one and Having so many concepts thrown at you at once is often difficult. So we're trying to kind of maybe Establish a few of them. We can't cover all of them because I'll probably confuse people more so First off how does this whole thing start way back in? 2003 right Ilco wrote this thesis about hey, we should be able to Deploy software right. I actually really like the quotes. I'm just gonna keep reading this every time I'm on any stage Right this thesis is about getting computer programs from one machine to another and having them still work when they get there That's really not a that's a pretty good statement of what it is. We're trying to do so go read it if you want But that's great. So some references some links so you guys can kind of get started We're gonna cover a lot of just about what the next language and the CLI does today and get you started That's kind of the contents of this workshop Again, it's not gonna explain everything. It's not gonna go into all the details It's we're just gonna give you enough of an introduction so you kind of see how people are using this Question in the back We can try to do some dimming. Yes Or no, maybe not Apologies Yeah, so the And the idea here is not always to go into like anything advanced as soon as we started to find ourselves starting to talk about advanced topics We try to pull ourselves back and not go into so much detail All right, so Nick's is this kind of tool that allows you to run those programs on other machines and get me to make them work But you need other things around in the ecosystem just do that really really fast and That might work so The next big piece of the ecosystem that you'll probably kind of come across is this thing called Nick's packages, okay Yes, whoo? Nick's packages is a Bunch of recipes a bunch of descriptions of Software that is out there a large piece of the open-source world is kind of available via this mechanism And it's maintained by a bunch of people doing a lot of hard work for a long time So definitely thank them and this thing is pretty big. It's pretty expensive Expansive and it's pretty useful and knowing how to navigate it though can get complicated So we'll try to kind of introduce some portions of this Then there's more pieces To the ecosystem right then people said hey this idea of making software work is really good Okay, making it reliable is really good. What if we build an operating system on this? Okay, we're gonna build it on as a Linux distribution and do a whole bunch of things with this package manager Because up until this point the operating system Even have an operating system for this it was actually a package manager that coexisted on other systems Whatever your other system was you kind of put nicks on it and use it With Nick's OS people said hey, let's kind of take this idea and kind of run with it So I also want to make sure there's it's clear that you don't have to use the operating system to use next So often a misconception probably because the web page URL is Nick's OS Apologies for that and there's lots of other things out there and each of these things either have a use case or was just someone's crazy idea that became popular or Is just a crazy idea and just is still a crazy idea, but there's a lot of things in the ecosystem We want to give you the highlights of like where to get started Okay, so one of the first things that we want I want to say is before we get into actually getting started is We know it's kind of gonna help there's a lot of people here if we want to do some overflow I know they're going to be trying to set up some talks outside But the format we're trying to go for here is a lot of questions we're gonna go pretty slow and Trying to make us so that everyone can kind of either like keep up keep track We want this to be hands-on. We don't want to be up here like lecturing So we're gonna be like introduce the concept or introduce something and then we're gonna actually just kind of walk around and make Sure, everyone's kind of understanding it kind of do this in a step-by-step motion. So Yeah, let's get this started first obstacle installing nicks It's not hard if it works of course What you will do you will Google most likely or Bing it And you will find this website and you will go to it and you will be presented with something like this Hopefully that's the last time you will curl something in your shell but the first problem Is there because there is a choice? while choice is nice in this case is a problem and what's the Choice that you have to select for if we have a multi-user Installation which is recommended and a single user installation and you will say why is that important? Even worse we say When you do multi-user with how the flag for the installer is dash dash demon So it's not multi-user, but demon and the other one no demon so This is the first problem and you know it scares a lot of people. What should I do? So a Bit below this of course a lot of people miss it. I did is What are the pros and cons? This is going to be very sort of short if the the multi-user Installation will in is a bit more Involved it does create users as the name suggests and it runs then after the demon But it's a bit and but it produces a better installation of nicks the single user is Much easier because you literally just put the binary somewhere, but it's the there is no demon The demon which runs in the background Assures the packages will be built reproducibly now. This might not be a problem if you're using In all the environments, so if you can use the multi user installation or the demon installation, we can also say And if not single user They are environments where you cannot run the demon in the background an example of them One example of them is a docker environment All right, so inside the docker when you install it Majority of the time you will run in a single user installation. What does that mean from a user point of view when it will you be using? When you're going to be installing packages from already pre-built Everything will work command line works the same way everything behaves the same the only the problem become I mean the problem the only Difference comes when you are building new packages and when you are building The things that you build what we say makes is they might be not pure not reproducible but I Mentioned Nick's this is how you get we also ship Nick's in a docker That's if you want to try Nick's you're familiar with docker We all have to be that's how it is Docker run Stash it Nick so as the slash snakes and you will be greeted with a Nick's installation There is also some other instructions on the website how to mount the current directory so that you can work with your current codebase there is also What we forgot to say There is also another let's say we're looking forward how to improve this installation So there is a different installer being developed alongside the existing installer It's being done by determinate systems It's a bit more reliable So if you the default or the official one fails, you might give this one a try you'll have maybe more luck And this is hopefully soon because soon going to become an official one right so Thank you determinate systems for work to work on this. Where are you? Thank you Verify that you're running Nick's on your system when you install it and Now the important part This workshop How to explain this To not confuse you more let's do this way Nick's is a community of People with different backgrounds different needs and we are not maybe so We don't think the same we have different as we have we have different needs so How Nick started is not sort of where How Nick started is that it became it was this policy free collection of tools that you could use together This means you had bunch of command line utilities that you were you just knew how to use together That was not very cohesive way What happens a lot of other package managers because they only do package manager package management job Have this one Common line utility that guides you through the whole process The UX is much better for this reason You will need to put in your it's not yet official But you will need to put the this following incantation in your next configuration Experimental features Nick's command and flakes We will explain what this means But for the purpose of this workshop we will be Referencing this because it provides a better user experience Especially for somebody coming to next not the perfect one, but the much better experience We will explain what this means right for for the purpose of now This is the the magic that will make all the other commands in this talk in this workshop Work yeah Did somebody already install next while I was talking you're a lucky one You had a good network. That's why So Yeah So I think actually let's take this one as a moment of to pause Actually, let's go back Let's actually start doing this like workshop style. So You know is I presume everyone with their hands raised probably already has gone through this and is somewhat familiar So I'm really interested in all the people who did not have their hands raised and maybe are starting to kind of go through this so if you're running into problems we have a bunch of people with Volunteers and lanyards and all those people who volunteered with their hands up like start figuring it out Like we're gonna try to do this Kind of with you. So if you have any issues if you're going through it right now, like literally raise your hand and yell at us Absolutely. Yeah, so one nice advantage of the the term is system installer is you don't have to kind of do this manually cool Question was is there a Docker image? Yes Yeah, so with that particular image right there You're gonna have to go through that configuration trick as well But there's a Docker image if you want to just have a really low barrier to getting started and Don't a deal with like making the demon choices and all that question Yes, that's the recommended one. We've got on there. It again can work either way, but the recommended is to you the multi user Sorry, the question was if you're the sole user of a laptop should you? You know do which which style of installation? And the recommended is still to do the multi user some of the reasons you might not want to is if let's say like can't because of Like permissions, let's say you're not the administrator for your computer You're on some other sort of ecosystem that like makes that more difficult then you know You can't run services or something along those lines. You could see there's there's reasons for that Question yep Switching over like that. It's gonna be cause you some issues So if you've got one already like up and running then stick with that If you need if you already did that and you want to switch over you still can be got to kind of clean up after Can I do kind of go through a process to install if you've already done so is that an issue at the moment? We can get you some help Yeah, if you're good you're ripping running then just leave it for now But if you do want afterwards help to like switch that over just contact some one of us and or ask someone and we can get That going pretty easily How's everyone doing and we kind of caught up? We're gonna slow this down as much as possible. So I want like I want thumbs up. I want hands up I want whoops and hollers Why fly slow, okay, okay, I Can't I don't know what I can do to make that faster Okay, which one? Okay, so Yeah, so this is basically a kind of the the configuration one line Just add this at the end of your nix.conf located at Etsy nix nix.conf And then at that point you should be able to run the following things and kind of follow along Question. Yes Yeah, the question is if it's not created then you can create that directory and make it and then if it's in the right place I'll get read So the question was how is nix the package manager different than other package managers? We're gonna answer that as we go along But do you kind of give it just a quick response? The difference is this is something that or the biggest difference you'll kind of see is that this is something that can coexist on Other ecosystems so it's not like sometimes in Some places you'll have a package manager that kind of wants to own your entire system This is kind of like an overlay you can use this in kind of more flexible ways there's a lot more power you get out of it and We're trying to kind of introduce people to what some of those things are and we'll go through that as we go Through the rest of the talk. All right, let's get started then hopefully everyone's kind of caught up a little bit on Installation all right, so basic commands This is a question in the back No, the question was do you have to run something after you modify the configuration file? No for something like this. You're not gonna have to change anything. Okay, so let's get started We're gonna run you through some of basic things It's gonna be we're gonna search how to like manage and manipulate a profile how to run Software how to get software kind of bring brought into your ecosystem into your environment and how to build things So the format again is we're gonna introduce we're gonna pause we're gonna give some time to explore ask questions and then Proceed all right. So first off we want to find software. We don't know what we don't know where it is We don't know what it's called. We want to find it So so running something like this is kind of a great way to get started I like something like H top. Let's actually search for something and this is kind of like the syntax for this So you search for this you say hey, I want to get information and one of the things is gonna be the thing you asked for now To explain what's going on here. This is gonna search for H top in the next packages set that we mentioned earlier This is kind of the place where we have a whole bunch of packages ready and available for you Packaged by a bunch of maintainers who make that possible first thing to note is the You could kind of ignore this portion in the beginning that says hey legacy packages and whatever system you've got Because most that's gonna be filled in for you It's gonna be filled in on your behalf, but this is being like ultra specific a bit more verbose But for the most part, you don't really need to even see that portion Okay Now the first time you run something like this. It's good. Oh questions good Very nice Hot spot if you got hot spots start using them as my is it gonna be the only only a proposal I've got All right, so it's gonna be slow the first time see I already predicted this It's gonna be the slow the first time. So yes, you're gonna be to have to download the things This is kind of like running very Running the first time is also similar like when you run app, you know upgrade or something or up or update You're gonna update your your view of what it is that's going to be available but once this thing is Downloaded once it's unpacked and after you do this like first search Subsequent searches are actually gonna be way faster because there's a cache that makes these things a much nicer And you'll see some sort of output like this so hopefully we don't keep hitting the get hub rate limit, but Any questions so far on just like searching for things and trying to find software there's also search.niksos.org if you want to kind of do this in a web page format and just Put it in there and the results are gonna be extremely similar if you're trying to get information Yes Correct. Good point. Yeah, so if you're already running Nick's OS then right it's a declarative thing You're not gonna probably be able to have right access to that configuration file There's ways to do that. So if you run into that problem, you have Nick's OS already But you don't have the config and you need help raise your hand someone with the hands that will help you Yeah, there we go. We got that one figured out Okay Searching everyone's good. Yes thumbs up thumbs down Go faster go slower. I see thumbs up thumbs up. Okay next Oh common mistake Hey, I just want to search for htop and you get like oh my god didn't work, right? What happened here is the user just kind of forgot to say where am I searching in we don't have anything defaulted to say Hey, every single user wants Nick's packages We don't want Nick's packages to be kind of privileged in some way over other package sets that might be out there So that's just a common mistake. You'll see in the very beginning. That's that's the reason behind that Who's had a successful search? hands up Who who is confused? It's not working. Who's who's doesn't like it? Oh if you want to pog a guy keep that Hands up. This is gonna be a shoulder exercise. Keep the hands up Okay Yes question for a particular chip set so You can also do that by saying you know search for a particular in a particular system But let's I can let's answer that afterwards if you can but you can search for other platforms If you need to by default the search will be for your own platform Is that okay? Question so the question is are there any other common repos out there you can be searching in yes That's kind of the whole that's one of the big points of this like flake ecosystem is that there's other Repositories that I can go search in not just Nick's packages Nick's packages just happens to be the one of the biggest You know most important one kind of very central to the community, but there are you can search in any other thing That's what that's kind of what a flake is when you turned on that feature is you can go search in other flakes for things Okay Moving on Okay, so First thing to note is there's a thing called Nick's profile now We use this kind of in it often in a like ad hoc manner to quickly bring something in this Interestingly enough is not a very declarative way to do things. It's very imperative right so this is used to say Hey, I want to install a piece of software. I want to remove it. I want to upgrade it I want to get rid of it things along those lines. It's not declarative, but it's just useful so using something like this allows you to come solve this problem so This is kind of the basics of it. Let's go see. I think there's a common Yeah, so common mistake made with profiles is Hey, I am gonna install like some compiler and then great Okay, I'm now need to install some libraries and you start trying to do this with a profile And it's not really gonna work usually the way you expect So don't expect this to give you a development environment, right? Instead expect this to just give you access to a program, right? Some sort of like command line utility or some sort of binary But it's not gonna kind of hook everything up so that you can kind of build with libraries and install development Environments or like dev tooling and things along those lines. Just think about this as you're just adding stuff to your path That's it. Not you know, once you start talking about libraries. This is probably not appropriate Nice thing about this is you can start installing removing things moving things around and this is Relatively cheap. There's no you can destroy this thing you can wipe your history. It's safe. You're not going to mess things up This is kind of one of the benefits of Nick's as the package manager that you can start manipulating these profiles and You can roll back you could install you could remove and it doesn't really matter all that much So we got a question in the back We're gonna cover Nick shell just a second after this. Yes, right So one thing that this does is that it adds these packages into this profile And that gets saved in your home directory and there's a reference to it so that when you come back the next day It's still gonna be there So it's a little bit more permanent than Nick's shell which we'll cover in a second Which is even more kind of ad hoc than this Question on the right Yes, so the question is is this a replacement for Nick's hyphen and that's this is the The new like the new Nick's commands replacement for Nick's end Correct So the question is does this pin Nick's packages? So the way that works is whatever that Nick's packages is at the moment that you run this installation It's going to be used resolved pinned down And so obviously that particular profile will use that Once you run an upgrade if you kind of said hey, I just want whatever the next packages is then that upgrade will kind of Try to say let me try a new one if you're very specific about what exact Nick's packages You have during installation. They'll keep it there So you kind of have that flexibility to pin it down or to kind of keep it floating over time Question so the question is is there a way to export from a Nick's profile into a more permanent Nick's configuration? Built in no There are some tools people have been playing with to make that a little bit easier to do that And that's a direction that we might go in but built in no and that's one of the limitations is that you kind of use this thing and Then there's like a conceptual leap to get into that those other pieces of it So this is kind of a little bit independent of that Sorry Yes, so I mean technically there's nothing preventing that from happening And there's tooling you could you can build for that and there's ways to do it But like there's no built-in command. That's like hey export profile But PR is welcome to the to the next project All right. Let's pause here. Are we good on this any questions any thoughts anyone hit any problems? How are we with the GitHub rate limiting? We're not okay. We're bad on the rate limiting, okay Okay, so the question is should we instruct people to use their GitHub tokens so that we get more get off the rate limiting That likely would work But then getting everyone coordinated all at once to do that the right way it might I don't at this point That's that might be kind of a bit too late But if you know how to do it absolutely do it Um Yes There are a few in other places off the top of my head. I'm not I don't know what what other ones to point you at for other git mirrors, so In terms of hitting that rate limit I think the best option you got is to try to use hot spots I just just because we're hitting like everyone's we're coming was coming out of one You know access point and we look like there's just one person hitting it really fast Okay, next All right, so next basic command we got here is Nick's run right Nick's run is to basically like I just want to quickly run something. I know what its name is I don't really want to install it or keep around for a long time And great. I just want to run something. It's you say hey I want to Nick's run you say where you're gonna get it from you can get it from Nick's packages or any other package set that's out there and You say hey hash this one might examples be top I want to run this piece of you know software and it just runs it It does a few things like it downloads it it makes sure that you have it locally all its dependencies exist And they just run that piece of software, but you're not actually installing it anywhere anywhere permanently So it could actually you know a few days later Just be completely gone and off your system because there's some garbage collection mechanism behind the scenes But this is for just quickly running something because you need quick access to it But you're not gonna you don't want to keep it around question Yes, the question is is it common to alias these things if you just want to quickly use them absolutely There's a lot of people that just alias either like Nick's packages or just most of this command So they just want to run and run B top or something. Yes, people do that quite often question ah Good point someone turned on a VPN and bypassed all those rate limiting. So if you got a VPN start turning them on Thank you for the tip Of course Yeah, if you got access to some server somewhere or some other machine SSH to that and go from there That will also help with the community Abuse of the public resources Okay, so with Nick's run if you need a little bit more kind of I got like things I want to do you could say you could add additional Command line arguments if you want to have something that has a dash in it for some sort of options or flags You got to put in this little dash dash that tells you I'm no longer talking to Nick's I want to talk to whatever that program is That's just a common mistake that We people run into right So yep keep it going so question so far issues Has have people been successful or unable to do this at this point? question Yes Yes, the question is you ran into a problem with Nick's search using too much memory on a two gigabyte system. Yep that for that initial search It's gonna take four if you don't you can kind of bypass that in various ways and kind of still make it work But yeah, this is a problem. We're still working on trying to fix Nick's packages is big. Sorry And it's gonna take something along at least like a four gigabyte system to do that initial evaluation Yeah, go question left Yeah, so if you run into an issue that references locales of some kind Then please raise your hand and we'll have one of the volunteers come help you out So if you were if you're an issue with either Yeah, who's a volunteer who can volunteer for fixing locale issues? I See a hand over there So get together if you run to anything that mentions a locale then raise your hand get some help if you Have anything that references a SSL error or SSL certificate error also raise your hand and get help from someone with a lanyard Or just someone who knows what they're doing Go ahead. Okay, so a recommended fix for this is to install nscd Thank you Yeah, so the the recommendation here is to apt install nscd, but get together just literally get up Let's stand up. Let's kind of make this dynamic All right, we question Yeah, so the question is what version of software is there in next packages? Is it the latest and greatest the answer is yes, that's why we love next packages So there's Sorry I'm sorry Ah, if you don't like the latest and greatest You can actually run something that's older so you can go to an older version of nix packages Or if you want something even newer you could start to build your own custom package that has something even newer That's kind of a bit more advanced, but that flexibility is available to you, but generally speaking nix packages is Pretty dang current. It's it's actually one of the amazing things about that that it uh You know in contrast to a lot of package managers out there It's quite current especially if you're running off of like the the latest available Yeah, if you want something that is kind of a bit more stable moves a little bit slower There's we have bi-yearly releases. Um, so the latest would have been uh, 2311 And then pretty soon we'll have 2405 Um, that's usually associated with a nix os release There's also a time period where there's a lot of work put in play to make things up to date make things work really nicely together So there's like an island of stability basically every six months So the question is kind of compare contrast uh nix run versus nix shell. Yep. That's the next thing we'll cover is nix shell So nix dash shell is was is basically the current stable way to do things Nix space shell nix space run is kind of this future looking way to use the command line Yes, so that's that experimental feature we turned on Okay, so this is a clarification to the question about versions There are a few resources available to if you have a very specific version of some software you're looking for There's a uh website you can get to that says you could put in an exact version for something And they'll tell you here's the commit of nix packages associated with that or here's how you can get that exact version Um So that's a bit more advanced kind of a bit more knowledge required to kind of make that work There's some tools out there as well that kind of give you easier access to that feature of saying I want an arbitrary version of software But it's not necessarily built into like the core basic uh feature set um question Oh, okay. So common mistake. Sorry. Um, so uh nix run is kind of this like quick access to something Um, but a mistake is sometimes that the name of so what's going to run when you say hey, I want to run beatop Basically what happens it goes. Hey, well here's a package named beatop. It likely has a Command called beatop or it's configured with a particular thing to say what the main program is And it'll run that program now There are some packages that provide not just one binary, but let's say 10 or 50 or who knows what Nix run has no way of knowing which one of those you want to run If one isn't configured or if you want to run one of the ones that's not the default. So that's like a common mistake with, uh, Packages that provide multiple binaries and that's actually we're going to cover how to kind of work around that next next So that this now we're back to nix shell And here so what does nix shell do nix shell? Is kind of actually at the core hopefully a very simple thing It just says we're going to spawn a sub shell with this thing now in added to your path That's it Right and now you can now say like add something to your shell I'm gonna nix shell this nix shell that and a few other things and now you kind of have a shell We have access to those programs again the simplest possible kind of way of doing so is this thing gets added to your path And it should use continue to use your existing shell So all your kind of aliases and kind of the things you've customized and enjoy doing on your command line Should still be available to you Um go next one So here's an example of a package that has all those multiple binaries You have a bunch of binaries available right under this package called core utils And you want to run a particular one underneath it Here's kind of a an easy way to kind of bypass that limitation of nix run and say hey I'm gonna run this command date out of the core utils package So that this is kind of like a little bit more, uh, you know Uh Involved because you've kind of know this distinction, but it gives you access to all those other, uh, binaries available from the package Oh, yeah, uh apologies looks like dash dash got Condensed into one glyph. So, uh, it should be dash dash command. Thank you Um, so the question is how do you discover core utils? Um, so this is another one where we don't have a built-in mechanism mechanism for this in nix itself to tell you Here is how to get a particular binary by name There are some there's other other toolings just for reference. It's called nix index and nix locate Those things can help you search by i'm looking for a particular library I'm searching for a particular binary and that will search the contents of the packages to give you Uh, what the name is for some of these ones where the name doesn't quite match the package's name. Yeah Uh Johnny Yeah, so, uh, if you're on nix os we usually install for you a helper that if you type just the Binary you want to run or the the command you want to run it will also help give you some hints Oh, you might mean this name or that name, but that's if you're on nix os There's other ways to access that tool if you want information about how to do that search, uh Raise your hand and try to get some help for that Yeah search dot nix os dot org. Um, actually rock over here is the one who built that Uh, that will help you also search for binars if you're trying to find them Okay, uh next Keep going. Yeah, so all this does is it just adds it to your path keep going. Let's Yeah, so okay. Here's just an example of adding two different packages kind of in one command You can kind of keep going and add 15 of them or 10 of them All at once if you wish to kind of say hey, I want to add all of these things to my path for whatever reason If you want to then be done with this you just type exit exit out of that sub shell go back into whatever your main shell is And now that gets you know removed from your shell and you're back up and running to wherever you're doing before Sorry Is this the same uh syntax as the nix shebang? Yes Um, if you're interested in the shebang, we're not going to cover that right now But I will help you if you want because I love that feature, but that's a bit more advanced Yeah, um, so once you exit this it's actually kind of gone So again kind of like nix run that whatever that thing is that you installed might be gone in Some amount of time if you've run some sort of garbage collection So this is not a permanent install onto your machine It's I want to quickly add it because I wanted this tool, but I don't really care about it long term So this is another kind of ad hoc mechanism So so the question is if I have two apps that need to work with each other Should I just use a profile instead? It really depends on what you mean by work together if you mean it's like if it's just two things that Two programs that you want in your path and you're just going to pipe things from one to the other or just use them simultaneously This will work profiles will work, right? They're just in your path. They're just programs that are going to run Where you're going to run into potential problems is if you want if what you mean by work together means I have a compiler in a library Then this approach will not work So I would not recommend unless you know what you're really trying to do Don't try to install like development libraries in this mechanism or use them in this mechanism Because this doesn't activate them in the way that you want for that to work This is kind of again another ad hoc to like just quickly get access to a program quickly get access to something in your path So for again for libraries, that's why I mean by this is only adding something to your path The binaries of your path will have allow you access to run them But first for libraries to see each other There's other like environment variables and there's other setup that's necessary for libraries to work So the distinction is just going to be like yes, these things can run at the same time on this machine You can kind of spawn programs But it's specifically for development and like compiling in libraries where uh, this is not going to be the recommended way But we'll cover that in a second Yeah, um, so questions up to this point Sorry Oh, okay. The question is is this the new way to do nyx dash shell Uh nyx dash shell does something very similar But it does two or three other things as well and over time that kind of led to issues with confusion So nyx space shell is kind of this one simple concept pulled out from that kind of legacy uh command And the way to think about it is nyx space shell. It just adds it to your path That's it And all of that other more advanced things that the other command used to do Is now put into another uh place So this kind of like a more limited feature to kind of keep things separated Thank you for the question next Yes, so the question is how does this work if you call this multiple times? Yes, each time you call this as a new command, it will keep nesting you farther and farther into subshells If you if you want to avoid that you can kind of say nyx shell a b c and d and then kind of You only have one subshell and only one to kind of exit out of but yes, thank you for the question Good question Once you've been so uh nesting down sometimes it is hard to keep track of how many times do I do this or how far I'm in Where am I? Uh, we don't have a command that tells you how many levels deep you are There's no kind of easy way to say exit out of all of them to the top One thing that I often do is I just go I I echo path if my echo path looks ugly because there's a bunch of stuff in there I know I got to keep going There's you can do things with shell levels. There's other kind of ways that like potentially we can solve this problem But that is a user interface issue at the moment Shell integrations can help here that can do some of this logic for you. I think there's something in Zsh that kind of help you with this I think people have bashed ways to like make this easier but built in and like here's like the recommended way Well, there isn't a huge one yet. So we're trying to make this user interface better That would be one thing to make it uh easier to use Ah Zsh integration uh is Yeah, so there's a few uh integrations and a few kind of uh plugins you could use they make that easier Um who entered today Not without the nicks on their Oh computer And he's already having nicks shell An environment like nicks shell with the packages inside Who came without knowing anything about nicks and is now at least Somewhere along the path of this thing. We're handing out pox and things If you want to pog raise your hand basically Okay, uh try to keep going a little bit. We're going a little bit farther Okay, so next command. This is a good game. Oh, sorry before that we oh We're good with questions. So next nicks build This is where it's going to start to get a little bit more involved But I just want to introduce this so that you're aware of like what what's going to be happening So if you call nicks build On the reference to some sort of a package Uh you run this thing what ends up happening you get this result sim link But let's break it down a little bit There's a few things that are going to happen and some of these might have already happened if you've already run Did something like a nicks run or a nicks shell But what ends up what it does is it goes? Hey, uh, let me go find this reference Let me go see what it refers to and it checks to see if you have it locally if you have it locally awesome If you don't it's going to try to download it from binary cache If you can't download it from the binary cache for whatever reason maybe because there's too many people using the internet Then it actually might try to fall back to well Let's say it's possible that no one's ever built this ever in the history of the world And i'm going to try to build this from scratch And this is kind of this fallback mechanism Is uh sometimes confusing it can be kind of a little bit weird So if you see this something building that you were like this shouldn't be building It might just be because you don't have access to the internet or for other reasons Um, but this is what nicks build does and then lastly it says once it's all done Once it's either compiled your software or it downloaded it from a binary cache to make it faster It gives you a sim link at dot slash result And that sim link will be a pointer to the location of where that package got put onto your system And then you have now easy access to it once you start having custom packages Clearly, you know, no one's ever built it before because you got your own custom code This is a common way to just I want to build something I have access to it. I can run it. I can inspect it. I could do things with it And this is how you hook into the like build manager the the build process uh piece of the nicks ecosystem Uh Issues problems with this. How are people doing? Are we going too slow too fast Thoughts Just yell them out Okay, uh any questions So far, we're going to kind of now go a little bit less out of the commands and come more until like Explanations up a few things If you have any questions that need help raise your hand Yep Sorry So the question is um when you run the build command and you get the binary. Where does it come from? Uh, very good question We're going to cover that in the concepts, but basically, uh, we there's a cache that's run by the like nicks os community The nicks community and it's kind of been built for you and then it gets downloaded and uh place there So it Is a helpful binary cache to make things faster for you, but we'll go over some of those concepts in a second Thank you tom that was long, uh He must be thirsty Okay flakes If you those of you who know nicks the logo Um, or you have the Pog It looks like a snowflake Flakes is a code name for um We'll explain why but it's a code name for this experimental feature which um one of the Goals of it was to Uh simplify make a uix a bit nicer On many areas. That's why we're also using it the first question Actually, a lot of newcomers to nicks ask should I use flakes? Makes complete sense To ask this question because uh, it's experimental, but everybody's telling you to use it It's confusing. We are Uh, hopefully gonna stabilize it soon enough so uh that we can uh market as non-experimental Um, as I told you nicks is a community. We have different opinions While we agree on 90 percent of the features or 95 percent of the features of flakes, there are still some disagreements how to For the last five percent, you know, the last five percent is the hardest as we all know So it's going to take some time before this gets stabilized, but Uh, if you're new to nicks, please use them. I think you'll have a much better experience Using them if you don't want to use them also fine. That's there is nothing just some instructions might be different But you can still do all the things that we do with the flakes You can do them with all commands. Just it's a bit more involved a bit few more steps so Flakes as I said are currently experimental, but they are being developed for so long that they are considered like a stable piece of Of nicks by stable. I mean They work well, it's no they are we are not experimenting in a way that there might be bugs inside They're quite useful and I think everybody that uses nicks Majority of them are using it. At least this is this was told by The survey that we ran each year Yes, so there is a it's already You open a how it's called Pandora's box Yes, there are many people that want to do this And there are many sides of the argument how to do it, but there are discussions I think we need to drink more when we discuss this Like alcohol because then you know We will reach the point the point of agreement much faster, but yes I was hoping it's going to be done by today Actually by last year. It's not it's Yeah, it's gonna happen At one point on the other there might be a few changes, you know how it's got implemented, but I don't expect much bigger Oh So, uh, that is the like the road map for the nicks team to make it non experimental And the path towards that is to basically break it down into smaller components And stabilize things step by step until we essentially have all of it So the beginnings of that's going to be fetch tree and then some of these other like aspects But yes that it is the intention But it is a large step a contentious step and trying to navigate that is well not easy But we're yes, we're trying Okay next So just to remind you what makes flakes turn on is to edit the nicks confile You need to able to experimental features which kind of work side by side nicks command nicks dash command and flakes Okay next so The question what I just said experimental, but we still don't know what flakes are As a user I would say you will notice flakes as two things next There are two files on your project that you will start which is flakes nicks and flakes lock As any package manager that you're used to You have let's let's take a npm an example as an example you will write a package.json correlates to flake.nicks where you describe your project and automatically the npm Comment line will generate The lock file for you same works in x you don't have to write your lock file It's being generated for you at the time at the first usage and then being reused So here I really hope you see this but this is the first time you see some nicks code I don't want to scare you We will actually go line by line. So by the time By the end of this workshop, you will actually understand what this does and it's actually not going to be that scary But I want to explain three concepts In flakes what this file tries to do What what you try to Accomplish with flake.nicks first one you defined inputs In this case we defined nicks package input and we point it as you might see To some github location So that's our input. So that's the all the collection of packages The second thing that we uh, the second The thing to explain with flakes is the second concept is outputs You uh, so what this flake uh produces So in simple in simple form we take the inputs We do something with them and we provide you some outputs This is like a function right and that's actually also what it is and the third concept Which is a bit maybe a bit You you you need to get used to it as you will use flakes a lot and also the common line is this syntax Starting with this url github colon and so this is called flake references and they're being used all over also from the common line This one I chose it this style because it's sort of I hope without explaining it it makes sense what it does it basically says Go to github to nicks s organization take nicks packages repository and go to the branch called nicks s unstable So there are many other ways to point to a resource online either. It's just a url Or it's mercurial or it's github or just git So I will not go into all of them, but I think what's useful is this one For now In this example also what we do What we define as an output here I'm gonna go on this side. So we defined a set of packages That's the first packages dot if you see it here After that comes a system. So you provide an output for a specific system As I was writing this on my mac That's my system For the mac and then we provide H stop or basically I should actually write any name. So we this will be our output We assign to this output Something from nicks packages Again nicks packages is a flake Which also provides outputs Those outputs are a bit different in this case we Point to legacy packages and the system And the package in that system so We will go through each line. So we understand the language. So please don't be scared I promise in 10 minutes the next language will be clear because it's not that hard Now to use the output from that From this flake We have a syntax That starts with a dot So when a new command that you learned before was nicks build But you pointed to nicks packages And builds htop or gtop from nicks packages In this case I'm saying nicks build dot pointing to the current directory you're at Hash and htop and this htop is the same as This one it's good to be tall So now you know how you can access how you can define outputs With How you define inputs and outputs in a flake why this is important We will see Maybe in six slides later, but This is the the the reason why we do this it We used to do this in the different in files that were named Randomly not there was no one file. So we had to search. This was before flakes We had different mechanisms to lock these files and keep those locks updated We have different standards how What things were exposed so we say like hey, let's just call these outputs We have different ways to provide inputs So flakes, it's just a standard That does a few things most notably it Provides a nice ux for you on the comment line If you want to work with a flake don't forget dot In the beginning Current repository Okay Questions Sorry I have to for this to work. No Yep Yeah, yeah, yeah, okay. Oh the just so you know github Okay, they unrate limited us on github. Thank you github Two questions here, uh, can you speak up just? Yes, um This is a language question. So I will defer it. It will make sense once we hit a few slides later Yes Yes, so The question was how do I know that I have to export packages and not just something else There is uh, this is basically the Decided standard. So packages is the key name. We will also see others They are Dev shells. They are templates we have also Yeah, there is a schema for this and um, yeah, there are also extensions to the schema Nicks will still work even if you provide your own So let's say you mistyped or you type something else. It will not not allow you to work with that flake It will throw warnings at you. That's all So you can extend it but yeah Documentation covers this in detail like how what's the resolution? Thank you. I forgot to mention this but yes question was Um, the nix build command does it imply packages? Yes Nix build command implies packages. I could actually write the full Name after the hash saying packages dot my arch and the htop what they export nix build defaults to To search inside packages for the current arch If so, you could also build something cross-platform. So you would build um, let's say Some other system which is supported so not everything can be built cross-platform, but you could do this as well um So there are other commands that default to something else and we'll see a few slides later One question. Yes Yes, um, so there are other commands which we didn't cover how to discover what's inside flakes the commands to to Um To look into what's what other flakes output are nix flake Show and nix flake flake info is also another they show very similar or metadata Sorry nix flake show and nix flake metadata those two commands will show what one will show what the inputs are And the other one will show what the outputs are Yes, please Yes, this is I was waiting with this for to finish the questions because this is so the question is what are legacy packages Hard one to explain but Here is my best nix packages, um we're uh started before we we Before we started working on flakes We noticed few limitations in nix packages So you will notice in nix packages. We have a tree structure of of our packages, which is not the most efficient In terms of how we handle when we started working with flakes we noticed this and we set ourselves to fix it so An old let's say it's still current way to be honest It's still the only way but we in flakes. We're calling it already legacy packages so in legacy package packages you have access to The tree of packages meaning instead of htop on it on the end you can say python packages dot and Traverse deeper While with packages that traverse traversal is not possible, right? That's one of them. Um, so eventually Eventually in the future once flakes get stabilized And if you change this happen in nix packages, we will also see In few design decisions need to be made, but we will switch to packages for now the only Uh flake that I know of that uses legacy packages is actually nix packages There are a few others, but they are sort of doing it just to um to be able to Uh work with legacy With the old nix system with old nix commands But that's the only reason sort of it's like compatibility reasons The only really that only exports legacy packages is nix packages This is a bit confusing, but so I think the tumble the rule of thumb is Only use legacy packages with nix packages you will hit You will avoid most of the Bucks this way Um That needs to be decided. I don't think it will I think there is a lot of Maybe it will maybe portions of it will that depends that's That's to yet to be discovered and I would not Way on any of this like one is better than the other I don't want to go into the mono repo multi repo discussion at least not while i'm so sober But yeah, um So the question was what would be the notation for uh in the future? I don't know that's exactly why we we we don't have like we didn't decide upon anything But there's going to be something. Um, there are many directions of this let's discuss them after because you know They're a nice challenge to solve, right Yes behind Yeah, yeah, there are ways. Um, I would put this towards you um, we're talking now, uh I don't want to confuse a lot of I want to avoid confusion for a lot of newcomers. I know that there are many ways how we can go around this. Um, but From the perspective of somebody who arrived to this room without nicks on their laptop And they already having they already know how to run nicks search nicks shell and they just saw the nicks Nick's run nicks install and so on and they already just saw nicks language for the first time um like the rule the uh rule to give them the rule then use legacy packages at least with nicks packages will avoid some Problems along the road because remember we're just trying to get you Across the cliff so that you get all the benefits That will that's one of the suggestions I saw some hand here. No No, okay question when you saw this or Ideas that you saw when you saw this syntax was I have to learn yet another configuration language Raise the hand if when you saw this this happened Oh me too Um When I first saw it really cannot we just use any other number of them? Um, there are reasons why uh first 2003 those were not around Uh, and there are some really nice features of nicks language They once you reach some advanced levels that is why That cliff uh of learning learning curve of nicks is has that cliff in it sadly, um, that's how it is but 10 minutes And I'll teach you enough of nicks that you can Be dangerous that you can break some more stuff Just to give you confidence to go next. I don't want you to fall off the cliff. I just enough So that you will enjoy the pain question in the back Thank you Yes, the last configuration language to learn It actually ends up play it really feels like this at the end So if there is some truth in that, um, but clearly You know play with other languages. They're they're also cool. So let's go next Let's explore let's learn to understand what we just saw and we'll go through some basic things This looks a lot of like, um Jason with a bit different Right same thing. So, um next Name and value we call this concept uh attribute set Uh, and inside you have keys and you assign values to keys Right nothing new like objects in json Dictionaries in python hashmax ruby you name it Some other language has some other names, but we call them important when you will read uh documentation Attribute set so set that has attributes question, please Attribute set is always It's meant something that that you're used to from python the dictionary some a collection of key value Uh items So that you can Yeah, sometimes you yeah, of course sometimes you only use set because we are lazy and because we are programmers, right? Okay next so There are a few differences in the syntax between json and nix Meaning well, you don't have to quote or every string so the keys don't have to be quoted, but you cannot quote them You can have multi-line strings Yay Right, so it's like just for this reason use nix non no json Uh joke, but it gets really useful Um, we have integers. We have floats We have bull ends and of course we have also null Um, that's actually zin valid. I should quote the null here to make it work But uh question Yes, I'll show you Two slides forward, um We also have comments so if you want json with comments Use nix question Uh-huh, so multi-line strings Um, how do we handle the the prefix of spaces, right? Um In nix it It takes the first uh, so it strips the spaces before and after And it takes the It aligns everything by the The first line so works has I don't know four spaces there So it will be it will remove all the four spaces from every Following line so you can have nice indentation Not something from the beginning so you can it will collapse nicely in your editors Uh, you know Exactly jammel cannot do this use mix Yeah Let's continue. We also have lists. We can have different types of Types in the list And one Extra thing in nix that it's not that maybe it's not in other configuration languages But it makes very good sense in a package manager is that we How we handle the pets and so you can reference pets in three different ways you can have them Relative pets you can have absolute pets to point to some file Most likely you're going to point to a other nix file to import And then uh, yeah, you can also the hyphen Point to your home question Yes, um, exactly. That's that's one of the differences which I have hard time switching from one to another length from nix to other languages as we have spaces You will notice there are no Comments, yeah, sorry Are you scratching your head or was the question? Okay scratching So these are the like the basic Types that we have that you operate. They're a bit Sort of they expand on the on if you compare it to jason or yamal But you will see where it gets really useful next one Before I continue is this was that's all clear, right? Similar to jason, but not the same Of course, uh, please fog Good. Thank you for noticing this because I thought nobody will So I will try to I will answer later, but The top level object In every file does not end with the semicolon But every other line as we see ends that's the rule. So thank you for noticing Yeah, yeah, yeah, that's uh You must be one hell of a programmer. I'll say this you notice this So yeah The top level object at the end you don't put Uh Semicolon every other line you have to Question Let's explore this a bit later when we will work with mix eval and Mix grapple next one. Yes, so The next thing I want to Sort of you will see it a lot of times We didn't see it in the flakes example, but we're going to rewrite it To make it a bit nicer and actually to answer a question from From before which was about how you can construct for multiple operate multiple architectures and stuff So we have this called rec keyword at the completely at the beginning before these turns the attribute set into a recursive attribute set meaning You can reference other keys in an attribute set Okay, that's an important one Meaning description you can read reference it to the key also description This is sometimes confusing, but Rec recursive attribute set Okay, we're doing good thumbs up if this was all clear so far Lots of thumbs up doing something good What I like to use nix for is to have a really quick templating language In nix to include in a string some other Uh Value You can use it as a template you see a template will become What the output of the template key is going to be My first flake rocks Um, and this also works in a multi line Right, it will insert the description there Will you use this to replace any static side generators Most likely not but people did and there's other tools like static side generators with nix because why not But this is really useful when you when you are writing Best scripts that need to interact with certain part of the system in the nix system We'll see it later where this really comes useful, but Just having a an ability that you can template in this configuration language language is a really Powerful feature Oh Substitution you've been the templating. Okay. Uh, this is not only for Uh recursive attribute set although this is the case because I wanted to fit two features in one slide So you could use this in any other attribute set But in recursive attribute set I could just reference the description But it could be anything else. We will see also other ways how to not do recursive attribute set Like a local variables. I think that comes next But yes So you don't have to use recursive in order to use the template Okay, I see some nodding. Let's move Yes, so speaking of the local variables So to put something in the scope of the expression you use the let in operator in between you have some expressions that that you can then reuse in your In your template. Can you move one more? So in this case We use in the description Oh, it's a bit We go a bit deeper another You can also have conditionals. So the eval statement I think this Questions of oh, okay. Um, so in this case what we're showing is First a string We are reading something that is defined in the local variable. So it's in the scope. So it's visible at this at that point And we are just returning first or not first and then we're reusing this one As first string first string does somebody notice an error here Yes answer The order no, but good good guess Oh There was it the order does not matter. It's sort of one expression gets Um Does not matter if you release nixos already Thank you. Um The the attribute set is not recursive. So first a string would not be this actually what you see now will not work But if I would put Wreck before the attribute set It will start it will work somebody Do uh, I don't want to ask in a negative way How do you ask this if I say if I ask somebody does not understand that I will single you out But how do I know that somebody I need to repeat it? Do I need to repeat this? But that's what's threatening damn it No way to win a question there Please uh Which portion of it where did uh, okay, thank you. Thank you for volunteering Uh question Uh, uh, if you have multiple items inside let in, uh, they are recursive. So they they see each other. They are in the same scope No, no, no inside let in. So if I would have multiple where I have is underscore first equals true if I would have more lines there because you can have We will see also later. You will need we will actually see an example of that Uh question in the back and then you There was somebody on the left side. No Uh there I will stop you you said he was demonstrated using a function. We haven't even reached functions yet We will Yes, just for the sake it's uh Calling yourself stupid is not good, but it's a stupid example that I came up, uh, but it's Yes, yes Context box local variable. Yeah Question here and then there Yes In the last slide I had the rack I think Because there is no rack I did this intentionally a broken example It's in the notes, uh, but uh In order to provoke why this will not work right so that we go and discover Yes, because Yes, yes, yes, you can still use the templating syntax without the recursive set That is not in the context. Uh, yes It's it depends on the use case. I think it's a lot of times come down to your style Sometimes recursive set can be confusing And sometimes let X let in expression is a bit more verbose Now if you don't want that verbosity use you go to the recursive set at your bit set Question to the left. Yeah Yes iteration will cover Did right Okay, I'll wrap it in two three minutes. Um Yes, um, what's the error if this is not what this will return an error that the first string is not Uh, defined. Oh, yeah. Yeah. Yeah, it will still work. Even if you don't use recursive set Um, because there are things that you can shoot yourself easily like, you know As I said style different people different opinions Um, I'll we'll have to run we are running out of time, but I really like it would like you to learn nicks Next thing to this uh to learn is functions I defined here a simple function two arguments See the semicolons argument one semicolon argument two semicolon and then the expression In this case, we just Sum the two arguments Um, and then I do this in a latin expression so that I can use it outside Right, and I basically sum one and through two. I have one more slide and then 15 minutes. Okay So this makes sense because we'll expand the pit on it next one Yeah, did I say semicolon? Oh, apologies a semicolon goes to the end colons goes in the where you define the at function arguments at the back So so arg one is argument one of a function called sum Okay, and then you have first argument second argument and The expression that gets returned. I see thumbs up Damn, I'm good. Okay Let's go next One thing that we also just come like the functions is any other functional programming language you can do partial application Right, so you can do sum one and this becomes like add one function and I then use it add one plus two The example is the same returns the same value um It's partial application. I think this is just like a cool thing to have Sometimes confusing but it's still cool Next In In many languages programming languages You have named arguments a lot of times In this case, I changed the function to a named argument So this is a bit of reusing the attribute set style Because we provided one argument because you see only one colon But that argument we expanded it in the in the form of attribute set, which means when I call When I call at the bottom sum I have to provide all the arguments in this case There is also a syntax To provide a default value that question mark is a it will if you don't provide it as I did in this case the default value of Arc2 is going to be number two Yes question Again depends on the use case, you know, I think in any language you have reasons to do either or both because After that I could I could have another argument or another named argument set right, so Depends on the style depends what you're actually doing how the api of that function call looks to you So it's all depends experience usually tells you that you did something wrong. So Yes Yeah, so there are ways There are ways how to organize the code I will lead actually up to you after this talk because there are ways That people You can do you can have it in another file You can then import it bring it to this file. There are ways how to organize it, you know, play with it It's a language break it Curses it all those things Yeah, so functions, right again json so nix what is nix how we like to describe it is just The nix is like a json with commands and functions Multi-line strings a few more things next Yes, so how do we run the nix code, right? so now we learn a bit of the language but Instead of using packages like we did before how would I Experiment with nix language, you know, you write some file you write some nix code in a file. How do I? Yeah, run it There is a sub command called eval So you do nix eval and dash dash expression and then you put an expression So if you would need to type quickly check something One plus two you get Three out yes If you have a file you provide dash dash file an example and the output is What was of that file basically if we return an attribute string so There is another one You say I only want the description out of that file That's a syntax So you at the end you provide the description and it will take that key out of the attribute Or complain that you didn't return the attribute set But you return something else that you returned an integer That's it Okay There is another way a more interactive way as any Nice language. You will have a mix of rappel. We also have it nix rappel in this case you go into it You will see there is no description Right because it's how there is a dash l which The dash load or dash l you load the example dot nix code And you type and then the description becomes available because it loaded that attribute set So this is the way how you can sort of Have the rappel experience so you can type one plus two and you will get three you play what's there and then you You can also load the files from That you work on right so it's like best of both What do you use up to you your style your choice your computer your time Next So yeah to finish it off. This was I skipped so many things that it's almost embarrassing Uh, but this is enough that you will understand flake flake dot nix other resources manual This is a reference manual. So treat it as What are what is the what are all the built-in functions which we didn't even cover you will get them there next so that's the How it looks when you get there Um, next one is there is a really nice Tutorial that will guide you to learn the language in depth Uh, that's the link And it's there. I don't know. It's really long. It will take you at least few hours to go through quickly Uh, to relearn it you can come back to it all the time. I did even after five years of using nix And Uh, there is also a bit Behind the scenes and how all these concepts and also other concepts built upon each other. They are called nix pills And go back one This one This is the slide we started with right Looking back at this Is there an increase of knowledge of understanding what this does? right So first of all One slide got skipped Okay, um, we we defined some inputs Outputs now we now I can say it because you will understand that outputs are a function of inputs That return some attributes at again really slowly Outputs is a function. You see the colon That had all the insight as arguments all the inputs that we define above This self is referencing to the self to the current folder. So you what's the revision and so on So outputs is a function of inputs And you return an attribute set specific of a specific format. So path for packages And then you build it see it took longer than 10 minutes because um Yeah, hard with words, but uh question Yeah Okay, we're wrapping up. Yeah, that's All right, no Okay, so we're gonna wrap that up. So hopefully Basically, we had a lot of questions Hopefully answered some of them and hopefully you have more questions now than you started with but hopefully they're different questions Um, so we're gonna move on to the uh next event at this point And hopefully all of this kind of gives you just kind of like a Shock style introduction to a bunch of things Hopefully, uh, that means as we go on to additional ideas and concepts You kind of have heard them before and just be a repetition throughout the day You'll kind of get more and more of these things and as always if you have any questions Ask someone very likely someone to your left or right might have done this before Please like start kind of getting interactive if you need to have a particular in-depth thing We could kind of go off to the side and work on these things in between the events um, but yeah, so far, uh, thank you so much and I'll hand it off to zack here All right. Huge thanks to rock and tom the I know also for the live stream and for the folks in the crowd We're going to be sharing the decks and all the slides from every talk every workshop on the github repo So we'll link that off as well. So don't worry about it. Um, next up We have a let me just actually say the name correctly managing your user land with home manager So give a round of applause. We'll get that started the last sorry before round of applause. Ah, got you there the lunch between 12 30 to 130 We're gonna Oh, sorry, we're gonna start the next session at 130. So just keep that in mind once we end this one Get that started. So now we can do the round of applause Thank you You've been sitting down a while just a quick posture check if you're sitting like a goblin sit up straight Yeah, all right. So while uh, they get that figured out We're gonna do some more question and answer and tom is going to take that away Okay, so while we're waiting, uh, I guess we could just ask questions either about content or just anything else plans evening plans favorite color Any issues anyone run into anyone needs help with anything? Go ahead Okay, so the question is can someone do a lightning talk on nyx repl Yes, that sounds like a good idea. Um I can just try to quickly do one if you want while we're waiting Okay, so Tom's gonna get his lap Is everybody able to hear me well, yeah Great. Thank you Everybody quiet down. We're gonna go ahead and get started. We finally got it figured out. Thank you av team. Thank you All right Take it away Okay, I'm good. Um Yeah Hello, everyone. Welcome to the workshop on managing your user land with home manager My name is Marianne and I'm excited to show you today how home manager will transform your work life Um, but before we get started with the workshop, let me first introduce myself and Give you some information about my background I'm a software engineer working as an independent contractor My past experiences mainly include a back-end application development Where I use languages like c++ haskell and recently Rust I've been using nix and nixOS since 2019 after a friend of mine whose name is yacht tech introduced me to it and I've never looked back before I I was knowing about nick before I knew anything about nix I was experiencing the same struggle that most developers these days still seem to Um experience, uh, which surprises me Like every time I hear it that surprises me to the new and that is most prominently that Yeah, developers still have to fight through an endless list of steps in a read me in order to get a basic development environment setup And thanks to nix this pain was Entirely eliminated for me and my life quality improved significantly and because nix was so impactive impactful to my To my life. I also tried to Give something back to the community through contributions Back in the days. I helped to port the nixos integration test driver from pearl to python I've packaged several packages and contributed them to nix packages for some of them I wrote nixos modules and respective and nixos integration tests And moreover, I've been fortunate enough to be able to use nix and nixos at work As the most projects I have worked on and the companies I worked with where either deciding to switch to nix or I've already been using nix and today. I'm here as one of the nixcademy.com trainers nixcademy.com provides in-person or online classes on nix and nixos Ranging from basic to advanced topics or even customized classes if you have specific needs We also help companies reach nix's full potential As fast as possible But yeah enough about me. Let's continue with the workshop So in today's workshop, I will first give you some information about what home manager actually is Afterwards, we will revisit how user environments are typically configured and managed and what the pain points are with the typical approach Next, I will explain how the whole manager workflow looks compared to this typical approach And how it eliminates a lot of these pain points Then we're going to take a quick look at how to install home manager and lastly I will We will together install home manager on an ubuntu vm and Configure a basic home configuration together All right Let's get started with clarifying what home manager actually is Pretty formal definition taken out of the home manager manual reads as follows Home manager allows for declarative configuration of user specific packages services and dot files It is basically The complementary part to nixos configurations which configure system-wide settings And it was Introduced or started seven years ago by a user called ricey and as of today it offers approximately 3000 configuration options for about 450 packages or services We refer to those as modules and Home manager can be run on any linux distribution macOS and even windows using the Windows subsystem for linux And yeah To better understand what I mean with declarative configuration of user packages We should first go back and examine how User environments are usually configured So after you've installed your your distro on a new machine and you start to Set it up for your current needs You're typically first required to install You're typically required to go through a bunch of imperative steps So first you have to install the packages that you want to use And you do that by executing the install command of your distribution's package manager You provide it with a list of packages you want And on some occasions if you're on a distribution that you're not usually not used to You have to account for different package names and potentially different versions being available through that package manager Once you have the packages installed in some cases you want to install additional plugins extensions or themes for some apps So you go to the internet and download these resources additionally After that you create The the configuration files at the specific locations where the packages expect them to be And then you start adapting the configuration files to your needs or the system types you're running like if you're on a desktop environment or on the server And lastly if you configure a service You usually have to start it manually first or if you make changes to your config You have to restart the service Manually and we can see that this is a lot of manual labor that we have to do in order to set up our user environment and that is already a very big drawback to me and But there are other drawbacks. I was able to Yeah to find with this typical approach and That brings me to my next slide so The first other drawback that comes to my mind is that Configuration files and their respective packages are not coupled So I could have a configuration file present on my system without even having the package installed and vice versa And that is kind of a lot of unnecessary clutter in my home like in my in my dot files um, then Configuration files can't be Programmetically or configurations can't be programmatically dependent on each other So if I want there's no easy way to express for me That if I have one configuration option set to x that the other configuration option should be set to y And then it gets really painful when we're managing Um, the same environment across multiple machines that potentially run different distributions Um, it requires us to rerun all the steps that I mentioned on the previous slide For each machine and then as I said, uh, different distros have Potentially have different package names and versions available So, um, we have to adapt for For these differences and that Well, that causes mainly inconsistencies between the package names and, um Lastly if we want to configure different types of system like a desktop or Or a server, um, there's no easy way for us to compose configurations And, uh, lastly Um, it is very difficult to recover a previous state Like let's say you want to try out a new package or, uh, service And or play around with your configurations If you're not happy with the result, you have to go back to the files and undo the changes manually and Home manager, um, eliminates a lot of these pain points and on the next slide I want to go through Um, some of the features that home manager, um, provides us to do to do so So first home manager and mix can be installed and used on any distribution and even macOS and windows with the, um Windows subsystem for, uh, linux Then the next packages package set supports many different platforms and since it's the same package set For any distribution we're on, uh, we don't run into any package name inconsistency. So we Every time we use the next packages, we use the same package names or the same packages Then second, um, as you heard earlier, uh, in the talk from, uh, rock With flakes, um, nix locks the actual nix packages revision that, uh, we are using in our home manager configuration and that way we, uh, eliminate any version inconsistencies Uh, when we, um, yeah, basically apply our config to different, um, machines And since, first since, uh, home manager configurations are written in nix, we can use Uh, the full power of the expressiveness of nix like we can, um, express dependencies between configurations Um, what I mentioned earlier, which is not trivially possible Um, with a typical way and fourth, um, the configuration of a package is tied to its installation state So if we install or uninstall a package, home manager will make sure that the configuration files are added or, um, removed accordingly And lastly, home manager keeps track of your, uh, configuration deltas. They're called generations And that allows you to easily roll back and recover a previous state by running a single command And now let's take a look at what a workflow with, uh, when you, what a work, what a workflow looks like when you configure your home environment with home manager There's two steps, uh, required. You first edit your home manager configuration configuration files And, uh, once you like it, uh, you run home manager switch and home manager will evaluate your home manager configuration Uh, download all the resources that, that resources that it requires to realize that config And then just activate it and you will be dropped in a environment with any changes you made right away And, um Yeah, that's it. Um, that's all that you need to do. Um, and that's by the way also what the declarative in the definition means that I gave you, uh, on the first slide And, um, in order to use this workflow, we first have to install home manager, obviously And, um, there are two different starting points to from which we can get started to install home manager Um, the first situation is we don't have an existing home configuration Then we would run, uh, the first command, uh, mix run home manager in its switch, which basically, uh, creates an first initial, uh, home configuration And then evaluates it, fetches all the resources for that and activates it in our current environment And the second starting point is we could have an existing home configuration That we, uh, maintain upstream in a github repository, for example And then we could just run mix home manager switch and refer to where this, uh, home configuration is located at And it would fetch our config, evaluate it, again, fetch all the resources and activate that environment And, yeah And now let's take a look at what, um, such a home con home manager configuration actually looks like and, um, if you've been in the previous talk You might recognize a few things So what a home manager configuration is, is basically a description of, um, It's a function, um, where you have to describe what it has to do with packages, lib, config and any other, um, arguments to that function And then, um, you basically list a bunch of options given these, um, Arguments, uh, we will, we will go into a little bit more detail in the tutorial on How you would actually use it and, and how, how it works Um, but, yeah, this is just a basic example in the first line You would see how we would install ripcrap without any other configurations Um, after that we can, um, use the home file, uh, option to tell, um, home manager to create a file located at, um, uh, in our home directory located under config git ignore And we say that the file should have the text result and the s store, um, By the way, we, we configure the global git ignore with this And, yeah, we, we tell it basically to ignore the result and the s store, um, names And further down below you can see what it would look like when we actually, um, coupled the installation state and the configuration of a package. So we can, um, say, um, git should be enabled And we can along the way configure, um, our user identity, set the username and the user email And, um, what home manager would do it would install git And create a configuration files, a file given these, um, like the, the, the options that we configured and sim link that in our, um, in our dot files, um, accordingly And lastly we can see an example of what the programmatic dependency could look like So we say it only makes sense to install lazy git if, um, we actually have, um, Git installed somewhere and we do that by referring to this, um, config argument Which is basically the configuration that is going to be produced by this configuration So it's kind of a way to achieve, uh, reflection or imperfection, yeah And, um, another thing I mentioned is that, um, it gets very easy to do rollbacks using home managers So if we don't like our changes we can very easily switch back to one We run home manager generations and it gives us all the, um, all the generations that we had enabled at some point on our system So if we want to, um, Get back to the state, um, at 1155 we would copy the next door path append activate To refer to the activation script of that generation and then home manager would add another generation with, which basically is the one that with id6 in this case here now And, um, before we go to the tutorial, um, there's one more thing I want to mention And that is, um, that, uh, nix can be installed in two different ways There is the standalone installation which does not require any, uh, root permissions And it is a per user installation and that is the one that is basically compatible with any distribution out there, um, macOS and windows And the alternative is to add your, uh, home configuration to your existing NixOS configuration together with home manager's module, uh, home manager's home manager's NixOS module and down here you can see an example of what that would look like So you're in your NixOS configuration you would import the home manager NixOS module and then prove the option home managers dot users and then your user, uh, you would, um, define your, uh, home configuration and in the tutorial that we're going to do now, um, we're going to install home manager on an Ubuntu VM from scratch using flakes and, uh, we'll create a, um, like a sample configuration together and, um, the final configuration that we're going to build, uh, you'll be able to find that on github or by, you know, if you're free to scan the code so you're not required to take any notes while we do this, uh, you can just follow me, um, what I'm doing here in the front or if you want to, you can also follow me step by step on your own device, but, um, I decided to not make it very interactive today, uh, so I won't have a chance to walk around and help you if you run into any issues. You shouldn't run into any issues, like everything should work if you just follow me, but just in case there's something, um, yeah, you can, um, ask me afterwards and, um, I can help you or any other experience mix, uh, user here would be probably also very happy to help you. Yes, please. You've been rate limited. Okay. Uh, the solution that I saw on, uh, Matrix is to connect to a VPN or a remote SSH, like a remote machine through SSH. Um, otherwise, as I said, I've got a VM here. I, I'm connected to the internet too. I hope that it will, um, work reasonably fast. Okay. So, um, let me switch over to the VM that I prepared. Uh, right. And, um, while we're doing the tutorial, I will also show you, like, where you can find all the, um, um, home manager configuration options. There are many different ways, but, um, yeah, let me first prove to you that we don't have home manager install, uh, home manager installed. The only thing that I did to this machine is I installed Nix and I enabled the two features that, um, Tom and Rock were mentioning earlier. Um, I enabled the Nix command and, um, the flakes. Let me show you that real quick. So in order to install home manager, let's go back to the slides and copy and paste the install command. Okay. Seems like, huh, that's unfortunate. Is, is anyone, um, around here who is able to help me work around this? Excuse me? That would be great. Um, can you come up? Yeah. I wasn't expecting that to be honest. I, I, I hope that there would be a dedicated Wi-Fi for speakers here. Um, yeah. Thank you. Thanks a lot. Okay. Let's see. I'm also not familiar with, uh, GNOME and I usually use exponent and BPA. It doesn't have service. Okay. That's unfortunate. Yeah. That's really, really bad. Um, is someone of the organizers present here? Nope. Excuse me? Okay. Okay. Just brute force. Thank you. I wasn't aware that it was asking for the password. I thought you asked me for my password. Okay. Let's try that. That seems to work. Thank you. Thanks a lot. Let's just hope that it's fast enough. Otherwise, we're just going to spend a lot of, yeah. That's not very ideal, but it's better than nothing. I guess we have a lot of, excuse me? Um, can I con, connect to it through word manager? Can I, can I connect through word manager to it? Or like, I mean, the problem is that, um, I don't have an ethernet, but it's not, it's not the Wi-Fi connection. The problem is that we're rate limited here with the network. It didn't, yeah. But I mean, will it change? Is it a different network? I can try it. Thank you. Okay. That seems to be a little bit faster. All right. So what happened now is, um, that, um, this script will, uh, download home manager. It will initialize, um, our, uh, a flake. We're rate limited again. Yeah. Yeah. Did any of the organizers by any chance respond? Did any of the organizers respond? Uh, not yet. No. Where is the, uh, I'm looking for the charging cable. So how would I, no, I don't. Um, I will, I will just turn this off for a second. I'm sorry. Okay. We're back on. Um, can I ask you for your attention again? Thank you. All right. Um, as I was, uh, mentioning earlier, so that command will download home manager. It will, um, create an initial configuration and the flake as you can see up here and a lock file. And then it will start evaluating our, uh, home configuration fetch all the dependencies and, um, yeah, realize or activate that, um, the, the configuration that we, we, that, that is provided by the default config. So if we run home manager now, uh, we can see it's installed and it also tells us that it, um, uh, created the configuration files under config home manager home.nix. So let's get over there and see and examine the, the files that it generated in a, in a little bit more detail. Okay. Let us first take a look at the flake.flake.nix. Um, um, rock and Tom, um, already told, talked about this, but I would just a real quick go, uh, over, uh, what flakes are again. So flakes are basically an attribute set that, um, expect a specific schema. Uh, most importantly, the inputs and the outputs, the inputs described what dependencies our flake has. In this case, we say our flake depends on nix packages and specifically the nix-os unstable, um, revision and it depends on home manager. And then we tell, uh, um, yeah, we basically define that the home manager's nix packages input should follow our flake, uh, nix packages. Let me see whether I can change the color scheme here. I think that's a little bit easier to read. Right. And then, uh, we have the output attribute, which is basically a function that takes these inputs and then we describe how to transform these inputs to our flake's outputs. Um, so what we do here first is we obtain, uh, nix packages set for our system. Um, in this case, it's an x86 64 linux. If you're on a Darwin or an ARCH machine, you would need to change this, um, system string to either ARCH 64 Darwin. If you're on an M1 Mac or an ARCH 64 linux, if you're like on an arm machine with running linux. And then we define the outputs to, um, to export, uh, home configurations and specifically the OS boxes home configuration. So you could potentially have, um, several home configurations in one flake or exported by one flake. And, um, the way you get a home manager configuration is by calling the home manager library called home manager configuration. And then you pass in the package set that you want to use and the modules, which are, which is then the home, the actual home config. So let us go and see what the home config looks like. And as I said earlier, it looks a lot or it looks exactly the same as what, uh, Nick sauce configuration looks like. And, uh, yeah, it's basically, again, a function that takes some input and we, the output, um, contains our final configuration and home manager or the knit command will create some details for us. Excuse me. Can someone close the door? It gets really noisy for me and it kind of distracts me a little bit. Thank you. Um, yeah. So, uh, home manager, like the running the init will, um, create some defaults for us. So home manager, like, I'll just briefly explain what they are, but the comments are pretty self-explanatory and I'll delete the comments along the way because it creates a lot of unnecessary clutter. So when we start configuring things, you can focus on the actual stuff that we're configuring. Yeah. So we got to tell home manager what our username is and we have to tell it where our home directory is located. Then the state version, we use the state version, um, to, um, yeah, tell home manager basically with what our config, with what, um, yeah, version, our, um, configuration is compatible with down here. Uh, we can provide a list of packages that we want to install or delete the comments real quick. And then there's a home dot file, um, option where we can define files that we want to have in our home directory. We'll see what, what we can do with each of those in a little bit we'll go, um, yeah, we'll configure it step by step together with some examples, right. And some session variables we can define and lastly we tell home manager that it should, um, manage itself basically. Okay. So, um, let us first just install, uh, simple, like just one package without any configurations to do so. Um, we would add, um, for example, ripgrab to, um, this list and we refer to it by writing packages dot package name. Um, Tom and, um, Rock already showed you some ways you could write next search and then search for packages. What I like to do, which is a little bit more visual, there's this thing called mixed packages search. Um, so we can search the unstable channel and I don't know, like in this case I want ripgrab, right. Surprise. There's a package called ripgrab and mixed packages. So, um, let me just add ripgrab here to this list. And, um, just to prove you we don't have RG installed yet and if we run home manager switch, we'll again evaluate our configuration, download all the dependencies that need, activate the config and we will be able to run ripgrab, for example, package, I'm sorry, still a little bit jet liked, right. So, um, this is how you would just simply install a package, but we can obviously do a little bit more complicated stuff. So, let us now start with building the config and ideally we're, we're going to maintain it in a git repository. So, the first thing we're going to need obviously is git and one thing that annoys me a lot when I freshly install git on a, on a new system, like every time you run the git command for the first time, it asks you to, to, um, set the username and an email address and you usually have to run these commands manually to do so, but we're now going to build it once and then once we have our home configuration, as I said earlier, we can just, when we're on a new machine, run home manager switch and all everything will be set up. So, we have to go once through setting up our home config and then we're done forever, like no more imperative runs of git config or anything else. Okay, so in order to, to add, um, git or any package to, uh, home manager together with a configuration, we, um, we can explore, um, the available, um, yeah, um, basically the modules that are, um, provided by home manager and, and we can do so by running home, uh, the manual for home configuration. If we don't have any internet access for some reason and, um, then we can just search for git dot enable, for example, and we can see, yeah, there is, uh, a git home manager module and to activate git, we would need to set this value to true. The default is false. This is the default for almost any package in, in any module and, um, if we, um, search further, um, we can see that there are two options, one for user email and username. So we can go back to our home configuration and then we would write programs dot git equals and we would set the username and, uh, user and just as a proof in the other tab, we don't have git installed yet. We would run home manager switch. Um, and in this case it would download, um, git and create our config based on the configuration options that we gave it here and sim link that config, um, at the specific location. So if we go to our dgconfig directory and run LS Lisa, we can see that we have a sim link called config, which points to the next door. And if we examine this file in a little bit more detail, we can see, um, that it contains our provided configuration. Okay. Um, so another thing I was, um, mentioning earlier is that we can make options, uh, dependent on each other. So I, I, in one of the examples I showed you how to install lazy git only if git, uh, is enabled. So again, um, in order to see whether, like this is very fictional, right? Like whether lazy git is available as a home manager module, we again would look up either the manual. The other way to do that is through this third party home manager option search, uh, tool online, which has like a really nice UI. So we go, we'd go here, type lazy git and we can see someone wrote a home manager module for lazy git and there's free options available. Um, we are going to use enable. So we're going to say, uh, program.lazygit.enable and then, um, through this, um, configuration variable, we're able to refer to our, um, to the config that is going to be realized by home manager. So we have this kind of introspection. So because it doesn't make sense to install lazy git, if we don't have git installed, we would, um, write something like config.lazygit, uh, config.programs.git.enable and that would, uh, only then install lazy git if somewhere in our home configuration git would be enabled. Now this is very trivial because obviously git is in the same file as we have it now, but you could potentially split up your home configuration into multiple different files and that makes it much more composable. So later when you have like a top level home manager configuration for a server and for, uh, your desktop machine, you could like basically import different files which contain configurations for your desktop or for your server, right? It, you would install, yeah, you could install git somewhere where you have a headless machine, but it wouldn't make sense to install a document viewer, um, if you're on a headless machine. So if we run home manager switch, it will again download lazy git and we can run lazy git and it will ask us, okay, we're going to create a new repository with a main branch. That was a mistake because I opened up lazy git in a toothpick. Uh, okay, it's, uh, for whatever reason, a lazy git is doing some weird stuff and showing me, um, not the current directory, but whatever. So we're going to stage our, um, flake. Um, I did something stupid where I, uh, discarded all the changes so the, uh, configuration is gone. It was stupid. Okay, let me run, uh, home manager. Oh, it's just in it. Let me recover the state real quick. I'll go to, you still have git installed, right? I'm sorry about that. And I apparently deleted the whole config directory. That's very bad. Um, yeah, it was, okay, maybe the easiest way would actually be, um, I'm really sorry about that. I will just kill this machine and go and reinstall it. Just one moment. I'll need my token again. So I basically reset my VM and I'm going to real quick, um, rerun the installation script. I will just leave git on here and we will just continue with what I intentionally planned to do. Yeah, the error, um, I obviously used the wrong option, which was email and not, um, user email. So nix will, like home manager will also help you a little bit if you make mistakes with your, um, configuration. So anyways, um, so, um, the example with git was an example where you could, where you, um, benefit from this coupling of the installation state of a package and its configuration. Um, but it's not only like trivial packages like git that you can, uh, install, um, you could also, for example, install VS code. Um, I personally use a new one, but there's a lot of people who use VS code and what they usually have to do once they installed VS code, they have to go to the extensions tab and then look for all their extensions and then manually install them. And you can ever, you can do everything. You can do all of that declaratively in, um, in a, in your home configuration too. And, um, to do so, we again, we can go to our options search, search for whether there's something called VS code in there and there it is. We can enable it through the setting by setting the enable option to true. Um, then what I personally like, uh, is to use, um, VS code and what you can do with almost any, um, home, uh, like home manager module is you can override the package. So if you want a different version or I don't know, um, wrap on an existing, uh, program that has other functionality, you can kind of override it and pro it into, uh, and tell a home manager to use that specific package version. So in this case, you could say, hey, I won't, I don't want to use VS code. I want to use VS code. So let's install VS code real quick and that will, uh, download VS code. And while that downloads, uh, in the meantime, let us see how we can add extensions to this. So there's, uh, extensions options and we provide a list of, um, VS code extension. So there's some extensions which are already packaged in Nix and, uh, you can find them under the attribute VS code extensions. Um, if there, if you, if one extension that you want to use is, uh, under any circumstances, not available through the Nix package set, there are, uh, libraries and everything is explained in, in, in the Nix, Nixos Vicky, um, how you could, um, add a library that is not packaged, uh, with Nix yet. But, um, yeah, let's go over to, uh, Nix packages search and just type VS code dash extensions and by now, like for now, there's approximately 290, um, extensions in here. So what I usually like is, uh, VS code them and, and by the way, the way you would identify or the way these, um, extensions are structured, they're like, uh, you can refer to them by the publisher dot package name. So it would write VS code, VS code extension dot publisher dot extension name. So I like to add VS code them, um, a material theme and a material icon theme. So, um, right. And in the meantime, um, by the way, codium, um, was installed. So without me having to reload my environment, um, codium is available just like this and now let us go and, um, add some extensions. So we can add, I like the, and lastly, we're going to install an extension called Nix IDEs. So we have some syntax highlighting, uh, when we inspect our, um, Nix files. Thank you. But it will probably, uh, I've got another type pool and again, uh, home manager will also download the extensions, put them in the right places. And when we run podium now, um, and go to the extensions tab, we will see, oh, it has all the extensions that we defined here installed. So now let us actually activate or create some settings. Want the material icon theme and one pro darker. And, um, that would, what, what I did here would update our settings.json. So the reason why I'm showing you this, that this is not very optimal. So we would still have this, um, uh, this settings.json would not be, um, managed through home manager yet. So we have to fix that. We would want to add that file to our repository. So, um, we can also have it upstream and we want home manager to take care to put this file at the respective location. So what we're going to do now is we're going to copy, um, copy this file to our git repository or move it. And in our home configuration, there's this, um, there's this home dot file, uh, option where we can again define where, where home manager should put specific files. So our file was, uh, originally at config vs codium user slash settings. And then we would provide the source. And since we moved this file to our current directory, we can refer to it by writing, setting the relative path to that file. And I think we can see that the settings got, um, unloaded. And if we run home manager switch, we'll sim link the file accordingly. And this code should pick up the settings again. And yeah, we can see the, the theme, uh, changed again. All right. So, um, um, I mentioned earlier that is very easy to recover previous states, um, with home manager. So we could probably, we could, for example, um, run a home manager generations. And we know like 10 minutes ago we didn't have this code or you could just track in your men in your mind what, like what kind of things you added to your config. And then, um, yeah. And then, um, pick the, pick the respective generation that you want to, um, recover to. So let's say this early generation that one didn't have, um, VS code yet, if we append activate to it and run it, then and run code again, it's not there. And since, uh, this activation here actually created a new generation in our generations, if we run home manager generations. So there's two ways to recover the state with VS code again, which is basically running, um, home manager switch again, which would evaluate the current configuration or we pick, um, the one with ID five. Since the, this one up here refers to our current generation. And if we run active, activate, code is there again together with its, um, configuration files. And, uh, let us now imagine that for whatever reason, our laptop burns down and, um, we have to, uh, reinstall our distribution and we want to set up our home environment again. Um, I mentioned earlier if you maintain your home configuration, uh, online or it could be also on a USB stick or whatever, you, you can, with one command, you can install home manager and activate your old config. So let's shut off this machine and, um, reset it to the snapshot. And I'm going to go to the, and, um, neither home manager or a codium are installed, but if we paste this command, it will fetch our contact from the git repository evaluated, download all the dependencies. And in a few seconds, we will have all the old, um, user environment available to us. Um, we, we will make these slides available publicly. I'm not sure yet how I will notify you, but I'll probably add a link to this GitHub repository if you have it somewhere saved or I'll talk to Ron and see what, what, how they are going to do that with their slides and then they'll, they'll probably be available, um, at the same place. Yeah. And so let's wait a second. I just want to prove you that it actually, like we will have codium with our, uh, themes configured and everything available. And you'll hopefully be convinced that this is, um, a really nice setup to have, especially if you, yeah, manage multiple machines or your computer breaks often. Yeah. Or even if you're on a colleague's machine, like there's a way, uh, where your colleague could just refer to your online config and import it as part of his config. And then you would have your editor, if you have like a specific configuration, you could just plug and play that together. So if we run codium now, just run codium, it just works. And also the themes are applied and the icons and stuff like that. So, um, that's basically it. Um, I just wanted to give you another list of useful resources. So there's the home manager manual available under mixcommunity.github.io, a home manager, using man home configuration. You can find all the configuration options locally on your machine, uh, using the home manager options. Extranet, Nick search. You can have them in a really nice UI. And, uh, what I, uh, lastly would recommend you is to check out the Nick source viki, which has, uh, a list of various, uh, configurations from other users. So you can draw a lot of inspiration from just reading other people's conflicts and copy pasting what you like. And it should just work on your own conflict. Um, yeah, that was the tutorial. I'm sorry that it was a little bit chaotic. Every time there's some life, um, yeah, presentation of anything that kind of error prone. Um, yeah, feel free to follow us online. We post, yeah, we frequently post blog articles about Nick's and Nick's OS, um, and thank you for your patience. Yes, please. Um, so home manager, with home manager, you would just, uh, configure your own user. You would, you wouldn't configure the root user, but if you manage it through our Nick's OS configuration, you obviously, um, I mentioned it earlier in the slides, you need, uh, root privileges to rebuild your own system because now your home manager configuration is part of your system configuration. You would need root, root rights to do a Nick source rebuild switch. If that was your question, I'm not, not sure, but usually you don't have to adjust any permissions when you use home manager. You can just have it, just install it for your user. You just saw that, uh, it didn't change any, like my user doesn't have any special rights. It's just, I run this install script and then I run home manager to, uh, realize and activate the configuration and that's it. Um, if it's for Nick's OS configurations, I think so. You should add it to wheel and, uh, mm-hmm. Cool. All right. Let's go to lunch. Let's eat food. Cool. Thank you. Okay. So, um, wait, let me first turn off this. All right. Let's get things started. Hopefully you got something to eat, got to move around a little bit and hopefully you're not too sleepy. Uh, because this is going to be cool. Uh, Dan's a cool guy. Um, so, uh, the next workshop is about the module system. So it's going to walk you through that. Um, I just wanted to mention, uh, all of our speakers get these cool little Nick's bricks. And these are, I'm going to point out Ross again. Ross, Ross makes these in addition to a bunch of other little Nick Macs that you get at, at Nixcon. Yeah, handmade in the Ross factory with a CNC machine. Um, uh, yeah, but it's super cool. Um, each of the speakers gets one of these with their, their name and the, like Nixcon in a 2024 on it, stuff like that. Um, yeah, it's super cool. So, uh, if you're ready for next year, you'll have more Nick Macs. Get ready, Ross. Um, yeah, submit your talk for next year. Um, cool. Uh, anything else before we get started? Uh, no, I think I'm just going to go upstage and start talking to the sides. Oh yeah, just your hourly reminder that we're doing karaoke tonight. So be prepared. Um, yeah, cool. Uh, with that, I'll let Dan take it away. Thank you. Cool. I actually want to leave the microphone. Hi, everyone. Uh, you're gonna hear me okay? Perfect. Uh, so we're going to talk about next to us modules. Um, a little bit louder. Can I like, can I bring this up? Hello? Uh-oh. We're not going to do like TikTok style, are we? Um, open the stake. Let's see. Maybe I can bring it down here so I can hear me better. How's that? I think that's a little louder. Um, yeah, so I'm Dan Baker. Um, my handle is Jakku or DJCU. Uh, pretty much everywhere online. Um, I help out with the marketing team. Uh, I'm the big user of Nix for the past couple of years. Uh, and if you're local and interested, uh, me and a couple of our buddies, uh, we run the SoCal Nix users group, which you can find at that link over there. Um, we have about 20 or so people, uh, joining and last, last meetup we had 16 people show up. Uh, we have our next meetup next month. So if you're interested and want to come on by, uh, catch us on Matrix, all the information is on the, uh, the website there. So I want to give a shout out to a couple of people. These guys, uh, really, really helped out when I was preparing these slides. Uh, the whole, this entire, uh, workshop is a bunch of lessons that are hosted on a website, and in a GitHub repo where you can go and pull them or you can like follow the lessons online. Um, each one of these individuals contributed with feedback, helping with dry runs, helping with advice, uh, answering my questions about the module system. So, you know, big props to them. And, um, so there's a couple of ways to find this. Um, the, this is the actual URL for the website. It's got a hiragana tld. Uh, not everyone has the capabilities to type that in the keyboard, so you can go to my profile here. And if you go to this link, it's just on my readme, uh, might be a little hard to read right here. But if you go to my, uh, GitHub, there's a link in my, uh, readme profile, um, which will take you to the website. Uh, this is really hard to, is it really hard to read out there? Yeah. Oh wait, you know what? We can make that better. Watch this. Ah! Technology. Um, zoom in. All right. There we go. Uh, here we go. It is djacu. Yeah. Um, my buddy David has also set up this domain for the next year. Uh, you can go to nixmodules.dev that'll redirect back to my website. Um, yeah. And if you go to the website, you can also just click on, I guess, probably any one of these links and it'll take you back to, uh, repository. And you can check out that lesson and the source code for it. But we're not gonna, we're not gonna look at this. Uh, I'm gonna kind of follow this, uh, the kind of basic layout that's, that's written here for this. But, um, I'm just gonna do it all in, uh, the terminal so we can actually look at the nixcode, run the nixcode, um, and you don't have to just watch me read my website. Um, but if you want to follow along, it's on there. You can pull down the, well, if you can get to GitHub, you can pull down the repository. Um, and yeah, I think we are good to get started. Ah, let's see. There it is. There it is. Any type? I should have picked a different terminal color. Oh goodness. Hmm. Is that really hard to read? Hmm, mm-hmm, mm-hmm. I think if they turn off the lights, it kills the video stream. Oh, they did? Thank you. Um, yeah, so let's start. I'm just gonna cd into the repo that I have locally. And, um, so like what are modules? What, what, what, what are, if you haven't seen them before, if you haven't heard about them before, what are they used for? They are a really useful tool. They are what makes NixOS happen. So, when you want to configure a package, when you want to build a package, when you want to configure part of your system, uh, how would you do that with Nix? And the answer is there's a whole system, a whole module system that Nix uses to do that configuration. Uh, what you're able to do is create kind of a schema of options and then expose that to your users and they can configure those options however they like, however they like, and it builds essentially whatever you want. You can build just simple text files, you can build packages, you can build an operating system with this, and so we're going to talk about how you construct these modules for yourself so you understand how they work and how to use them. Um, so what is a basic module? Well, at its core it is, uh, a function that takes an attribute set and it returns an attribute set. Uh, hopefully by now, since if you guys were here at the first, uh, workshop you were kind of maybe familiar with some of these terms now. Um, so let's take a look at there's, there's one file in the, the first, uh, tutorial, a basic module called uh, Useless.Nix. And there you go, that's a, that's a fantastic module, it's valid, it, it, it takes no arguments and it returns an empty attribute set. Um, and as the name implies it is useless. Uh, so let's, let's, let's skip past that but this, this is a, this is a core structure, we're going to build upon this. Um, so let's look at there's one, I have a file in here called options.Nix. There you go. So there's a couple pieces in here. Uh, you can see and at the top level of the returning attribute set there's something called options. This is the key name that is used to, where you declare all of your options. So if you wanted to have something like, something called name, uh, you can see right here I have something called name. Uh, we use, uh, a function called MKOption. This is the most like kind of generic tool within the module system for creating options. And you can pass it in another attribute set with, with different attributes. The most important one is type. So this is going to set the type that is going to be type checked by the module system, uh, to make sure that whatever you define it, uh, in, in the, uh, a value for this later is valid. Um, so you can see I've set type. I've called from lib.types, the str type, which is a string type, a very simple string type. And there you go. That is a simple option. Use MKOption. You set a type and give it some attribute name. Uh, one other very important thing to point out is, uh, the function argument. So now we're not taking nothing. We're taking lib. So lib is one of a few arguments that are automatically provided by the module system. We'll, we'll, we'll look at some of the other ones that are provided later and show you like kind of what, how this all evaluates for you. But you can just assume that you get the standard library from the packages. Um, so that's why I'm able to say like lib.mkoption, uh, lib.types.string. Those are automatically given to you. The other important thing, uh, is these ellipses. So I don't recall if they were covered in the first talk, but, uh, this kind of specifies that we're allowed any kind of extra arbitrary arguments. Um, if you don't put this in here, your module's not going to do very well. So in all of your modules that you define, make sure to include the ellipses. Um, because some might take lib, some might take some of the other arguments that we're going to look at later, but they have to be able to take all of them that the module system's going to provide. So that's why we, that's why we set the ellipses. Okay. So we have one defined. It's called name. Let's take a look at, uh, what the configuration of the, uh, looks like. So there's a config.next in here as well. And so we, we do the same thing. We have our ellipses. We don't need lib this time. We're just going to, we're just going to define the value for it. Um, and so we're going to use it. We're, the way we're going to do that is with this other top level attribute called config. Um, and that's all you have to do. You say config. It has another attribute set. I'm going to set name here and it's going to be voting the float face for today. Um, and that's the configuration. That's all we have to do for, for, for the option that we've declared. Uh, uh, one thing I do want to point out, I've been using this, these words declarations and definitions. So options here on, on the right, its formal name are, is option declarations. And the one for config on the left is option definitions. These are just legacy names, but I just want you to know that I will sometimes use option declaration or option definitions and they refer to options and config more colloquially. Um, and you'll see that a lot, a lot in the, in the documentation on, on the mix website as well. So, okay. So we've got a declaration. We've got options. We set it to string type. We've configured it. So how do we, how do we get something out of this? How do we actually like see that, you know, this is all neat, but this is still a mix. I want something on my terminal. I want something I can touch. Um, so with the way we do that, let's just get rid of these and go back to, there's another file called eval.nix that I've set up. So this is not a module. This is just a regular mix file. Uh, it's going to take packages because I need access to this function from the standard library called eval module. And the way that this works is that we give it an attribute called modules and modules takes a list of paths to all of the modules we've declared. And that's it. That's how you get, that's how you do your evaluation. It will handle passing in all of those automatically supplied arguments like lib to your modules for you. And it returns back an attribute set. There's a lot of, there's a lot of information in there for the sake of this. I'm going to look at the configuration output, the thing that we want to see that like we, we've set our, we've declared an option, we've configured it. We want to see that it looks right. So I'm just going to look at the configuration output. And, uh, for the sake of myself and all of you, I've included run scripts in all these lessons, which just, you know, runs nix eval on the file, automatically provides that imports the packages and applies it and gives it to the, to the eval.nix file and just formats it nicely in a JSON output so we can look at it. So let's run it. Okay. Go ahead and make a quick piece. Exactly what we wanted. Uh, so this was kind of trivial though. This is a little, a little simple, a little too simple. You know, we, we have an input. It's the same as our output. And we've declared it and defined it in the same space. We don't, we don't have any kind of interdependencies between different options. So let's look at that. Let's look at what we need to do, kind of in the next steps. Uh, let's look at something a little bit more useful. So if you go back out and then we go to the next lesson, which should be called option dependencies. Well, let's look at, uh, actually setting up a couple of, several options. Some we're going to use as inputs that we're going to configure. And then we're going to use the last one to actually use the values that we, that we define for all those options to create like a little message for us. So most of these lessons will have like an options, a config and a valid and a run script. Um, so in our options.nix, let's take a look up here. Okay. So we have some more arguments. I'm going to talk about config and it's like, but we still have live and we still have our ellipses. Um, so we have a few more. You can see we have a few more options now. We have a name, we have a title, we have an origin and we have a greeting. We're going to use the first three to configure something, to configure what we want our greeting to say. Um, and in this file, we're actually, we're configuring the value for greeting right away. We want this, we want this kind of part of like the module that we give to a user. Um, so how does this work? Well, you can see there's this CFG right here. So let's go back up and look at where CFG is coming from. It's coming from this line, which ultimately comes from config. So config is another one of those arguments that is automatically provided by the module system. It is kind of the lazy ultimate value of the configuration values that you set. So in another file, we'll configure like name, title and origin and config will be aware of what those values are. We can then take them and then use them down in greeting. This is all just kind of happens, you know, this is, this is the kind of like nice lazy nature of, of configs. We don't have to have these immediately available in this file. They can be in another file and we can use them here. Um, just as, as a note, this config is not the same as this config. This is the configuration that I'm, I'm setting up right now for this, for these particular option definitions. The config at the top, that's part of the module function argument is the, is the final evaluation of all your configuration. And this is, this is why you'll see this a lot if you look into anything that's created within the next module system. Um, sorry, that are like, if you look into any of the options that are on the search.nextOS website, you usually see this like config equals config dot something. And for us, like we're just looking at the top level, so I'm just gonna say CFT equals config. It kind of, kind of helps mentally separate the idea between like final configuration versus like configuration I'm setting right here. Um, but yeah, so I'm gonna say greeting is hello. My name is the configuration value for name. I am a configuration value for title and I am from configuration value for origin. And let's look at the config. Yeah, so here I just have to set up. It's similar to what we did before. I'm just gonna, except now I have a config for name, title and origin, along with these options. And I'm gonna use what we did, similar with the eval dot nix to combine them together and say evaluate both of these files together. Yeah. Actually, this is eval greeting. There's actually two evals here. This one is eval. And we'll see right real quick. So let's just exit out of this and run dot shell. Okay. So this is neat. So you can actually see like we have the configuration at the bottom. We have the configuration values for our name, origin, title, kind of like we just declared in the config dot nix file. But look at greeting. Greeting is, it's actually injecting those configuration values for name, title and origin into our greeting string. It is a little bit kind of hard to read because it's, you know, spit out from JSON or using GQ to try to format it as best we can. I have included, if we just look at the, there's another eval dot nix. There's eval greeting dot nix. I only want the greeting output. These are attribute sets. So you can just say, just give me dot greeting. There's another run script to go along with this. There's a run greeting. Just points to the run eval greeting that file instead of the regular eval file. But if you just look at that instead. Yeah, there you go. That's a nice, that's a nice pretty value. It says, hello, my name is Vody McBoatface. I'm an on-autonomous underwater vehicle and I'm from England. These are all very true statements. And yeah. So now, so now instead of just like using the configuration value or the configuration declaration and just setting the value for the same input or same output, now we've used three inputs to define what one output should be like. Let me just give a quick pause. Any questions so far? Can you say what's the instance of Nix packages? Which instance of Nix packages does the library that I'm using come by from default? So I'm using Flakes for this whole website. So it's whatever is pinned in my clock file. You mean like these ones up here? No, you can omit this. You could delete that. Let's do this and just delete this. And here I'm just going to change these to something. That's valid. That'll work. I use it mentally so I know which ones are which. So when I'm looking at them, that is my final evaluation. And also you usually see it, like I said, when you look in any kind of like NixOS module that's declared and like in the repo, they'll usually like try to access, they'll have multiple configs like accessing different layers of the configuration and it just gives you like a kind of a quicker way to get to it. Yeah. So he was asking in this right here, I'm adding the other one. Okay. And let's look at this one. Yes. Yes. So this is adding, yeah, these name, title, and origin are being added to the top level configuration. Yes. I could have taken these. I can do this. I can just do it like that. That's valid. But I'm showing you in a way that you kind of like for this something this simple that you would want to architect like you have an options. You give that to the user, they set the config. That's why I've kind of separated these things throughout. You see this a lot within like the module system. You know, you don't want to, you don't want to set these. The user wants to set these. But you want to define what the greeting is going to be because they want, they want that final output product. So that's, that's why they're set up like that. Yeah, go ahead. Yep. Well, they all get output. I mean, I think we saw that. Yes. Yes. Yeah, you can see, I think in, in, in these lines. Oh, I can't highlight. Let's go over here. Yeah. And all these, that's the entire duration. Yeah. And then the second one I just said like just gave me the greeting output so I can see the, the new lines. Yeah. Yeah. We have not talked about that yet. Merging. I didn't have, I don't know if there's enough time to talk about merging. Sure. And actually I've, I forgot to talk about this in the game. I am talking with the documentation team about this. I don't know if you guys have seen, there's one article on module system on Nix.dev which is the current official like outside of the manuals documentation. I've talked with the documentation team about bringing this all over. So if you guys have any feedback, good, bad, positive, critical, whatever, please find me after. Let me know what you think. This could really be helpful for future Nix users. But yeah, merging, the way that these are structured is to build like one little step at a time. Merging comes after enough foundation has been placed. So now we've got option dependencies. I hope that there is one. Talk to the architecture team. Okay. Okay, so let's look at, let's look at the next one. Let's look at the next, do I have anything? No. Splitting module. Okay. So you can imagine, this is the start. But you can imagine as you build up, you might have a module that gets quite large. Or you might find that you're developing several modules with option configurations in different places. And you find that you have some code reuse. Like, oh, that could be like a little piece right on its own. And I can, I mean, I could use the same kind of options in multiple places. And you can do that. There is the third kind of top level attribute. We've talked about top level options. Talked about config. And let's look at, well, let's look at some individual files first. I've taken kind of the previous lesson and split it up. So now we have a name.nix that just has name. We have a, let's see, what's the next one? Title.nix that just has title. This is kind of the same stuff we've all seen before. We're just declaring an option right here. But these are all just single ones. And we have an origin.nix. That's an option.nix. How about an origin.nix? There we go. Okay. So how can I combine these all together? Well, imports. So this is the third major attribute that's available, kind of the top level of the module system. So with imports, you just pass it a list. And you pass it, or you give it a list of paths to all the other modules you want to do. And here I've given the path the name, title, and origin, which are all in the same directory. And this is as if I had just declared them all in this file. It's exactly like the same as we saw in the previous lesson. But now, like, I have reuse. And that's basically it. I mean, you can see here I've got my greeting locally defined. I've got the configuration for greeting locally defined here as well. If you look, there should also be a config.nix that has the same configuration as before. And if we run this, we'll get the same thing. But this is nice. This allows you to, like, say, like, oh, I've got this nice, like, tight little module. I want to, like, put it away. I don't want it to be, like, you know, injected into this code here. I want to be able to use it in multiple places. You can use imports, and you can just pass them, pass their paths. Yes. Yes. So the question is, is like, if someone's already defined a configuration value, can you override that? The answer is yes. There is a priority system. It is, I think, one of the last lessons that I want to talk about. And hopefully we can get to it. But yeah, you can't, you absolutely can't. Yes. Not necessarily. I'm just doing this because that's how the lessons are structured and to be very simple. You know, for this one, let's see, let's take a look at the eval. If everything at the top level, then they're pretty much the same. But we're going to look at some special types called submodules that allow you, like the name, they allow you to define submodules. And sometimes you want to do imports at the submodule level and not at the top level. Yeah. Of course. So if you're just doing, so the question is, like, what's the path availability for these, just repeating it so that people can hear better. What's the path availability for these modules? So if you're working with just, like, regular NICS stuff, like not talking about NICS OS yet, you have to, like, know what the path is. I have to be generally, I think, relatively available. Like, all the stuff that I'm doing is, like, all relative directory. You could probably give it an absolute path as well. The only question is, like, if it's not in your repo. Yeah. So, I mean, you can do all sorts of cursed things. Just don't expect anyone else to do it, use it. One thing I'll just touch on, if you're talking about NICS OS modules, you have another special argument. I believe it's called modules path. And that is, I think, I believe that's another automatically provided attribute that I don't have in the lessons, but it's kind of important to talk about. It will give you a path in the NICS packages repository based off of whatever instance you're using to the directory that has all of the modules in it. So if you, let's say you wanted to extend NGINX or something like that, or extend some other package or some other service, rather than having to know where everything is in NICS packages or, like, having, drilling down from the top level of your NICS packages instance, you can just say modules path and just slash from there. Really, really handy. You can, that, I believe, is documented on the website, on, like, the official manual, so you can go look at that. Okay. So splitting modules was pretty simple. We're just doing imports. And the next lesson we want to talk about, ah, arguments. So let's go to options, arguments. So generally, without any kind of conditional logic, if you declare an option, you have to define it when you try to evaluate them. If you try to evaluate an option declaration that doesn't have a definition, in other words, if you have an option that doesn't have a configuration value, the module system will throw an error at you. But that's, I say, without any conditional logic. So there's a couple ways to do it. One of the ways I want to show you real quick is with, ah, using another automatically provided keyword, options. So this is the kind of final, you can think of it as the, like, the overall, the accumulation of all of the options you've declared. And it has a bunch of information in it. Like, if you go down inside options and we wanted to look at, like you said, options.name, it has information about its type, it has information about, ah, let's see what else. If it was defined or not, ah, see what else kind of stuff do we have. There's a lot of things you can look at that you can find in there. And also, similar to config, this options, it's not the same as this option. One is, one is all of the options together. This option right here is just what's local. Um, but what I can do, let's say, let's say I wanted to amend the things that we've done so far in this lesson. Let's say I wanted to give the user the ability to only define some of the things that we declared. Like, I didn't want to, you know, we have name, title, and origin. I didn't want to define title. I just wanted to name an origin. You can do that. And that's because mix is lazy. So I'm going to do something similar just for the sake of my own sanity. I'm going to say ops equals options. And what are we going to do down in my greeting, rather than kind of statically saying like, this is the string and I want you to inject these values and I'm going to put some conditional logic in. So I'm going to make a list of strings. And so if you haven't seen the optional function before, the first argument is a boolean. If that boolean is true, the second argument is passed in as a list, or it gets injected into a list and passed back. If it's false, it returns an empty list. So essentially what I'm doing is I'm generating a list. I'm concatenating all these lists together. And if I define, I'm going to say options.name, if it's defined, then pass the string along. And if it's not, concatenate an empty list, which will just be nothing. And then I use this other function called concatStringSep, which takes a larger and then concats a list of strings together for you. So I'm just building up the same kind of string that we saw previously, but now I don't have to define these options, or whichever, you know, these options that are the name, title, and config if I don't want to. So let's take a look at a config. Ah, there we go. So I've just defined a name and title, sorry, name and origin. No title. Eval is the same. Just pulling in options and config and giving back the config output. And the run is going to be the same. So let's just take a look. Doesn't crash. Works. I can go back in here and let's go back to the config. I can take out origin. Not all the way. Just that much. Doesn't crash. Which is exactly what I expected. So if I had done this before in the previous lesson where I didn't have those conditional conditionals in, the module system would have thrown an error at me. Let's actually go take a look. Here's a config. Oh, hold on. Let's go back again. Do I have something open? I do. Okay. Let's just see what happens real quick. Yeah. You'll see this error message. This is the kind of the facto error message that you will see at the bottom here. If you declare an option, you don't define it. So the option origin is used but not defined. A little confusing at first. Essentially what it means is I created an option called origin and I didn't give it a value. Now it's complaining. Yeah, go ahead. Ah. That is a really good question. Let's find out. Let's find out. I'm going to put origin back in. Let's open this options. Let's get rid of... Yeah, let's get rid of origin. Let's not import it. Come on. I probably screwed up something there. Hold on. I did. Thank you. I did delete the end of string. Yeah. Does not exist. So they go hand in hand without any conditional logic. That option has not been declared yet. And it even tells you where you messed up. Which is really nice. It's like you messed up right here in this config file. I guess you guys can't see that. Right there. So make sure that there's... It'll tell you right away. It doesn't take that long to figure out that you messed something up. But those tools are there. Just recognize that the error messages might not necessarily be what you have expected. You've defined something here but you didn't declare it. Or you declared something and you didn't define it. These are kind of the translations. This option origin does not exist. It's not declared. So we've got that. Okay. So far, all of these have just been kind of contained within the next language. Strictly within the module system and just extending on the next language. I try to keep it as much in here as possible so that you're kind of always touching something. Something that's always familiar. Or something that I didn't want to add packages or external things where you have to pick up something new like some API or Nginx or some service that most of you might... Some people might not be familiar with. We're going to take a little step out and we're going to use packages for something. So let's go over to... Let's just make sure I didn't... Okay, nothing's still there. Let's look at extra arguments. We've talked about things that are automatically provided so far which are lib, options, and config. Packages, if you're just writing standard Nix-level modules, not NixOS modules, you don't get packages for free. If you're writing a NixOS module, you do. But I'm writing just something really simple that just puts out strings so I don't get packages for free. So how do I get access to it? Well, first, I'm going to assume that I do get it. I'm going to call it packages. And I'm going to use it. So what I'm doing here is similar to what we did before. I'm going to provide it a name and a greeting this time, just two. The name is going to be my input and greeting is what I'm going to see in the output. And I've configured this kind of silly little thing that uses Cowsay, shoves the name into Cowsay and then spits it out to a text file that we can just cat out and look at later. This is just kind of stuff that I had to do to make sure that I could integrate it all with the lessons site and the build, because this whole site is built with Nix and verifies that everything runs before the site can deploy. So this isn't the way that you would normally write something like this, but I just did it for the sake of having it work for my CI. But the short is name goes in, Cowsay says hello, name. But I need to give it packages somehow. We're not going to find that config. Configure just those names. The way that I'm doing it right now. Let's take a look at eval because the way that packages are provided, you'll soon need access to packages somewhere. You need to pass that in. And since I know previously that when we were looking at our eval files that were just regular Nix files and I was using the run scripts to provide packages to it, I know that I have packages available there. Similarly, this is a little bit different because now we're not going to use Nix eval or we're going to use Nix build for this particular example. I needed a more pure version of Nix packages available. So don't worry too much. This is just a purity thing. Just know that right now, at the top level of my eval file, I have packages. And this is unfortunately not documented too well. I believe the only place that this is actually fully documented is in the source code. The documentation team is working on it. I promise. They're doing a great job. But within config, so within that same config that we were, actually, this is not the top level of the config. This is like the regular module attribute config. There's a kind of sudo underscore, sudo hidden argument called underscore module. Within that, there's another attribute called args. And args, you can pass it arbitrary things that you want to be provided to your module system. So I'm going to say inconfig.module.args inherit packages or packages equal packages. And this is what allows me to pass in anything that I want. So let's say you were building up some library. Let's say you had some really elaborate module that had your own library called mylib and had all these cool functions in there. If you had that available here, I could just say like and mylib, you know. And then I could go over to my my options file and say like, oh, now I have access to mylib. Since I actually have these, I'm going to undo that real quick before this thing breaks. But yeah, you can pass in arbitrary things right through that argument right there. I don't have it in the lesson yet. You can also look in the documentation for something called special args. It is another way to do it because this particular way has some limitations. It is the more recommended way. But if you run into those limitations, special args is there as a backup. Look in, I think it's the Nix manual. No, Nix package is manual or the Nix OS manual for the documentation for special args. But yeah, now we have packages. Well, at least I'm telling you I do. I've tried to apply or make it available. So if I click at my run file real quick, this is just going to be a oops, that is not it, run.shell or build.shell. Sorry, this is a build file. Just runs Nix build on the aval.Nix file. If we try to build it, it might take a little more. Okay. It gives us a result. If we look out here, there's something in result and if I cat that out, it says hello in the code page. And that's it. So yeah, this is how you can give anything you want for the module system that you've tried. Yes. Let me see if I understand. So yeah, when you go to the source code that builds for the derivation for a particular package, usually you see as a function argument, but you don't usually see module options in there. But are those Nix OS options or are they just like function arguments? The module system? No. Ah, right. I think generally for things in Nix packages, you just want to use simple functional arguments. You don't want to use the module system. I don't think I've ever seen something from Nix packages that you just use as a module system. Generally, where you see options is for Nix OS. When you want to configure services, that is not a mistake. I started using what recently? Really? Okay. Okay. So something just said that recently people have started using the module system for packages. Cool? The typing is nice. So this covers the basics. This is just enough to kind of get you started. But let's continue on. I want to talk a little bit more about MkOption. That was that generic option builder that we had. Some of the other things that are available for us. Let's see. I believe this is let's go to default okay. So doing all this is really nice. You saw in some of the previous lessons that we had, we could configure a value for things like reading in the same thing that we had our option declarations, which is really nice. There's also another attribute that is available from MkOption that we can use to set developed values. Just as a thing, they are completely overwritable. But they make your users lives easier if you kind of know what the fault they might like. So here's a really simple module in my options.next file. I have an option called A, which is integer. B, which is integer, and sum, which is integer. And the configuration for sum is A plus B. Simple. But I've added a little default value here for which one is this? For B. And that's it. This uses the priority system. We will talk about that in a bit. But this has this priority possible within the module system. This is the most overwritable thing. Easiest to override. But is available if the user wants to use the default values. So let's take a look at a config. Just a regular config. Let's do that. So in this configuration, I've only set a value for A. So I expect that it will use the default value for B, which is 2. Let's give me a sum of 5. Let's take a look. Run.shell. Perfect. So what do I need to do to override it? Well, there's another configuration file in here called config-override. That's it. Just say B equals 4. B is whatever. B equals 40. There's a run override in here as well to help you out. And there you go. 40 plus 3? 43. These next couple ones are fairly quick by some of the other ones. Go for it. You could totally do that. You have the power to do whatever cursed things you want. Not these. These are all just example files. But I could have defined it in another file. I could have defined it in somewhere. Somewhere it has to be defined. I just set these up as the way that I have defined it to the user. And then what they would have in their config.x file to configure those options. But yeah, like we've seen with like imports. Like we saw, you know, you can split these files up as much as you want. Just how readable do you want them to be? Any other things? That's a pretty simple one. I'm going to quickly talk about some of the other attributes that are involved with documentation. So if we go over, there is option documentation. Directory. Okay, there's a couple other really handy attributes. This, if you ever start, you know, building up a project that uses the module system and you want to like throw it off on a static site with all of your options, like you've seen with like the home manager talk that was earlier. Or, you know, you see on like the search for search.nextwest.org. If you look at the options tab, you can see all the options that are available for NextOS. There's a couple of extra attributes that are held with documentation. So one of them is called description and one of them is called example. So description is like it sounds. You just can write it. Text, sentences, paragraphs. You should just describe what this option does. Please be thorough. Some of, as you might have noticed, some of them are not super well documented. The more information you give to the user, the more they can understand the better. An example is just just another example. This, you know, strings are kind of simple, but like, we'll look at some extra types and like why you might want to put an example and to kind of show the structure of what your option can look like. And all of these, if you look at the outputs for documentation, will be included. So let's take a look real quick. We don't have a config this time. We're not caring about config. Actually, let's see. Is there a config? No. What else is here? There's docs. Yeah. So now we're going to use some new functions. So when, generally, when you're trying to create documentation for all of these options that you've created, you don't need to have a config. Wonderful laziness of Nix that allows you to do things like this. So we're going to probably want to use this function called NixOSOptionsDoc. So this takes an attribute set and one of the attributes for this is options. And here, we're going to pass in the evaluated options options attributes. So this eval options is the same kind of eval options that we've been using before. Normally, we had our config.nix right here next to options.nix, but we don't need to configure it. We're actually fully evaluating these things. We're just going to look at the options output. So we can take the evaluated options. We can look at the options. This line right here is up to you if you want to implement it. The generated documentation includes all of the documentation for that little hidden underscore module thing that we saw earlier when we passed in packages. It doesn't really generally add a lot of value. So for the stuff that I generate when I build documentation for my modules, I remove it and it just cleans up the documentation a whole bunch. If you're using it in really cool ways that it's meaningful to leave it in there, feel free to leave it in there. When you're writing your first module, the function provides a couple of different outputs. It provides an adjacent output. It provides an ASCII doc and it provides a common mark output. Maybe one more, but I think that's it. We're going to look at the common mark output. I'll build it and then we'll build it without that line and we'll see what happens. Let's see. I think I already have it built. Let's build it just in case. Okay, it built really quickly. Let's take a look. Okay, so this is the common mark output. So it's going to look like markdown. But you can see right here at the very top is the name of my option which we also name. The description for it which was a name for a user. The type which was a string type. It's the fault value which in this case was empty. An example which I call Voting with Boatface. I'm going to have this declared by which is actually going to show you basically a link to your system where this option which file was declared in. This is maybe less handy generally for things on your system. Definitely handy when you're looking at NixOS options because it tells you where in the repository it's defined. Or it's declared, I should say. Exactly. It's showing manipulation. For some of this documentation that I've generated I will actually look at the JSON output and create my own common mark output. Which is not terribly hard. You can go look and see how this is generated in the Nix packages repository. And I kind of just took that and massaged it a little bit and made it my own flavor. Another question? Thinking. Do you have documentation in the doc? Can you say that again? Who do you have a doc that's available to build this project? Do you run streams of documentation in the doc directory? Yeah. Is that in the Nix thing? If I'm documenting some other thing and I assert on a file it's used in the doc directory. If the doc builds they can fail the build. That answers your question. When I build this site I take in all these Nix files I evaluate them and I inject them into the Markdown lesson source code and that will build the site. That's how I know that all of these work. Is that answering your question? Okay, great. Let's answer this the other question we had earlier. What happened? Oh, no, sorry. Docs. Options. Equals. Eval. Options. Okay. Build. Let's see what this looks like. Actually, let's look at it in less because it's probably going to be big. There you go. Actually, if you wanted a quick access to the documentation for this, this will give you some of it at least. But, yeah, you can see this is we're still on the way. Oh, wait, here we are. Now we're at our stop but we had to get past all of this so it's already bigger than what we had for a single option. If you had a lot of options, yeah, the percentage goes way down so you don't need to know or care. Unless you get to more advanced things. But if you're already in the advanced stuff, you know that exists and it's always there so you don't really need to document it. We're going to talk a little bit more about documentation and try to help you guys avoid a potential pitfall which you can run into. Not the biggest pitfall but just some funny things happen when we try to use a default value as a package or something that's not like a simple type like a string or an integer or a list. So we've got a new options.next file here. So this one is using packages again, we already know how to pass that in that's great. And we're going to, we're creating a new option called random package. So random package its type isn't string anymore it's from the typing system it's a package type. It's the default value and we're going to use the hello package. The description is a random package and the example is going to be a cal say package. So basically saying just give me a random package, it doesn't really matter. We're not doing anything with this we're only kind of, this is just an exercise to look at what does the documentation look like when we try to build documentation with these values. So the docs file is exactly the same the regular docs.next there's a fixed version of this but we'll look at that in a sec. Let's look at what happens when we build all this. So we build docs.shell and let's look at the results. Okay, so yeah, we've got our title which is random or the heading of this output is random package which was the name of our option. The description was a random package type is package but look at the default and examples, they're variations. That's weird that isn't how we configured it it was package.hello or package.cal say but this is the kind of problem like the string output of a package is this. So how do we fix these kinds of things because we don't want to give this to our user and be like, what does that come from? So, instead of that let's look at this file. Fixed. Oh sorry, not the doc. Options fixed. So there's a couple of functions that are here that are really handy. One of them actually first before we talk about the functions, there's another attribute, default text. So default has to be left alone. The default value of the module system will use. But you use default text for your documentation if you need to do these kinds of things where you need to fix up, like if you're using a package or some other kind of derivation. So in default text what we can do is say put packages.hello in a string and pass it to literal expression. So this will extract the kind of code within the string outside of it and put that in a code block for you within your documentation. Because if you didn't include literal expression it would be a string and we don't want to say package in string quotes. We want to say packages.hello. You need something? What's up? So real quick announcement. So since everything kind of got shifted this morning, the next talk will start at 3.30. Not right now. So you still have time. There's a bunch of people in here for the next talk. You're going to get in. It's fine. We're going to have an hour behind. So I just wanted to call that out. So you still have time to go use the restroom or whatever. Good? Or you can stay. Yeah, you can stay. That's also totally fine. Yeah, you should stay. You can go back to Pierre. I might need him. Okay. So one other function that's really handy but not necessary unless you're writing a lot of writing and it's better to maybe explain an example rather than trying to write out what an example could look like. You can use this other function called literalMD or literal markdown. And you can write markdown inside of your string now. And that'll just be injected as is into your documentation. So you can see here I'm saying like any italicized random boldface package. And it should show up like that. It should just basically just translate directly into the markdown file. Yeah, so let's see. We've got default text for overwriting the default value as some sort of text.value. We've got a loader expression when we want to use things like the packages. And we've also got literalMD for when we just want to write markdown. I believe literalMD is generally used for example and either default.text or like the documentation. I don't remember I think if you put it in the wrong one it might fail. You'll find out. But so we've got another build file that looks at let's see where is it. Yeah, we've buildbox fixed to build these locks but with all these things that we have fixes now. So let's take a look at the result for this. Okay, look at the bottom. We have our default and we have our example and it doesn't say derivation anymore. It says packages.hello exactly what we wanted, exactly what we said. If you assume that they had the package namespace available, like just kind of spot it out, you could just say hello saying like that's a package. But it's kind of nice to say like this comes from packages, something packages.hello and our example is any random package with the markdown of a file is already injected in there. So that I think is all we want to talk about about empty options and documentation. Any questions before we move on? Yeah. This is a totally new one. Oh wait, did I take out the case? Oh, this was just to show that like instead of having like actual expression I can just throw like a description in there. It's not part of the, I could have used literal expression the same I did for the default text. But I just wanted to show you that I didn't want to have like a third example in here. I just wanted to show you. Default text is the fix for showing what the default value looks like in the documentation. But example doesn't get evaluated. It's just for documentation purposes. Moving on. So we're going to quickly talk about some really simple types. Because I want to talk about some modules. I think we have enough time for all that. So if we go to basic types. Just wanted to show you guys some more basic types that we can look at. So we've looked at string. We've looked at integer. We've looked at package. And there's the kind of normal set of types that you would normally expect from a typing system. So we've got Booleans. We've got enumerated values. We've got integers. We've got strings. If we look at just a simple configuration for all that. You can see, like, I have an example Boole is true. Example integer is 42. Example enum is left, which is one of the values in the list that's provided to enum type. By the way, that is how you declare enumerated values as you pass in a list of all the enumerations you want to the enum type. And then we'll handle that for you. An example string is hello. If we run this evaluation for this, we get exactly what we want. Nothing surprising there. Let's go to compose types. These are a little bit more interesting. That's not the right file. Options. More trivial. So we can build things of things. Compose types like we have list of at this very top one. Example list of this type is a list of integers. I can have an attribute set of strings. I can have null or boolean. You can either give it null or boolean value. It's called either. So it can be either string or int. Another really nice one. It's one of. So you give it a list of all the types you want it to be able to be. So it could be either a string and a integer or horrible. Similarly, we can configure these ones. We'll look at the configuration trivial. And if I evaluate this, it's the same thing as before. It evaluates, it verifies. But you can see we have our list of integers. We have our attribute set of strings. This one was the example that could have been null or boolean. For this case, I set it to true. Either it could have been string or integer. And like the text says, I could have been integer. This example one of could have been string, integer or boolean. Either one of those three if we run this friend trivial, we get a bunch of things. You can nest these pretty deeply. Yeah. A list of one of string, integer or boolean. So you're basically creating like, I could have a list that has the first element of a string, the next element of an integer, the next element of a boole. Attributes of null or string. So I can have an attribute set where the values are either null types or string types. Attributes of a list of either integer strings. And then like the last one, I'm not going to go through all that. You can get some really, really crazy stuff and create some really interesting architectures and structures. Look at the configuration for that. And this all works. This all evaluates. If you look at run nested, you get a big big output. Okay. So why do all that? Well, there are other ways to do things like this. And this is where we're going to start talking about submodules. So rather than kind of creating these complicated structures that might be hard to parse, might be hard to debug, might be hard for users to even understand, there's a better way. So let's go over to the submodules lesson. Submodule. Yeah. And this is arguably one of the most powerful types in the whole typing system. Is the ability to create modules that go inside of other modules. So actually, before we look at the options on the next, let's go look at the character dynamics. This will look really familiar. I have an options of name, title, and origin. I have a greeting. And I have a greeting configuration that is conditionally dependent on whether name, title, or origin are present. This is the same thing we saw when we looked at the conditional using the options argument to conditionally set what the greeting would look like. So this is all continuing within this file now. It's called character.nix. And if we go look at options, let's go look at the options file. We're creating a new option in this file called characters. And its type is a list of submodule and a path to characters.nix. So now I can create kind of arbitrarily many characters as I want. And they'll all be contained within this list. The way that you configure sub-options, think of options that are very adder-like. So let's just take a look at the configuration so we can see what this looks like. And we'll keep this up, actually. Yeah, let's config. Right, so here's my character. Remember, it was going to be a list of, and it's a list of submodules. So the things that we have exposed are name, origin, and title. So the first one is going to be podium and foot face. It's origin from England. And then the second one is going to be me. Titles is in Nix Enthusiast from the USA. And now I've, this is kind of what we had a question earlier about imports. This is where you would want to use imports when you're using them for a submodule. Because then it's not the same thing as importing them at the top level anymore. Yeah. And then for the greeting output, basically what I'm going to do is extract the greetings from every single configuration that I have, concatenate them all and string and have a big greeting for everyone that I configure. But yeah, so let's take a look at the run. There we go. We have hello from podium and foot face. We have hello from me. But it's, I don't know if I can stress this enough. This is so absolutely powerful. Because now I can have a character and I can, for each character, let's say you wanted to go like a video game route. Like I could create like a job system or something like that. And job could be its own module. Or the character module. So you could have arbitrary lines of things. But this has a lot more structure. When you generate the documentation for this, it's a lot easier to read. It's a lot easier to parse. So get familiar with some modules. They're really, really handy. This is the big one. So any questions before we move on? Yes. I haven't played with trying to go up a level. Because I know you can go down if you're aware of what's below you. And within character.next, this configuration I have right here, it's nested underneath like my top level options. It's here. But that config is going to refer to like locally myself. I don't know if there's a way to drill up. Unless you like override the fault. Like if you try to like import the character or do something strange. But you are able to like if you look at the options.next, it is aware of what's below it. So if you with attributes it gets like let's see. You can go through some indexing and stuff like that. If you're doing like an adder of characters, it might get a little dicey because you don't know what the end user is going to set the value for the end user. But I guess you could still iterate over the adder values. But yeah. So the option because it's above is it config is aware of some module below. But I don't not sure if character can be aware of it's parent module system. Here do you know anything about it? Okay. Is that good? Anybody else? What's up? Does somebody else have a question? I believe the last thing we're going to talk about when we're running out of time. So this is a good thing. So priorities. So this goes back all the way back to the beginning when we were talking about overriding things. Okay. What did you find? Yes. There are some other functions that we don't have time to cover. There are other ways to do submodules. We did it the most simple way which is using the submodule type. There is another function called submodule width which is what I think you're looking at. It exposes a lot more arguments that you can use to pass more arbitrary arguments to your submodules. That's documented pretty well on the manuals. Check that out if you want to look at other ways. It's really handy. I've used it before and it's super powerful. Yeah. Let's see what we have here. Okay. Okay. So default values plus priorities plus overriding things. Okay. So we looked at before using the default value inside of mkoption. Instead of having it like you can say there's a default value here, we have a default value of default equals something. Deep within the module code, there's a priority system. And anything that's defined here within mkoption as a default has a priority of 1500. The lower the priority the higher the presence or the more preferred it is. So 1500 is basically like anything will override it. There are different functions that we can use to kind of change the priority that we're setting for particular option such as this one. So if you do something within config using lib.mk default, it will have a priority of 1000. So it will automatically override this one because it's 1500. If you don't use mk default and just do it like this sneakily, the module system will give this a priority of 100. So even even and the kind of idea behind that is that like sometimes you need to like create your default values in config and not within the option itself. And so they created kind of a secondary function. So that's why this is 1500 if you use mk default it's 1000. But generally users don't use mk default this is usually when you're creating a module for someone else to use. When you're doing it like this it has even higher precedence over a predefined module. So this is what users would use. If someone else I think someone else had earlier asked like if someone else has done this but then you wanted to override that even further well there is one called mk force and it has a priority of 10 which is I believe the lowest one that's kind of defaultly available. If you want to set up more there is I believe something called mk override. The first argument you pass it is an integer which is going to be its priority. The second one is the content you would provide like the string value here so I could say let's see lib.mk override and then 1 beat that. I don't know if you can go negative with the value I guess you could say like 0 but you can essentially just create any kind of priority level that you want for a particular option. If you're doing this for things you want to expose to the user and you actually want to configure it don't do this. Either use mk default or put it in here. Everything past that like mk force is used or just like not even using any function just configuring it in the config attribute is generally used for the user. Yeah so let's just take a look real quick. We've got our option here. We have a config let's see maybe we don't have a config oh right we just have this one this one's already got a config within it. Okay no big deal let's take a look at the eval file since the one module that we have has both the option and liquefaction definition we don't need anything other than that options file and so then if we run that we're going to get both of my code paste remember that was uh this value right here. So just to kind of push it forward to like really show you that like yes you can overwrite things there are some let's see then it will complain so you can see this one I'm not using mk default this is just configuration value we call this one had a priority of a hundred whereas mk default had a priority of a thousand we expect this one to supersede the previous value so what was that called a boat overridden okay so if we run overwrite we get exactly that there's one more um sorry the way that that was being used there's another eval file called override where it pulls in that option file and the override the last one we're going to look at is uh force I think yeah so force is going to use mk force which we're calling out a priority of ten and then we have another eval file called you know force which uses all three and you can use all three but it's going to pick the one that has the lowest priority yes fifty is is there one that's okay sorry what was the name of the one that has ten make vm override okay sorry so corrections thank you for that um apparently uh mk force has a priority of fifty not ten yes all the way in the back it doesn't or not overriding it's not important at all why design um and then if we look at the run for m force a force there you go um let's take a look at real quick what happens if I uh what happens if I have them at the same level I believe that should just be run let's look at actually a run overwrite I believe there you go so the option name has conflicting definition values and you can actually it nicely gives you a path to each one of those files about overridden and voting my vote base conflict because they have um the same priority and the str type cannot be merged unfortunately we don't have the time to get into merging but if you continue looking at the documentation for this there are types that can be merged attribute sets you can have multiple definitions for I believe certain types of lists I don't know if all lists can be merged it should absolutely say on the NIC packages documentation whether or not it can be merged I think the default list won't come out um it's in the source code sorry sorry what was that okay oh they actually have it because I found it in the source code but I think that's all the things that I had planned is there any more questions before we wrap up and prepare for the next session yes so I know there are everywhere in the NIC packages sure are there any other NIC packages that I mentioned like if you said I'm writing a package that's still in the NIC then I also think you also think it's in the NIC yeah so not just in the NIC but basically anything everything within NICsOS is module configured yeah so actually I do want to point out if we look at where do we want to go seven I want to go eight yeah I do let's go here NICs.dev so this is the official documentation so the question was asked about like more practical things these lessons were created with the idea of keeping you within the NIC system not exposing you to too many other things that might add some complexity but if you go here you should have enough information now to read there's this article called module system deep dive which is one of the maintainers for the module system also lead of the architecture team here they create a set of modules to interact with Google's Maps API they configure some options for like zoom and scale and they show you like it's not like kind of split up they work from like nothing that kind of useless.NICs empty attribute set and build up all the way to a fully fledged module system if you're interested in like kind of a thought process for someone who does a lot of NICs I highly recommend reading this article it is also where I pulled a lot of good information from and it's the outside of the manuals is the only other official documentation on the module system that you should go read up on so that's at NICs.dev module system deep dive anybody else? can you speak up? it's a little hard to hear you main trade off of the module system just writing a package or a function well you don't get type checking you don't get type checking that's one of the major trade offs users can just inject arbitrary things into the arguments of a function if you're having a regular like kind of package that you want to go the other way like why would you want to pick up just a function package versus using the whole module system? simplicity it's a lot quicker and simpler to write up something like that and the real question is do you need all of this? I don't know that would probably be a good question for someone who's committed a lot more to NIC packages I've only made one so are you good? thank you all right the next talk will start in just a couple of minutes so let those speakers get set up in the meantime if you're entering or leaving this room do everybody a favor and close the door very quietly it's very distracting so that's the only real announcement there I would like to bestow upon Daniel Baker a Nick's brick there you go where are the next speakers? right here cool I'll let you guys get set up we have your bricks here hello one more quick announcement so here's how lightning talks are going to work all right everybody quiet down for a second I have a mic but I don't want to yell at you so lightning talks that will happen after this talk so the way that's going to work is if you want to give a lightning talk you can line up against that wall after they're done please don't interrupt them while they're finishing up their workshop but you'll just form a line over here first come first serve I'll give you five minutes to present your lightning talk as five minutes approach I'll be uncomfortably close to you to force you to finish and at five minutes I'm yanking the cord so first come first serve five minutes weird shit anything you want fair game you guys ready to go? hello all right thank you everybody for coming today I'm Ryan Trinkel this is John Erickson we've worked together for a long time in the Nix community Nix really made a huge impact on how we work I started moving stuff to it in 2012 and that was in the context of a company that wanted to provide a really high quality application to some commercial market so obviously one of the most important things about running a high quality application is knowing that it's actually high quality and how do you determine that when you're constantly changing it? well continuous integration is sort of the main and first step for most organizations in that I'm sure probably almost all of you know what continuous integration is but I'll just reiterate it in case basically continuous integration is a system that continuously builds and tests your software as people make changes so that you always know whether what you've got on your main branch is something you can actually push to production and it can enforce all kinds of other rules and sometimes they do automatic deployments and all kinds of other automation but basically you want to know that the work that you've been doing continues to do continues to meet the quality standards within the company and CI is the framework for that now Nix gives us an amazing foundation for this because Nix gives us a very high degree of reproducibility so with a lot of non-Nix based continuous integration systems even if CI says your code is good it might not be good because the thing you put in production might not be the same thing that your CI system tested that's no good and so obviously people have ways that they try to approach this like using Docker containers or really carefully holding on to artifacts that the CI system produces making sure those are the things that get pushed to production there are many ways to do these things but Nix gives you the advantage that the default and kind of only way is already pretty good at any given step now that being said Nix is not really that great to use with traditional continuous integration systems for a couple of reasons let's see I'm going to skip ahead to this one the two big reasons basically being that these Nix is based around sandboxing everything an absolute total chain of custody for everything that your software depends on which often is a lot of stuff so when we build at our company we do a lot of Haskell work and the Haskell compiler tool chain is like a few gigabytes and so when you try to go build stuff in a traditional CI well it needs to fetch all that stuff and every CI system tends to have its own caching stuff they all tend to be not as principled as Nix and not interoperate with Nix super well so people who use Nix the long and short of it is we tend to use Nix oriented continuous integration solutions I'm going to go back and talk a little bit about the benefits of CI I already mentioned testing but the other big one with Nix is that Nix in addition to doing reproducibility and all the sort of robustness things that we like it also has this awesome caching capability which you know whereas outside the Nix community you might pull Docker images with Docker compose or whatever but then as soon as you make a tiny change the whole thing has to rebuild from scratch with Nix you can have very fine grain binary caching and so if you have a bunch of different people on your team they're using a bunch of stuff you can pull from binary caches and everybody's development environment can be set up very very quickly I mean when I converted my two companies ago from like Ubuntu and just traditional stuff to using Nix we went from having usually a few days to a week for a new developer to set up their laptop to 10 minutes however long it takes to download basically so that's another huge advantage and that's another place where the traditional CIs even if they have their own internal caching that cache is not usually exposed to developers to be able to pull it directly onto their laptops so we want to have Nix solutions to take full advantage of Nix and also to deal with the sort of different performance profile that Nix has from traditional builds and so we have a few different tools in the marketplace here I've only covered the ones here that are well known and publicly available for some time and sort of tried and true there are a whole bunch more there you know if you go look on the course you're going to find more it's a great open source community lots of people do this kind of stuff but so Hydra is probably the best known CI solution in the Nix space that's the one that builds Nix packages so anytime you're seeing whether you know a given version of something is building on Nix packages or whatever you might find yourself on hydra.nixos.org and that is that and this is an open source project you can use yourself in my experience people find it kind of difficult to run difficult to keep running it tends to be I mean it has every feature pretty much that you could imagine but it's kind of a beast to work with Hercules is probably the best known most mature managed CI service for Nix so Hercules will manage the actual interfacing with your GitHub project it will manage assigning jobs out and it will give you a user interface for all of this with Hercules you do run the actual builds on your own hardware which is nice it also is a thing that you need to set up Garnix is a little bit less at least it's a little younger I guess I don't really want to comment on exactly how mature each of these solutions is since they are competitors with each other but I think that Garnix is a newer competitor and they host the runners for you as well so they'll manage not only the build but also getting the machines ready to actually build the software and then we have some more specialized tools so there's Cachex which is just for caching and it also has some deployment features but it's focused on caching as the name implies and then you've got NixBuild.net which is effectively like a remote builder as a service as far as I know they don't do anything with the actual CI sort of traditional loop but they'll give you as much compute as you need on demand so that's the basic lay of the land here of course there are other tools and I'm not discouraging you from using any of those but these are the ones that seem to me to make sense to say like this is the normal stuff in the ecosystem so when you're setting up CI for yourself you're going to need to try to decide a few different things for example which of those tools do you want to use if any of course you can always roll your own as well you're also going to need to know which provider you're on not every CI tool supports every Git forge so you actually would potentially want to consider moving your repo to one that is better supported by the CI tool but not if you've got a lot of issues and everything going on so anyway that's one thing to take into account when you're picking a provider then the Flake support is pretty good nowadays but there is usually a different way to do things for the Flakes or non Flakes way so release.nix is the main way traditionally before Flakes came around and now there's a lot of support for Flakes in all these different tools but this is another decision that you want to make fairly early on when you're doing your CI deployment you know probably Flakes is the more modern way to do things and so then yeah you're going to want to choose one of each of these tools to make sure that you've got something that lines it up so that's basically all the talking I'm going to be doing here I do want to ask how many people in this room already are running some sort of CI integration that they manage on a repo of theirs okay great so that looks like about 40% of the people in the room so great you all just volunteered so how many people have a project that needs CI but doesn't currently have it I think probably there are a few people who put their hands up and didn't but anyway all of you are the ones who we're really here to help today so we want to make sure that by the time everybody leaves here everything they've got is being CI'd at the very least everything should be getting built ideally you have a workflow that includes you know green check marks and red X's for all of your pull requests and merge requests and things like that and hopefully you are populating a cache and if you are working with other people on a team you've given them instructions for setting up the cache so that when you push some massive change in your merge request they don't have to take 4 hours to build it before they can test it similarly you know with continuous deployment that's something you might want to consider even if you've got CI set up maybe you don't have CD set up that's something that we can also help with basically I want to encourage people to ask as many questions as possible we're going to have people wandering around everybody who knows me here better be doing that and so yeah we're just going to try to help out answer questions if there are questions that seem like very generally relevant I might turn on the mic and announce them or something but I think for the most part it's going to be about like how do we get through each person's individual issues with their repo because there are various situations you can run into where the CI won't work as well as it might otherwise and hopefully everybody leaves with something that's working and running so before we break into that are there any questions there? yeah I would say all of these do a considerably better job with that than just like typical like for example if you go on github or gitlab and you just use one of their standard runners and say nix build this thing then yeah almost all of your CI time is going to be dominated by downloading dependencies every single time and then you can get kind of fancy and try to like shove that stuff into their cache and pull it out it's sort of a mess these tools because they're nix focused from the beginning trying to do that better and typically they will have if you're running on a cluster ultimately things will need to be downloaded and moved around sometimes but like these tools are going to get it pretty nice from the get go you're not going to have nearly the amount of downloading and uploading time for example with Hercules most of the users of Hercules are going to have one or several large builder machines and those machines are just always going to have most of the stuff in their local cache so that works super nicely I think Garnix has something sort of internal to their cloud that does a similar thing I don't know the details of how Hydra works but I mean it works at the scale of all of nix packages built multiple times a day so it's getting that right too so yeah and that is one of the big big reasons that it's better to use a nix-specific CI than to just use a typical average mainstream CI so in terms of convincing people usually people who are operating CI systems which often falls under the DevOps category care a lot about speed so I've heard one of my clients for example they have a KPI for are the CI CD builds under five minutes so that's something that's got management visibility for them so I think that just bringing those speeds down because really with a nix-focused tool you can beat the pants off the speed of traditional CI tools you can get down to the point where it's like well very little changed so all I'm actually doing is evaluating the nix expression seconds or tens of seconds as opposed to traditional CI even if it's got caching it's usually going to relink it's going to at least do something bigger than that and then in terms of the actual operation of transitioning I think it depends a lot on how the existing CI system is set up but for example on GitLab so GitLab allows you to specify a directed cyclic graph of jobs in their GitLab CI.yaml file and what you could effectively try to do in that is you could say well my nix-specific CI is going to be one of the nodes in that graph and then I'm going to make everything that might want to pull from that cache be a dependency sorry be a dependent on that node and then you can make sure that everything's in the cache before you know maybe some third party tool wants to I don't know run a virus checker or something right and so then it can always deterministically pull from the nix cache because it's afterwards in the CI pipeline go ahead for the most part yes although I think that there's a pattern that I've come across in the nix community that can be very nice which is to have a derivation that builds a script to do something so for example at our company we produce iOS apps a lot of the time and that can't be done the final signing step can't be done inside of the nix sandbox and so we just return a bash script and then I think the bash script invokes nix again so it's sort of like a continuation passing style of the idea bash scripts for the things that can't be sandboxed and pure so that's the kind of thing you can do so you could produce an artifact from the nix CI tool that then becomes it embodies a lot of the logic of some other step that needs to happen even though that's an impure step and Hercules for example has a way of specifying impure steps to do after your build successfully completes in the nix language so you can kind of do what I was just describing you can produce a script and you can say you know whenever the master or main branch you know successfully finishes building then run this script which maybe is a deployment script or something like that it tends to be very specific to your CI system how you do anything like that but I think it's great to integrate it with nix I think that nix doesn't have a lot to say about the very final impure step but it can produce that step for you and that can be a really useful way to do it go ahead well I think I've seen a lot of projects that involve integrating nix with basal and or buck I think that can be a little bit awkward obviously those systems do have advantages in some areas and I think also disadvantages in other areas I think the key with nix to structuring those kinds of like code quality tests and other kinds of tests is to leverage the fact that it's a directed acyclic graph try to get as much parallelism as you can there's no reason you can't invoke a basal build inside of nix or invoke some other tool and there's no rule that the output of your nix expression needs to be a package so for example you could I don't want to get too specific about particular tools but let's say you had a code coverage tool that produces some sort of report at the end so you could write a very small nix expression that says hey take my source directory take the tool on the source directory and then just whatever its output report file is copy that to dollar out and that's my output and so now you've got this artifact produced by the nix system that has that report or you could even go a step further and say well the report had better be all good otherwise I fail as a build so I think if you look at Haskell.nix which is the next generation proposed Haskell infrastructure for nix it takes every Haskell package and splits it into a library component a test component various other benchmark components things like that and each of those is a separate nix derivation which means that if you have a library that depends on another library it can start building before the tests finish running for the first one so I think that's a very valuable technique as well like just because something like is one package doesn't mean it needs to translate into one nix derivation it can be a dag of nix derivations that come together at the end and then you can leverage a bunch of parallelism in the nix build as well as avoiding rerunning things that haven't changed yeah just a small addendum there nix packages Hydra is going to take a while before it even starts to evaluate we haven't really thought about latency so much but I think some of the idea with the AI use case is if we are going to run something every commit or every PR we do care about these issues and we're going to care about them more than we traditionally have and the good news is just as Ryan says nix is ultimately just a graph of jobs there's no rules about how fine-grained or coarse-grained those jobs have to be and so just naturally in trying to tune our CI to be faster and faster we're going to end up having more and more fine-grained steps and push the CI system harder and harder and like Ryan said earlier yes that will take some engineering to make sure the intermediate artifacts are efficiently moving between the runners and whatnot and the place where nix really is competing head-to-head with the bucks and basils in the world much more than it is today so I guess I would just invite everyone to have faith that we can if we care about this use case we can start using nix in ways we haven't really as a community done yet and the technology will rise to meet the challenge yeah definitely is that ATTIC? okay cool so yeah I guess that should go on the list of things people should consider here any other questions? alright go ahead yeah I think well actually in terms of free open source options I would throw that one back to the crowd I know Hercules and Garnix both support flakes and do you know I think I know that Hercules has a capability to do something like that I think it's 29 bucks a month so outside you know for a hobby project that's probably a bit much for an enterprise it's probably not such a big deal but yeah it would be certainly nice if Hydro had that capability as well and maybe someone will contribute that functionality go ahead right okay that makes sense yeah did I see another question okay well then let's get into it to make sure that everybody who is interested in getting their CI rolling right now has the chance to do so and has the support if you are doing that and you have a question please raise your hand that anytime we'll be looking for hands up and yeah ask questions early ask them off and don't worry about anything being dumb and the second set of eyes always helps with that kind of thing so yeah let's get to it and anybody in the audience who's willing to help please help the people around you or just start walking around and looking for hands thanks test test I can help someone someone raise their hand who needs help hello hello we've got the whole Garnix team here by the way guys if you're interested in setting that up please there we go yeah we'll be over there and if anyone has questions or wants help we'll be over there alright folks the time has come it's time for lightning talks just flashbang myself with the projector okay if you want to give a lightning talk if you're not at all first come first serve let's do it hello hi I think that's very loud yeah okay sorry so we're Garnix I'm Julian this is Alex and that's Junke so we thought we'd give a talk immediately after the previous workshop because we're Garnix and we thought that we could show you how hosting is a new thing CI caching and hosting works with Garnix from signing up to having your checks on github and on the website to caching to deployments which are a new future sorry and the premise here is these lightning talks are supposed to be five minutes long so I'm going to be measuring the time myself and we're going to try to do this in five minutes so from not having an account to having servers running, NixOS servers running in the five minutes cool so we're going to start by signing up here Garnix currently uses github for authentication so Junke is going to sign up through github and then we finish sign up agreed to those terms of service and then the next step is to enable Garnix on repo so going to choose the repo that we want to build and we prepared repo with some small Haskell project ahead of time we're going to set that up and as you can see there's no build yet and that's just because we haven't pushed any commits since setting up the repo so as it is now going to push a commit to this repo that we just set up and the first thing Garnix is going to do is evaluate your flake Nix that it finds Garnix specific in this repo there's just a flake file in the root that has some packages, some NixOS configurations and some checks in it and Garnix is just going to immediately start evaluating this and you can see our check has failed here so if you go in here there's an issue there it goes and you can see that this was a check to make sure that there was no 2 to 2s in the codebase and it failed because of that all these checks are also visible on github so you can go there and see them all there Garnix is reading through your flake file and you can see that there's 2 NixOS configurations it's building those it also sees that there's a check it builds that the check is just a regular flake check so you can run this locally with the standard Nix tools Nix flake check which solves the problem that you have in other systems where reproducing SCI failure or whatever locally is quite hard this is just Nix so if we look at what it says here the check is just checking that there's no 2 to 2s in the source code and it failed because there is in fact a to do so we're going to fix that and that's the to do I don't know if you can see it but the to do says say hello to Nixcon this is a small Haskell server so we're going to change that to say hello to Nixcon fix that and we're going to do one more thing we're going to add a Garnix.yaml which is the first Garnix specific thing on this repository and that Garnix.yaml is going to have I don't know if you can see this but it specifies what server is to deploy so this is something new everything that we've shown so far is available you can sign up it doesn't cost anything you can sign up right now and use it this is still behind an alpha wait list if you want to use this sign up for the wait list and this is going to deploy your servers to Garnix's own infrastructure so if we push this we have now presumably a second entry in the builds this is the second commit that we've pushed and we have to wait a little while and we see the same things as before because the deployment is going to come in as a new check after everything else is done so if we wait a few seconds hopefully you still have a few seconds if we wait a few seconds we'll see these things finish by the way all of this is cached so Ryan and John talked about caching and all of these things so we have a local cache so we make sure that between builds everything is much faster and we see that everything's succeeded the cache you can use it as a remote cache so you can download it locally as well so you don't have to build everything and now we see the two deployments at the end of that we're going to have the two servers the back end and the front end talking to one another and every commit the update with zero downtime this will take a few more minutes before it's deployed but once it's deployed the server will be running and we'll say hello Nixcon when you do a curl thank you well done for five minutes next person up if you've got a demo get in that line the line's looking pretty short come on hey Tom do a Nix Rebel demo do a Nix Rebel demo get in line to do it so these tokens too if I use one of these tokens can I get on the Garnix waitlist a little bump okay so I'm going to go through a project I've been working on for the past two months it's basically what I'm trying to do is make verse hell for Nix I'm not going to go through the entire thing like the Garnix people just did but I'll just give a brief overview of what it's trying to do and what you can do with it today so I've got to find my mouse so I'm just going to go over deploying a Nixflake on Flakery and connecting to Tailscale so what you can do is you create a Tailscale service using this Flake template and add your service to your configuration with an auth file key and can I zoom in? I don't know let's see there we go now I'm going to find the mouse again here you go so yeah it's not too crazy and then I already have one here so you would take this copy it head over to Flakery.dev and then this would say sign in with github if I wasn't already signed in you would sign in you can paste it here and hit create but I already have one created with the right syntax you have to make sure you use a valid Flake URL and then when you have that where is that link right there what you can do is then add your auth key which I would show you it but I don't want to give that to everybody here but you can add a file to this template here with your Tailscale auth key and then go ahead and create a deployment and what this will do is provision you a VM and apply that Flake to the VM with this secret file there and then after you wait a few minutes you should be able to see it in your Tailscale and then connect to it via SSH so it's basically it's like if you have a Nix Flake that configures a NixOS module you just put it into this put it into this form hit go and then you'll get a VM with that configured and one day it's going to have auto scaling and load balancers and lots of cool stuff but I'd really love you guys to check it out try it out and if you want you can join and give me feedback that's all I got question it's open source it's scattered but I'm going to get it all in one place so yeah alright thank you very much let the next one get set up if we don't get more people in line I'm just going to make Tom do more stuff I know no I'm pretty sure Tom would love to give plenty of demos yes after Nix REPL we can do a Nix output monitor we can do a one liner with parallel to do some crazy stuff you ready? cool hey there this is a very humble demo I haven't built anything but I thought about sharing this which happened last week is sort of like motivational for newcomers and just general Nix appreciation so last week I picked up this ticket our Kafka client would stop processing messages and never recover and I couldn't rep locally and basically it would freeze with this log message that the application MaxBall Interval was exceeded and not being able to rep or I tried to trace this message and I managed to find it inside the already Kafka source code and my naive approach to this was well can I print debug my way to understanding what is happening here like why does the prod consumer hit this line of code but mine doesn't does this function ever get called do we always reach this return here and my first problem is this is my dependency chain I have my application I have the company's wrapper for the Kafka library I have the Haskell Kafka library and then I have already Kafka the C library that HW Kafka client uses how can I swap already Kafka for my local version without Nix I have no idea how to do this with Nix I know there's a chain of derivations that takes me from my application to already Kafka and then what I do is I just go to search.nixsoas.org and you hear me now awesome alright so I click source and I find the definition of HW Kafka client here and inside the library system depends I find already Kafka and then I go to search.nixsoas.org I go to the source for already Kafka and I see it's fetched the source is fetched from GitHub and I think hmm can I just point that source to directly I know make derivation can be can be changed with override errors so I do that pointed to a local check out of already Kafka but how do I make HW Kafka client use it though can I use an overlay can I make my Nix packages already Kafka use this overridden already Kafka which points to my local check out I don't know why I thought overlays allowed me to replace packages but well it's not using my local version with my print debugs but I have other tools can I override adders on the HW Kafka client well I try it it doesn't error out it still doesn't work it's not bringing my debugs Google Google I find a slides from Nixcon 2015 talking about override cabal I use override cabal library system depends points to my already Kafka and it works my takeaway I would have no idea how to do this without NixOS like how to replace a C library deep in my dependency chain without Nix who knows maybe doing this without Nix is easy perhaps even easier but it's not discoverable with Nix the dependency chain is all declared and readable and I can poke at it so in a sense for the average programmer like me Nix is a little bit like a super power here's to hoping that this battery doesn't die I just hold it so hello everyone I'm Nix how and I just decided to do this lighting talk maybe five minutes ago since I feel like a lot have been covered not for the upper levels of Nix but few have been covered on lower levels of Nix so like how does Nix actually works under the hood a lot of content in my talk can be found on that Nix Pills webpage but I feel it's just easier for me to talk about it so first of all we know about view systems like NUMAKE so what is it NUMAKE you just write a make file and you say that on the left side is the output so our output is main.l on the right side is all the input file so main.cdev.h below that it's the command to run to generate the output from that input so that's a view system if we check one of these view rules we can see that it can be separated into three parts as I've just described so it's the target it's the prerequisites so the prerequisites so the dependencies or inputs are referenced in the recipe and so they should be considered part of that recipe so what I mean is that so you do cc compile utl.c utl.c is both an input and part of that recipe and target is the consequence of the recipe so like whatever recipe whatever command you just run you produce the identical output given your input and the command you're using so the output is actually a function of that recipe think of like among math functions sine and an input 2 you know sine 2 that's the output or wherever you run that function it always gives the same output so we know that a rule in glue make file is the smallest minimal unit of build so we name the minimal unit of build as a derivation as in nix so the codes below are just a rough approximation of how nix really works don't try them they won't work so given that makefile line utl.o is built from utl.c and divs.h and how to build that we use cc utl.c so that's a derivation and the builder is just that command we use to build the output so how do we name that output first of all we evaluate the derivation so we drop all the syntax triggers of nix gets the final output is just like json a flat output and we normalize it so like non-code json kind of thing but in nix it's called derivation and we hash that output so we get a shahash and we use this to name that output so to ensure the reproducibility of nix derivations we also have to track all the inputs so like in the previous command we use cc as the compiler we use utl.c as the input so we have to track these inputs as separate derivations this is a very natural design so we can just do cc is some derivation utl.c is from some derivation and our resulting derivation is a deck composed of these input derivations you can see that there's generally no impurity from this invocation everything is just encapsulated in derivations and this can be normalized or evaluated to this so you can see every derivation pass is replaced by the hash let's ignore this part