Nix By Examples

Basics

The Nix Language

Flakes

hello world

console

To "nixify" a project, it only needs a `flake.nix` file at its root. To create one, you can use the `nix flake new` command.
$ nix flake new hello
$ cd hello
$ ls
flake.nix
To build a nix project, you can then use `nix build` which will find the `flake.nix` at the root of the project and build it. Unfortunately, by default mac is not supported.
$ nix build
error: flake 'path:/some/path/hello' does not provide attribute 'packages.x86_64-darwin.default' or 'defaultPackage.x86_64-darwin'
You can also launch a shell that will act as a development environment by running `nix develop -i`. Unfortunately, this won't work on mac by default as well.
$ hello nix develop -i
warning: creating lock file '/some/path/hello/flake.lock'
error: flake 'path:/some/path/hello' does not provide attribute 'devShells.x86_64-darwin.default', 'devShell.x86_64-darwin', 'packages.x86_64-darwin.default' or 'defaultPackage.x86_64-darwin'
If you are on mac, modify the flake file and replace `linux` with `darwin` and run `nix build` again. You should see two new files: a lock file and a result file symlinking to the built artifacts.
$ ls -l
total 16
drwxr-xr-x  5 me  staff   160B Aug  7 14:31 .
drwxr-xr-x  3 me  staff    96B Aug  7 13:40 ..
-rw-r--r--  1 me  staff   508B Aug  7 14:12 flake.lock
-rw-r--r--  1 me  staff   378B Aug  7 14:29 flake.nix
lrwxr-xr-x  1 me  staff    56B Aug  7 14:31 result -> /nix/store/zrm3agz6hqncqbbpmn8v3w70qzzd2wdd-hello-2.12.1
In the folder symlinked by the `result` file you can find binaries and outputs produced by the build of the `hello` package.
$ /nix/store/zrm3agz6hqncqbbpmn8v3w70qzzd2wdd-hello-2.12.1/bin/hello 
Hello, world!
Thix `nix flake show` command shows you what is encoded by the `flake.nix` file.
$ nix flake show
path:/some/path/hello?lastModified=1659875514&narHash=sha256-mse3RPTu2OYYM%2fteTK54p6xgO5QpyYRiVdjZgj80%2frQ=
├───defaultPackage
│   ├───x86_64-darwin: package 'hello-2.12.1'
│   └───x86_64-linux: package 'hello-2.12.1'
└───packages
    ├───x86_64-darwin
    │   └───hello: package 'hello-2.12.1'
    └───x86_64-linux
        └───hello: package 'hello-2.12.1'

flake.nix

A .nix file is written using the nix language (more on that later).
{
  description = "A very basic flake";

  outputs = { self, nixpkgs }: {
We obtain the `hello` package from [nixpkgs](https://github.com/NixOS/nixpkgs), the place for all softwares that were packaged with nix. Note that `packages` is a list of `packages` we want to package, and it is a special keyword recognized by `nix` (so you can write `nix build#hello`). For this reason, `nixpkgs` had to use a different keyword called `legacyPackages`.
    packages.x86_64-linux.hello = nixpkgs.legacyPackages.x86_64-linux.hello;
the `defaultPackage` points to what `nix build` will build by default. It is a deprecated keyword, which is still used by the nix CLI for some reason. Don't worry too much about the content of our `flake.nix` for now, you'll have to learn a bit more about the nix language before we go back to that.
    defaultPackage.x86_64-linux = self.packages.x86_64-linux.hello;

  };
}

flake.lock

The `flake.lock` file is created when you build for the first time. It is then used to track the hash of each dependencies you listed, so that they do not change under you in the future.
{
  "nodes": {
    "nixpkgs": {
      "locked": {
        "lastModified": 1659782844,
        "narHash": "sha256-tM/qhHFE61puBxh9ebP3BIG1fkRAT4rHqD3jCM0HXGY=",
        "owner": "NixOS",
        "repo": "nixpkgs",
        "rev": "c85e56bb060291eac3fb3c75d4e0e64f6836fcfe",
        "type": "github"
      },
      "original": {
        "id": "nixpkgs",
        "type": "indirect"
      }
    },
    "root": {
      "inputs": {
        "nixpkgs": "nixpkgs"
      }
    }
  },
  "root": "root",
  "version": 7
}
next: REPL