Skip to content

The flake guide #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft

The flake guide #8

wants to merge 4 commits into from

Conversation

DamitusThyYeetus123
Copy link
Collaborator

Self explanatory, but also painful

DamitusThyYeetus123 and others added 3 commits January 2, 2025 17:10
Added some extra details, capitalized "Nix," and added a neat lil' metaphor for inputs and outputs
title: Flakes
---

Flakes are one of the most complex and confusing concepts in Nix, especially for beginners. Even though, as dependency lock files, flakes aren't anything new, their use in the context of NixOS, an operating system, adds an unsurprising amount of complexity.
Copy link

@NotAShelf NotAShelf Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not necessarily true, nor is it elaborated on.

Flakes have been a difficult concept for as long as they have been around, but their use for NixOS configurations (for, not in) does not add any added complexity. nixosConfigurations is a part of the schema, and flakes almost exclusively consume other items from the the schema, even when they are used outside the context of NixOS.


## What are flakes?

Flakes are an experimental feature of nix that adds two new important files, the `flake.nix` and `flake.lock`. While experimental, they are widely used among the Nix community. Flakes allow you to extend your Nix projects, including development shells, NixOS systems, home-manager installations, and more, with Nix code from other projects and repositories.
Copy link

@NotAShelf NotAShelf Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flakes do not "extend" anything. This is akin to claiming a PKGBUILD extends your project. Nor are they only for Nix projects.

Clarify wording.


Flakes are split into two major parts, the inputs and outputs.

The inputs include a list of all code included in the project. This commonly includes nixpkgs and, on NixOS, home-manager. But it can also include any git repository which has a flake.nix file.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can also include any git repository which does not have a flake.nix. This is confusing wording.


The inputs include a list of all code included in the project. This commonly includes nixpkgs and, on NixOS, home-manager. But it can also include any git repository which has a flake.nix file.

The outputs point to everything which is created by the Nix project. This can include dev shells, applications,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are any of those? Clarify, or link to appropriate pages.


## Why use flakes?

The primary benefit flakes give is making Nix truly declarative. Without flakes, there is no way to include specific versions of git repos like nixpkgs in a Nix project. This can cause issues when sharing a project with others, as users could be using different versions of nixpkgs, causing bugs and conflicts. Flakes solve this with the flake.lock file. This file is automatically generated and pins all inputs to a specific git commit. This ensures that everyone using the Nix project is running the same version of nixpkgs and any other inputs. This setup, again, is nothing new. A flake is just a dependency lock file, which are commonly found in other programming languages, especially Node.JS, which uses a package.json and package.lock file.
Copy link

@NotAShelf NotAShelf Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

False. The primary benefit is purity. Flakes (and by extension nix3) force pure evaluation of code. NixOS is a declarative distribution even without flakes.

Without flakes, there is no way to include specific versions of git repos like nixpkgs in a Nix project.

Also false. fetchTarball as a function allows specific revisions with hashes.

Copy link
Collaborator

@deviantsemicolon deviantsemicolon Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well this is a guide for noobs who have no idea what any of that means, so I don't think we can just say "it makes the system pure." So we should reword that.

As for the second thing, I'd recommend changing it to say that pinning specific versions of git repos becomes more challenging without flakes

Also, I think "declarative" was supposed to be "reproducable" @DamitusThyYeetus123

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait I can edit Raf's comment? 😭

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also provide a description of purity here, or link to a separate page that talks about it. Inexperience is not an excuse for ignorance, nor is an excuse for us to leave it out.

}
```

The default flake template includes a description, a list of inputs including nixpkgs, and a set of packages as outputs. There are many different possible types of outputs, which are all used by different nix commands and projects. In this instance, the `packages.x86_64-linux.default` output is used by the `nix build .` command, which builds the package and adds it to the nix store. The most common output type, and the most important one for this guide, is `nixosConfiguration."<hostname>"`. This outputs a NixOS configuration which is used by `nixos-rebuild switch`. Here is an example of a basic flake for a NixOS configuration:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cite or provide examples for other outputs.

}
```

This file includes a few new parts. First, the `{ self, nixpkgs }` has been changed to `{ self, nixpkgs, ... } @ inputs`. This allows for the flake to recognise any inputs passed in, rather than only being able to use nixpkgs. Next, the packages have been replaced with a `nixosConfiguration.nixos-system`. This exposes a new nixos configuration with the hostname nixos-system to `nixos-rebuild`. When using this in a real system, make sure to change nixos-system to whatever your system hostname is. Thirdly, the `specialArgs = {inherit inputs;};` allows other files to access the flake inputs. Finally, the modules list includes every file imported into the NixOS config. This file can be placed alongside an existing NixOS configuration to add flakes to it. Using `nixos-rebuild switch` will create a flake.lock file and begin using flakes.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file includes a few new parts. First, the { self, nixpkgs } has been changed to { self, nixpkgs, ... } @ inputs. This allows for the flake to recognise any inputs passed in, rather than only being able to use nixpkgs.

The main "benefit" of @ inputs is to destructure the argument set. In addition, you may very well add more inputs to the argset (e.g. home-manager) without ever destructuring it.

The first sentence is incorrect.

When using this in a real system, make sure to change nixos-system to whatever your system hostname is

This does not have to be the hostname. The name is just to identify the contents of the set, nothing more. A system's hostname must be set with networking.hostName.


## Adding extra inputs to Flakes

One of the key benefits of flakes is the ability to use code from other projects. For example, the Hyprland WM has a flake, allowing you to use the latest builds rather than the build included in nixpkgs. This can be done using the following example:
Copy link

@NotAShelf NotAShelf Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not exclusive to flakes. You seem to have misunderstood what flakes are, and what comparative advantages they provide over non-flakes.


## Further reading

If flakes still confuse you, [this video by Vimjoyer](https://www.youtube.com/watch?v=JCeYq72Sko0) is a great source which teaches everything you need to know about flakes. All of Vimjoyer's content is very useful and is highly recommended when learning Nix and NixOS.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not encourage shilling of content creators for the purposes of a technical documentation.

For the sake of clarity, avoid linking personal blogs or youtube channels.

Copy link
Collaborator

@deviantsemicolon deviantsemicolon Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was kinda hoping we could link to the NixOS and Flakes book for further reading

But yeah, we should probably avoid linking YouTube videos

still needs a lot of improvements but i sleepy

Flakes are an experimental feature of Nix, but are widely used among the community. It that adds two new important files, the `flake.nix`, an entry-point file for your config, and `flake.lock`, an autogenerated lockfile, based on your `flake.nix`.

The addition of a lockfile, (like the `package-lock.json`/`Cargo.lock`/`poetry.lock` files you may have come across in other programming languages) makes your project truly *pure*, so it will be the same no matter where/when you build it (you can avoid a lot of "it works on my machine" problems), and any dependency can be trivially updated and rolled back, instead of dealing with channels via the `nix` cli or manually regenerating hashes for fetchers like `fetchTarball`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest extracting the comparison to other lock-files into a footnote for readability's sake

@deviantsemicolon deviantsemicolon marked this pull request as ready for review January 10, 2025 07:57
@deviantsemicolon
Copy link
Collaborator

Oh fuck me

@deviantsemicolon
Copy link
Collaborator

I did not mean to do that

@deviantsemicolon
Copy link
Collaborator

My thumbs are too fucking fat for this phone 😭


## Why use flakes?

The primary benefit flakes give is making Nix truly reproducable/pure. Without flakes, there is no way to include specific versions of git repos like nixpkgs in a Nix project. This can cause issues when sharing a project with others, as users could be using different versions of nixpkgs, causing bugs and conflicts. Flakes solve this with the flake.lock file. This file is automatically generated and pins all inputs to a specific git commit. This ensures that everyone using the Nix project is running the same version of nixpkgs and any other inputs. This setup, again, is nothing new. A flake is just a dependency lock file, which are commonly found in other programming languages, especially Node.JS, which uses a package.json and package.lock file.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without flakes, there is no way to include specific versions of git repos like nixpkgs in a Nix project.

This is not correct, as both fetchGit and fetchFromGitHub exist. However, as implied previously with fetchTarball (Line 13), using flakes is simply way more convenient to work with in the long term

@a-usr
Copy link
Member

a-usr commented Jan 10, 2025

Oh fuck me

Not now, Im at work

@a-usr
Copy link
Member

a-usr commented Jan 10, 2025

I did not mean to do that

cant you un-mark it ready for review?

@DamitusThyYeetus123 DamitusThyYeetus123 marked this pull request as draft January 10, 2025 08:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: In progress
Development

Successfully merging this pull request may close these issues.

5 participants