![A snowflake through a magnifying glass](https://collab.thilohohlt.com/uploads/da9422e6-547d-4f63-b491-2fbc4682d00f.png) # Getting started with the Nix ecosystem ## Table of contents [TOC] ## What is this article about? When I first started to learn how to use NixOS, the Nix package manager, and how to work with the Nix language, I was overwhelmed. While it did not take me too long to (sort of) get into it, it was not the most pleasant experience. I would say that there is not really a single source of truth, like Arch Linux users have with the [ArchWiki](https://wiki.archlinux.org/), where you can basically look up everything. Instead, the information is spread across many different sources, which can make it difficult for beginners to find out how to do what they want to do. The "modern nix CLI", also known as "nix3 cli", is another thing that can cause confusion when you are just starting your nix journey. There are some commands that look almost exactly the same, such as `nix shell` compared to `nix-shell` or `nix-build` compared to `nix build`. Do not worry if this sounds strange to you, we will come to you and make it understandable. With this article, or whatever you want to call it, I want to help people who are new to the ecosystem and have trouble finding their way around, but there may also be some more experienced people who can learn something here. With that said, I hope you enjoy the read! ## Resources Before we get into the more technical stuff, let me show you the main resources where you can get information and/or ask for help if you get stuck. For each item, there is a link to the source, followed by a description of what it is used for. ### Official manuals The manuals are great. You can find a lot of information in them, they are well written and reliable. - **[Nix Manual](https://nixos.org/manual/nix/stable/)** Here you will find all things related to the nix package manager, i.e. the many different commands available to you (e.g. `nix build`). This manual gives you examples for most of the commands, and lists all the arguments available for them, with compact explanations. - **[Nixpkgs Manual](https://nixos.org/manual/nixpkgs/stable)** You will spend a lot of time here if you are a developer and want to package software. Nixpkgs is a GitHub repository that contains all the software packages available for the Nix package manager. An example package that many people might use is Visual Studio Code, and in order to make this available for you to easily download via Nix, someone first needs to write some code in a `.nix` file that basically describes where to get this application, who maintains it (keeps it up to date), how it is licensed, what operating systems it has been tested on, and much more. - **[NixOS Manual](https://nixos.org/manual/nixos/stable)** For the most comfortable experience with Nix, most people choose to use NixOS, a Linux distribution based on the Nix package manager. While this is not a requirement, and you can run Nix standalone on other Linux distributions or other operating systems, it can make things a lot easier. ### Forums / chat rooms Sometimes you just cannot figure things out on your own from all the different sources of information out there. Luckily, there are several platforms where you can chat with experienced users who can help you quickly. - **[Official Forum (Discourse)](https://discourse.nixos.org/)** The forum can be used for many things. If you have a more complex question, you can go to the *Help* category and post it there. Then there is the *Announcements* category, where you can find Nix-related projects created by members of the community, as well as other exciting news. Finally, the *Guides* and *Links* categories can be used to post tutorials, guides, blogs and more. I highly recommend checking out the announcements, guides and links sections to keep up to date, as the Nix community is huge and there is a lot of work being done every day to expand the ecosystem. - **[Matrix space](https://discourse.nixos.org/)** If you have a quick and simple question, this is probably the best place to ask it. Often you can get an answer in a few minutes, and if you are confused, you can easily have a longer conversation to solve your problem. - **[Unofficial Discord Server](https://discord.gg/hwJC22bfZh)** This is the same as the Matrix room. However, there are different active people chatting here, so if no one could help you on Matrix, they might know better here. Or vice versa. ### Other Here are some other helpful websites that will make your life a lot easier. - **[NixOS package search](https://search.nixos.org/)** A simple GUI to search for packages in the nixpkgs repository. Say you want to download the Firefox browser: You would go to this url and then search for `firefox` to see if it is available for download with Nix. It will also show you results that include your search string (similar results), for example `firefox-devedition`; if you wanted the Firefox Developer Edition. - **[NixOS Option Search](https://search.nixos.org/)** A simple GUI to search for system-level module configuration options in the nixpkgs repository. You probably want a desktop environment to easily navigate your system. Good news - Nix has you covered. If you search for `desktopManager`, you will find that `xfce`, `gnome`, `plasma5` and more are available. Now you can just copy the desired lines into your configuration and you have a complete desktop environment in a few minutes! - **[HomeManager option search](https://mipmip.github.io/home-manager-option-search/)** This GUI is very similar to the NixOS option search, with the difference that it is used to search only HomeManager configuration options. HomeManager has become a popular tool in the Nix community, and I would recommend taking a look at what it is. I found this blog post about [Why and How to Add Home Manager to NixOS](https://drakerossman.com/blog/how-to-add-home-manager-to-nixos) which you might want to take a look at. - **[nix.dev](https://nix.dev)** Here you will find many helpful tutorials on how to work effectively with Nix. It is an official resource and you can learn a lot from it. I highly recommend it. - **[Unofficial flakes book](https://nixos-and-flakes.thiscute.world/)** Since the new CLI and flakes are still marked as experimental, there is no documentation about them in the manuals or in the official nix.dev tutorial series. For this reason, someone has come up with an unofficial book where you can find simple tutorials on the newer features. - **[GitHub advanced search](https://github.com/search/advanced)** This search can be really useful sometimes. It is not always easy to put your configuration together just by looking at the configuration options, and there is not always a blog post that shows you exactly what options you need to configure an application or service properly. With this search, you could, for example, search for `services.nginx` with `language` set to `Nix`, and you would see example configurations from thousands of other people who have already figured it out. All you have to do is copy them. This is also useful for packaging if you cannot find the information you need in the Nixpkgs manual. ## The new way versus the old way Now that we have covered the primary sources of information, we can delve into the technical aspects by first looking at the "old way" of doing things, then the "new way" and finally comparing them. ### The old way There are two key words we can use to summarise this section: - Nix Channels - Original Nix CLI Let us take a closer look at each of these concepts. #### Channels While you could install the packages you want directly from the nixpkgs master branch on GitHub, this is not the best idea. Instead, you can rely on commits that have been thoroughly tested, so you will not experience breakages on a regular basis. There are many different channels, and in the nixpkgs repo they are represented as branches. Instead of listing them here, you can take a look at [Zero to Nix example channels](https://zero-to-nix.com/concepts/channels#examples-of-channels) for a nice little table listing the ones you will see most often. #### Original CLI Contains the already stabilised commands for Nix. You can find them all in the [Nix manual main commands](https://nixos.org/manual/nix/stable/command-ref/main-commands) section. This CLI works together with channels, as they are the common way to provide `<nixpkgs>` for these commands. ### The new way As with the previous section, this one can be summarised in two key words: - Flakes - New CLI, also known as the "unified" or "Nix3" CLI Both of these features are still experimental, which means they are not yet marked as stable. However, more than half of the user base already relies on them. #### Flakes You can think of flakes as a way to manage *channels* in code and with native support for git. A `flake.nix` file contains an attribute set with two attributes: - `inputs` - `outputs` The `inputs` attribute is used to specify other flakes you want to use. Popular examples are `nixpkgs` and `home-manager`. To get these dependencies, we specify the url and assign a *flake reference* to the project code containing its `flake.nix` file. Next is the `outputs` attribute, which is just a function. Nix fetches the inputs, then loads your `flake.nix` file, and finally calls your `outputs` function with the other flake `outputs` as arguments. To lock versions of dependencies, a file called `flake.lock` (same concept as `package-lock.json` or `cargo.lock`) is used. It keeps track of which revision was fetched from the URL you specify in the `inputs` attribute. `flake.nix`: ```nix= { inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; }; outputs = {nixpkgs, ...}: let system = "x86_64-linux"; pkgs = nixpkgs.legacyPackages.${system}; in { devShells.${system}.default = pkgs.mkShell { packages = with pkgs; [ nodejs_20 tree ]; }; }; } ``` `flake.lock`: ```nix= { "nodes": { "nixpkgs": { "locked": { "lastModified": 1695806987, "narHash": "sha256-fX5kGs66NZIxCMcpAGIpxuftajHL8Hil1vjHmjjl118=", "owner": "NixOS", "repo": "nixpkgs", "rev": "f3dab3509afca932f3f4fd0908957709bb1c1f57", "type": "github" }, "original": { "owner": "NixOS", "ref": "nixpkgs-unstable", "repo": "nixpkgs", "type": "github" } }, "root": { "inputs": { "nixpkgs": "nixpkgs" } } }, "root": "root", "version": 7 } ``` #### New CLI Contains experimental commands for Nix. You can find them all in the [Nix manual experimental commands](https://nixos.org/manual/nix/stable/command-ref/experimental-commands) section. This CLI adds support for *flakes*, the topic we discussed in the previous section. A nice little example of the new CLI in combination with flakes is a remote development environment. For this we can use the flake from the previous section, which gives us temporary access to the `nodejs_20` and `tree` packages. I have pushed the [example flake code](https://github.com/thiloho/example-nix-flake) to a GitHub repository so that we can use it remotely. All you need is the Nix package manager installed on your system. Now, we can use the `nix develop` command and pass it a flake reference pointing to the repository containing the `flake.nix` file: ```nix nix develop "github:thiloho/example-nix-flake" ``` And that is it, now we are in our development environment! ### Comparing old and new Although flakes are still marked as experimental, and there is still a lot of work to be done before they can be considered stable, I would recommend them to users new to the ecosystem. Here are some of the reasons why: - **Reproducibility** Flakes pin dependencies to exact revisions, which means they always use the same versions of other packages or modules they depend on. This makes your project more reliable and easier to share. - **Composability** Flakes allow multiple projects to be easily combined. Each flake provides a standardised interface to Nix artifacts such as packages or NixOS modules, which can easily be used by other flakes. - **Improved dependency management** Flakes make dependency management easier and more intuitive. ## Getting up and running I hope that what we have covered so far in this article has cleared up most of your confusion. With that out of the way, you can take a look at this roadmap I have created to build your own personalised NixOS system: 1. Install the [NixOS ISO image](https://nixos.org/download#nixos-iso). To make things easier, choose one of the graphical ones, not the minimal one. 2. Use [Ventoy](https://www.ventoy.net/en/index.html) to create a bootable USB drive, then put your downloaded ISO image on the USB drive. 3. Boot from the USB drive, select the NixOS ISO and follow the installation steps. As a file system, ext4 is good and easy, and you can create a swap partition the size of a quarter of your memory (e.g. *32GB* RAM = *8GB* swap). 4. Navigate to your home directory using the `cd` command. 5. Follow the instructions in the `README.md` of my [nixos-flake-config-template GitHub repository](https://github.com/thiloho/nixos-flake-config-template). ## Conclusion I hope this article has been useful and that you have enjoyed reading it. It takes a long time to get really comfortable with Nix, but it is an incredibly powerful tool and you can do a lot of cool things with it. After using it for a year, I would definitely say it was worth the effort!