Flakes provide improved reproducibility and a more organized package structure, making it easier to maintain NixOS configurations compared to the traditional approach. Therefore, it is recommended to manage NixOS using Flakes.
However, as Flakes is still an experimental feature, it is not enabled by default. To enable Flakes, you need to modify the `/etc/nixos/configuration.nix` file as follows:
After enabling `flakes`, whenever you run `sudo nixos-rebuild switch`, it will first attempt to read the `/etc/nixos/flake.nix` file. If the file is not found, it will fallback to `/etc/nixos/configuration.nix`.
To learn how to write a Flakes configuration, you can refer to the official Flakes templates provided by Nix. To check the available templates, run the following command:
After reviewing the example, create a file named `/etc/nixos/flake.nix` and copy the content of the example into it. From now on, all system modifications will be managed by Flakes using `/etc/nixos/flake.nix`.
We defined a NixOS system called `nixos-test` with a configuration file at `./configuration.nix`, which is the classic configuration we modified before. Therefore, we can still make use of it.
To apply the configuration to a system with hostname `nixos-test`, run `sudo nixos-rebuild switch --flake /etc/nixos#nixos-test`. No changes will be made to the system because we imported the old configuration file in `/etc/nixos/flake.nix`, so the actual state we declared remains unchanged.
The comments in the above code are already quite detailed, but let's emphasize a few points here:
1. Default parameters like `lib`, `pkgs`, `config`, and others are automatically generated by Nixpkgs and can be automatically injected into submodules without the need for additional declarations here.
2. In `specialArgs = {...};`, the content of the attribute set is omitted here. Its contents are automatically injected into submodules through name matching.
1. A common usage, for instance, is to directly write `specialArgs = inputs;`, enabling all data sources from the `inputs` attribute set to be used in the submodules.
2. If you do not want to get all the data sources in `inputs` mixed with the defaults, use `specialArgs = {inherit inputs;};`(akin to `specialArgs = {inputs = inputs;};`) instead.
After the switch, we can manage the system using Flakes. One common requirement is installing packages. We have previously seen how to install packages using `environment.systemPackages` from the official `nixpkgs` repository.
Now let's learn how to install packages from other sources using Flakes. This is really useful when you want to use a newer version of some package that is not added into Nixpkgs yet.
Let's use [Helix](https://github.com/helix-editor/helix) editor as an example.
> If your system's hostname is not `nixos-test`, you need to modify the name of `nixosConfigurations` in `flake.nix`, or use `--flake /etc/nixos#nixos-test` to specify the configuration name.
> You can always try to add `--show-trace -L` to the `nixos-rebuild` command to get the detailed error message if you encounter any errors during the deployment.
Furthermore, if you merely want to experiment with the latest version of Helix before deciding whether to install it system-wide, there's a simpler way – just a single command:
> Similarly, if you wish to use the latest version, compiling from source is usually unavoidable and may take some time.
```bash
nix run github:helix-editor/helix/master
```
We will introduce `nix run` in detail at [Usage of the New CLI](/other-usage-of-flakes/the-new-cli.md)
In fact, this is the primary functionality of Flakes — a Flake can depend on other Flakes, allowing it to utilize the features they provide. It's akin to how we incorporate functionalities from other libraries when writing programs in TypeScript, Go, Rust, and other programming languages.
The example above, using the latest version from the official Helix Flake, illustrates this functionality. More use cases will be discussed later, and here are a few examples referenced for future mention:
- [Getting Started with Home Manager](./start-using-home-manager.md): This introduces the community's Home-Manager as a dependency, enabling direct utilization of the features provided by this Flake.
- [Downgrading or Upgrading Packages](./downgrade-or-upgrade-packages.md): Here, different versions of Nixpkgs are introduced as dependencies, allowing for flexible selection of packages from various versions of Nixpkgs.