NixOS & Nix Flakes - A Guide for Beginners

The target NixOS version of this article is 22.11, and the Nix version is 2.13.3. In this environment, Nix Flakes is still an experimental feature.
Article History
- 2023/5/21
- Complete the “Overlays” section.
- remove the “IX. Nix Packaging” section, which may be moved to a separate article in the future.
- Add an example of installing programs via flakes at section VI-4.
0. Why Nix
I heard about the Nix package manager several years ago. It uses the Nix language to describe system configuration, and the Linux distribution build on top of it can roll back to any historical state at any time. Although it sounds impressive, it requires learning a new language and writing code to install packages, I thought it was too troublesome and didn’t study it at the time.
But recently I encountered two troublesome things when migrating the system, which made me decide to try Nix.
The fist problem was installing EndeavourOS (a derivative distribution of Arch Linux) on a newly assembled PC. Because My old PC also uses EndeavourOS, I directly rsync
the old PC’s Home directory to the new PC to save time after installation.
However, this synchronization caused a problem. All functions worked normally, but video playback always stuck. Firefox, Chrome, and MPV would all get stuck. I searched various resources online but could not solve the problem until I realized it might be caused by the Home directory synchronization. After clearing the Home directory, the problem was solved immediately… Later, I spent a long time recovering things from the old PC one by one.
The second problem is that I recently wanted to try Wayland, so I changed the desktop from i3wm to sway. However, because there was little difference between the two and many inconveniences (hidpi, Sway configuration tuning, etc.), I decided to switch back to i3wm. After switching back, GUI programs such as Firefox and Thunar would always get stuck for about a minute after the system started…
I was too tired to deal with the second problem, after thinking about it carefully, I realized that the root cause was that the system did not have any version control and rollback mechanism, which caused the system to be unable to be restored when problems occurred. And another problem, when installing a new system, I had to manually export the package list from the old machine and then install them on the new machine. So I decided to switch to NixOS.
The first step I took was to create a NixOS virtual machine in my Homelab, and debug step by step in this virtual machine to migrate my old PC’s EndeavourOS i3 configuration to NixOS + Flakes and restore the entire desktop environment.
Once I had it working on the virtual machine, the rest was easy. I simply backed up my Home directory and software list from my work computer, reinstalled the system as NixOS, git cloned my debugged NixOS configuration, made some adjustments to the disk mounting parameters and added some extra NixOS configurations for my Nvidia graphics card. Finally, with just a few commands, I deployed the configuration and was able to restore the entire i3 desktop environment and my commonly used software on my fresh NixOS system. It was a truly satisfying moment!
The rollback capability of NixOS gave me a lot of confidence - I no longer fear breaking the system. So a few days ago, I further migrated to the hyprland desktop, which is indeed much better than i3, and I love its animation effects! (On EndeavourOS before, I wouldn’t have dared to make such a switch for the reasons mentioned earlier - it would have been a big hassle if something went wrong with the system.)
Note: some friends on V2EX gave feedback that
btrfs
’s snapshot feature can also provide similar rollback capabilities, and it is much simpler. After some research, I found that to be true.btrfs
can even be configured to boot from a snapshot using GRUB(just like the NixOS does). So if you only want the system rollback capability, then btrfs based snapshot tools(e.g. btrbk) is also a good choice. Or if you’re still interested in Nix, It is definitely worth learning, as Nix’s capabilities are far beyond just system snapshots.

My NixOS Desktop
So after studying NixOS and Nix Flakes for about half a month, I finally completed my system switch, and this article is born out of the notes I wrote during this period of time, hope you like it~
Now that the background information is out of the way, it’s time to dive into the world of Nix!
I. Introduction to Nix
Nix package manager is a declarative configuration management tool similar to pulumi/terraform/kubernetes that are currently popular in the DevOps field. Users need to declare the expected system state in some configurations, and Nix is responsible for achieving that goal. The difference is that Nix manages software packages, while pulumi/terraform manages cloud resources.
To put it simply, “declarative configuration” means that users only need to declare the results they want. For example, you declares that you want to replace the i3 window manager with sway, then Nix will help you achieve the goal. You don’t need to worry about the underlying details (such as which packages sway needs to install, which i3-related packages need to be uninstalled, which system configurations or environment variables need to be adjusted for sway, what adjustments need to be made to the Sway parameters if an Nvidia graphics card is used, etc.), Nix will automatically handle these details for the user(prerequisite: if the sway’s nix packages are designed properly…).
The Linux distribution built on top of the Nix package manager, NixOS, can be simply described as “OS as Code”, which describes the entire operating system’s state using declarative Nix configuration files.
NixOS’s configuration only manages the system-level state, the user’s HOME directory is not under its control. Another important community project, home-manager, filled this gap, home-manager is designed to managing user-level’s packages & HOME directories. By combining home-manager with NixOS and Git, a fully reproducible and rollbackable system environment can be obtained(ideally).
Due to Nix’s declarative and reproducible features, Nix is not only used to manage desktop environments but also widely used to manage development and compilation environments, cloud virtual machines, and container image construction. NixOps from the Nix official and deploy-rs from the community are both operations tools based on Nix.
Since there are numerous files in the home directory with varying behaviors, it is impossible to version control all of them due to the high cost. Generally, only some important configuration files are managed using home-manager, and other files that need to be backed up can be backed up and synchronized using rsync/synthing, or use tools like btrbk to take snapshots of the home directory.
Advantages of Nix
- Declarative configuration, Environment as Code, can be managed with Git. As long as the configuration files are not lost, the system can be restored to any historical state at any time(ideally).
- Nix lock dependent library versions through a lock file named
flake.lock
, to ensure that the system is reproducible, this idea actually borrows from some package managers such as npm, cargo, etc. - Compared with Docker, Nix provides a much stronger guarantee for the reproducibility of build results, because Dockerfile is actually an imperative configuration and there is no such thing as
flake.nix
in Docker, Docker’s reproducibility relys on share the build result(which is MUCH MORE LARGAR than Dockerfile itself) through image regitry(e.g. DockerHub).
- Nix lock dependent library versions through a lock file named
- Highly convenient system customization capability
- By changing a few lines of configuration, various components of the NixOS system can be easily customized. This is because Nix encapsulates all the underlying complex operations in nix packages and only exports concise and necessary declarative parameters.
- Moreover, this modification is very safe. An example is that one NixOS user on the V2EX forum have stated that “on NixOS, switching between different desktop environments is very simple and clean, and it is very safe. I often switch between gnome/kde/sway.”
- Rollback: The system can be rolled back to any historical environment at any time, and NixOS even adds all old versions to the boot options by default to ensure that the system can be rolled back at any time even though it crashes. Therefore, NixOS is also considered one of the most stable Linux Systems.
- No dependency conflicts: Because each software package in Nix has a unique hash, its installation path also includes this hash value, so multiple versions can coexist.
- The community is very active, and there are quite a few third-party projects. The official package repository, nixpkgs, has many contributors, and many people share their Nix configurations on Github/Gitlab. After browsing through it, the entire ecosystem gives me a sense of excitement in discovering a new continent.

All historical versions are listed in the boot options of NixOS. Image from NixOS Discourse - 10074
Disadvantages of Nix
- Relatively high learning curve:: If you want the system to be completely reproducible and avoid pitfalls caused by improper use, you need to learn about the entire design of Nix and manage the system in a declarative manner. You cannot blindly use
nix-env -i
(which is similar toapt-get install
). - Chaotic documentation: Firstly, Nix Flakes is still an experimental feature, and there are currently relatively few documents introducing it. Secondly, most of the Nix community’s documentation only introduces the old
nix-env
/nix-channel
. If you want to start learning Nix directly from Nix Flakes, you need to refer to a large number of old documents and extract what you need from them. In addition, some of Nix’s current core functions are not well-documented (such asimports
and Nixpkgs Module System), so it is best to look at the source code to understand them. Relatively few packages: Retract this one. The official claim is that nixpkgs has 80000+ packages, and indeed, most packages can be found in nixpkgs.- Relatively high disk space usage: To ensure that the system can be rolled back at any time, Nix preserves all historical environments by default, which can take up a lot of disk space. Although you can manually clean up old historical environments periodically with
nix-collect-garbage
, it is still recommended to buy a larger hard drive.
Summary
Generally speaking, I think NixOS is suitable for developers who have a certain amount of Linux usage experience and programming experience and want to have more control over their systems.
Another info, there is also some competition between Nix and the relatively popular Dev Containers in the construction of development environment, and the specific differences between them have yet to be explored by me~
II. Installation
Nix can be installed in multiple ways and supports being installed on MacOS/Linux/WSL as a package manager. Nix also provides NixOS, a Linux distribution that uses Nix to manage the entire system environment.
I chose to directly install NixOS system using its ISO image, to manage the entire system environment through Nix as much as possible.
The installation process is simple, and I won’t go into details here.
some reference materials that maybe useful:
- Official installation method of Nix: written in bash script,
nix-command
&flakes
are still experimental features as of 2023-04-23, and need to be manually enabled.- You need to refer to the instructions in Enable flakes - NixOS Wiki to enable
nix-command
&flakes
. - The official installer does not provide any uninstallation method. To uninstall Nix on Linux/MacOS, you need to manually delete all related files, users, and groups.
- You need to refer to the instructions in Enable flakes - NixOS Wiki to enable
- The Determinate Nix Installer: a third-party installer written in Rust, which enables
nix-command
&flakes
by default and provides an uninstallation command.
III. Nix Flakes and the old Nix
In 2020, Nix introduced two new features, nix-command
and flakes
, which provide new command-line tools, standard Nix package structure definitions, and flake.lock
version lock files similar to cargo/npm. These two features greatly enhance the capabilities of Nix. Although they are still experimental features as of 2023-05-05, they have been widely used by the Nix community and are strongly recommended.
Currently, most of the Nix community’s documentation still only covers traditional Nix and does not include Nix Flakes-related content. However, from the perspective of reproducibility and ease of management and maintenance, the old Nix package structure and command-line tools are no longer recommended for use. Therefore, this document will not introduce the usage of the old Nix package structure and command-line tools, and it is recommended that beginners ignore these old contents and just start with nix-command
& flakes
.
Here are the old Nix command-line tools and related concepts that are no longer needed in nix-command
and flakes
. When searching for information, you can safely ignore them:
nix-channel
:nix-channel
is similar to other package management tools such as apt/yum/pacman, managing software package versions through stable/unstable/test channels.- In Nix Flakes, the functionality of
nix-channel
is completely replaced byinputs
inflake.nix
to declare dependency sources andflake.lock
to lock dependency versions.
- In Nix Flakes, the functionality of
nix-env
:nix-env
is a core command-line tool for traditional Nix used to manage software packages in the user environment. It installs software packages from the data sources defined bynix-channel
, so the installed package versions are influenced by the channel. Packages installed withnix-env
are not automatically recorded in Nix’s declarative configuration and are entirely outside of its control, making them difficult to reproduce on other machines. Therefore, it is not recommended to use this tool.- The corresponding command in Nix Flakes is
nix profile
.
- The corresponding command in Nix Flakes is
nix-shell
:nix-shell
is used to create a temporary shell environment.- In Nix Flakes, it is replaced by
nix develop
andnix shell
.
- In Nix Flakes, it is replaced by
nix-build
:nix-build
is used to build Nix packages, and it places the build results in the/nix/store
path, but it does not record them in Nix’s declarative configuration.- The corresponding command in Nix Flakes is
nix build
.
- The corresponding command in Nix Flakes is
- …
maybe
nix-env -qa
is still useful some times, which returns all packages installed in the System.
IV. NixOS Flakes Package Repositories
Similar to Arch Linux, Nix also has official and community software package repositories:
- nixpkgs is a Git repository containing all Nix packages and NixOS modules/configurations. Its master branch contains the latest Nix packages and NixOS modules/configurations.
- NUR is similar to Arch Linux’s AUR. NUR is a third-party Nix package repository and serves as a supplement to nixpkgs.
- Nix Flakes can also install software packages directly from Git repositories, which can be used to install Flakes packages provided by anyone.
V. Nix language basics
The Nix language is used to declare packages and configurations to be built by Nix, if you want to play NixOS and Nix Flakes and enjoy the many benefits they bring, you must learn the basics of this language first.
Nix is a relatively simple functional language, if you already have some programming experiences, it should take less than 2 hours to go through these grammars.
Please read Nix language basics - nix.dev to get a basic understanding of Nix language now, it’s a very good tutorial.
VI. Managing the system declaratively
https://nixos.wiki/wiki/Overview_of_the_NixOS_Linux_distribution
After learning the basics of the Nix language, we can start using it to configure the NixOS system. The system configuration file for NixOS is located at /etc/nixos/configuration.nix
, which contains all the declarative configurations for the system, such as time zone, language, keyboard layout, network, users, file system, boot options, etc.
If we want to modify the system state in a reproducible way (which is also the most recommended way), we need to manually edit the /etc/nixos/configuration.nix
file, and then execute sudo nixos-rebuild switch
to apply the configuration. This command generates a new system environment based on the configuration file, sets the new environment as the default one, and also preserves & added the previous environment into the grub boot options. This ensures we can always roll back to the old environment(even if the new environment fails to start).
On the other hand, /etc/nixos/configuration.nix
is the traditional Nix configuration method, which relies on data sources configured by nix-channel
and has no version locking mechanism, making it difficult to ensure the reproducibility of the system. A better approach is to use Nix Flakes, which can ensure the reproducibility of the system and make it easy to manage the configuration.
Now first, let’s learn how to manage the system using the default configuration method of NixOS through /etc/nixos/configuration.nix
, and then transition to the more advanced Nix Flakes.
1. Configuring the system using /etc/nixos/configuration.nix
As mentioned earlier, this is the traditional Nix configuration method and also the default configuration method currently used by NixOS. It relies on data sources configured by nix-channel
and has no version locking mechanism, making it difficult to ensure the reproducibility of the system.
For example, to enable ssh and add a user “ryan,” simply add the following configuration to /etc/nixos/configuration.nix
:
|
|
in the configuration above, we enabled the openssh service, added an ssh public key for the user ryan, and disabled password login.
Now, running sudo nixos-rebuild switch
deploys the modified configuration, and then we can login to the system using ssh with ssh keys.
This is the default declarative system configuration in NixOS, where any reproducible changes to the system can be made by modifying the /etc/nixos/configuration.nix
file and deploying the changes by running sudo nixos-rebuild switch
.
All configuration options in /etc/nixos/configuration.nix
can be found in the following places:
- By searching on Google, such as
Chrome NixOS
, which will provide NixOS informations related to Chrome. Generally, the NixOS Wiki and the nixpkgs repository source code will be among the top results. - By searching for keywords in NixOS Options Search.
- For system-level configurations, relevant documentation can be found in Configuration - NixOS Manual.
- By searching for keywords directly in the nixpkgs repository and reading relevant source code.
2. Enabling NixOS Flakes Support
Compared to the default configuration approach of NixOS, Nix Flakes provide better reproducibility and a clearer package structure that is easier to maintain. Therefore, it is recommended to use Nix Flakes to manage system configurations.
However, Nix Flakes is currently an experimental feature and is not yet enabled by default. We need to enable it manually by modifying the /etc/nixos/configuration.nix
, example:
|
|
Now run sudo nixos-rebuild switch
to apply the changes, and then you can use Nix Flakes to manage the system configuration.
3. Switching System Configuration to flake.nix
After enabling the Nix Flakes feature, the sudo nixos-rebuild switch
command will prioritize reading the /etc/nixos/flake.nix
file. If not found, it will fallback to /etc/nixos/configuration.nix
.
Now let’s use the official flake templates provided by Nix to learn how to write flakes, check which templates are available using the following command:
|
|
One of the templates, templates#full
, shows all possible uses., take a look at its contents:
|
|
Now create a file /etc/nixos/flake.nix
and write the configuration content according to the template above.
All system modifications will be taken over by Nix Flakes from now on. An example configuration is shown below:
|
|
Here we define a NixOS system called nixos-test
, whose configuration file is ./configuration.nix
, which is our previous configuration file, so we can still use the old configuration.
Now execute the sudo nixos-rebuild switch
command to apply the configuration, and there should be no change to the system, because we just switch to Nix Flakes, and the actual configuration content is the same as before.
4. Manage system software through Flakes
After the switch, we can manage the system through Flakes. The most common requirement for managing a system is to install software. We have seen how to install packages in pkgs
through environment.systemPackages
before, and these packages are all from the official nixpkgs repository.
Now let’s learn how to install packages from other sources through Flakes. This is much more flexible than installing nixpkgs directly. The most obvious benefit is that you can easily set the version of the software.
Use helix editor as an example, we first need to add the helix input data source in flake.nix
:
|
|
Then udpate configuration.nix
to install helix
from flake input:
|
|
Now deploy the changes with sudo nixos-rebuild switch
, and the helix editor will be installed. You can test it with the helix
command.
5. Add Custom Cache Mirror
In order to speed up package building, Nix provides https://cache.nixos.org to cache build results to avoid build every packages locally.
In the old NixOS configuration, other cache sources can be added through nix-channel
command, but Nix Flakes avoids using any system-level configuration and environment variables as far as possible to ensure that its build results are not affected by the environment(environment independent).
Therefore, in order to customize the cache image source, we must add the related configuration in flake.nix
by using the parameter nixConfig
. The example is as follows:
|
|
After the modification, execute sudo nixos-rebuild switch
to apply the configuration.
6. install home-manager
We mentioned earlier that NixOS can only manage system-level configurations, and user-level configurations need to be managed using home-manager.
According to the official document Home Manager Manual, in order to install home-manager as an module of NixOS, we need to create /etc/nixos/home.nix
first, an example content shown below:
|
|
After adding /etc/nixos/home.nix
, you need to import this new configuration file in /etc/nixos/flake.nix
to make it effective, use the following command to generate an example /etc/nixos/flake.nix
in the current folder for reference:
|
|
After adjusting the parameters, the content of /etc/nixos/flake.nix
is as follows:
|
|
Then execute sudo nixos-rebuild switch
to apply the configuration, and home-manager will be installed automatically.
After the installation is complete, all user-level programs and configurations can be managed through /etc/nixos/home.nix
, and when executing sudo nixos-rebuild switch
, the configuration of home-manager will be applied automatically.
To find the options of home-manager used in home.nix
, use the following methods:
- Home Manager - Appendix A. Configuration Options: A list of all options, it is recommended to search for keywords in it.
- home-manager: Some options are not listed in the official documentation, or the documentation is not clear enough, you can directly search and read the corresponding source code in this home-manager repo.
7. Modular NixOS configuration
At this point, the skeleton of the entire system is basically configured. The current system configuration structure in /etc/nixos
should be as follows:
|
|
The functions of these four files are explained below:
flake.lock
: An automatically generated version lock file, which records all input data sources, hash values, and version numbers of the entire flake to ensure that the system is reproducible.flake.nix
: The entry file, which will be recognized and deployed when executingsudo nixos-rebuild switch
.- See Flakes - NixOS Wiki for all options of flake.nix.
configuration.nix
: Imported as a Nix module in flake.nix, all system-level configurations are currently written in this file.- See Configuration - NixOS Manual for all options of configuration.nix.
home.nix
: Imported by home-manager as the configuration of the userryan
in flake.nix, that is, it contains all the Home Manager configurations ofryan
, and is responsible for managingryan
’s Home folder.- See Appendix A. Configuration Options - Home Manager for all options of home.nix.
By modifying the above configuration files, you can change the status of the system and the Home directory declaratively.
As the configuration increases, it is difficult to maintain the configuration files by relying solely on configuration.nix
and home.nix
. Therefore, a better solution is to use the module mechanism of Nix to split the configuration files into multiple modules and write them in a classified manner.
imports
parameter can accept a list of .nix
files, and merge all the configurations in the list into the current attribute set. Note that the word used here is “merge”, which means that imports
will NOT simply overwrite the duplicate configuration items, but handle them more reasonably. For example, if I define program.packages = [...]
in multiple modules, then imports
will merge all program.packages
in all modules into one list. Not only lists can be merged correctly, but attribute sets can also be merged correctly. The specific behavior can be explored by yourself.
I only found a description of
imports
in nixpkgs-unstable official manual - evalModules parameters:A list of modules. These are merged together to form the final configuration.
, you can try to understand it…
With the help of the imports
parameter, we can split home.nix
and configuration.nix
into multiple .nix
files.
For example, the structure of my previous i3wm system configuration ryan4yin/nix-config/v0.0.2 is as follows:
|
|
For the details of the structure and content, please go to the github repository ryan4yin/nix-config/v0.0.2.
8. Update the system
After using Nix Flakes, it is also very simple to update the system. First update the flake.lock file, and then deploy it. Execute the following command in the configuration folder:
|
|
Sometimes when installing new packages, you may encounter an error of sha256 mismatch when running nixos-rebuild switch
. You can also try to solve it by updating flake.lock
through nix flake update
.
9. Rollback the version of some packages
After using Nix Flakes, most people are currently using the nixos-unstable
branch of nixpkgs. Sometimes you will encounter some bugs, such as the chrome/vscode crash problem
To resolve this problem, we need to rollback the version of some packages. In Nix Flakes, all package versions and hash values are one-to-one corresponding to the git commit of their input data source. Therefore, to rollback a package to a historical version, we need to lock the git commit of its input data source.
So to rollback the version of some packages, first modify /etc/nixos/flake.nix
, the example content is as follows (mainly using the specialArgs
parameter):
|
|
And then refer the packages from nix-stable
or nixpkgs-fd40cef8d
in your corresponding sub module, a home manager’s sub module as an example:
|
|
After adjusted the configuration, deploy it with sudo nixos-rebuild switch
, then your firefox/chrome/vscode will revert to the version corresponding to nix-stable
or nixpkgs-fd40cef8d
.
10. Manage NixOS configuration with Git
NixOS’s configuration file is plain text, so it can be managed with Git just like ordinary dotfiles.
On the other hand, flake.nix
do not required to be placed in the /etc/nixos
directory, they can be placed in any directory, as long as the correct path is specified during deployment.
For example, my usage is to place the Nix Flakes configuration in the ~/nixos-config
directory, and then create a soft link in the /etc/nixos
directory:
|
|
And then you can use Git to manage the configuration in the ~/nixos-config
directory. The configuration can be used with ordinary user-level permissions, and it is not required to be owned by root.
Another method is to delete /etc/nixos
directly, and specify the configuration file path each time you deploy:
|
|
Choose whichever you like.
11. Other commands you may need
As we mentioned before, each deployment of NixOS will generate a new version, and all versions will be added to the system boot items. In addition to restarting the computer, we can also query all available historical versions through the following command:
|
|
You can also list all Nix packages currently installed in the system with the following command:
|
|
And the command to clean up historical versions to release storage space:
|
|
VII. Usage of Nix Flakes
Up to now, we have written a lot of Nix Flakes configurations to manage the NixOS system. Here is a brief introduction to the more detailed content of Nix Flakes, as well as commonly used nix flake commands.
1. Flake outputs
the outputs
in flake.nix
are what a flake produces as part of its build. Each flake can have many different outputs simultaneously, including but not limited to:
- Nix packages: named
apps.<system>.<name>
,packages.<system>.<name>
, orlegacyPackages.<system>.<name>
- Nix Helper Functions: named
lib
., which means a library for other flakes. - Nix development environments: named
devShells
devShells
can be used by commandnix develop
, will be introduced later.
- NixOS configurations: named
nixosConfiguration
- Nix templates: named
templates
- templates can be used by command
nix flake init --template <reference>
- templates can be used by command
- Other user defined outputs
2. Flake Command Line Usage
after enabled nix-command
& flake
, you can use nix help
to get all the info of New Nix Commands, some useful examples are listed below:
|
|
Zero to Nix - Determinate Systems is a brand new guide to get started with Nix & Flake, recommended to read for beginners.
VIII. Nixpkgs’s Advanced Usage
callPackage
, Overriding
, and Overlays
are the techniques occasionally used when using Nix to customize the build method of Nix packages.
We know that many programs have a large number of build parameters that need to be configured, and different users may want to use different build parameters. This is where Overriding
and Overlays
come in handy. Let me give you a few examples I have encountered:
fcitx5-rime.nix
: By default,rimeDataPkgs
forfcitx5-rime
uses therime-data
package, but this parameter can be customized usingoverride
to load custom rime configurations (such as loading the Xiaohe keyboard input method configuration).vscode/with-extensions.nix
: This package for VS Code can also be customized by overriding the value of thevscodeExtensions
parameter to install custom plugins.nix-vscode-extensions
: This is a vscode plugin manager implemented using this parameter.
firefox/common.nix
: Firefox also has many customizable parameters.- …
In short, in order to customize the build parameters of Nix packages of this type, we need to use Overriding
or Overlays
.
Overriding
Simply put, all Nix packages in nixpkgs can be customized with <pkg>.override {}
to define some build parameters, which returns a new Derivation that uses custom parameters. For example:
|
|
The result of executing the above Nix expression is a new Derivation, where the rimeDataPkgs
parameter is overridden as [./rime-data-flypy]
, while other parameters retain their original values.
In addition to overriding parameters, you can also override the attributes of a Derivation(condiftion: it’s built using stdenv.mkDerivation
) by using overrideAttrs
. For example:
|
|
In this example, helloWithDebug
is a new Derivation, where the separateDebugInfo
parameter is overridden as true
, while other parameters retain their original values.
Overlays
The override
we introduced above will generate a new Derivation, which does not affect the original Derivation in pkgs
, and is only suitable for use as a local parameter,
if you need to override a Derivation that is also depended on by other Nix packages, then other Nix packages will still use the original Derivation.
To solve this problem, Nix provides the ability to use overlays
. Simply put, overlays
can globally modify the Derivation in pkgs
.
In the classic Nix environment, Nix automatically applies all overlays
configurations under the paths ~/.config/nixpkgs/overlays.nix
~/.config/nixpkgs/overlays/*.nix
,
but in Flakes, in order to ensure the reproducibility of the system, it cannot depend on any configuration outside the Git repository, so this classic method cannot be used now.
When using Nix Flakes to write NixOS configuration, Home Manager and NixOS both provide the nixpkgs.overlays
option to define overlays
, related documentation:
For example, the following content is a Module that loads Overlays, which can be used as either a Home Manager Module or a NixOS Module, because the two definitions are exactly the same:
Home Manager is an external component after all, and most people use the unstable branch of Home Manager & nixpkgs, which sometimes causes problems with Home Manager Module, so it is recommended to import
overlays
in a NixOS Module.
|
|
refer to this example to write your own overlays, import the configuration as a NixOS Module or a Home Manager Module, and then deploy it to see the effect.
Modular overlays
The example above shows how to write overlays, but all overlays are written in a single nix file, which is a bit difficult to maintain.
To resolve this problem,here is a best practice of how to manage overlays in a modular way.
First, create an overlays
folder in the Git repository to store all overlays configurations, and then create overlays/default.nix
, whose content is as follows:
|
|
Then you can write all overlays configurations in the overlays
folder, an example configuration overlays/fcitx5/default.nix
is as follows:
|
|
I custom the rime-data
package through the above overlay.
At last, you need to load all overlays configurations returned by overlays/default.nix
through the nixpkgs.overlays
option, add the following parameter to any NixOS Module:
|
|
For example, add the parameter directly in flake.nix
:
|
|
According to the above method, it is very convenient to modularize all overlays configurations. Taking my configuration as an example, the structure of the overlays
folder is roughly as follows:
|
|
Advanced Usage
After becoming familiar with the Nix toolchain, you can further explore Nix’s three manuals to discover more ways to use it:
- Nix Reference Manual: A guide to the Nix package manager, which mainly covers the design of the package manager and instructions for using it from the command line.
- nixpkgs Manual: A manual that introduces parameters of Nixpkgs, how to use, modify, and package Nix packages.
- NixOS Manual: A user manual for the NixOS system, mainly including configuration instructions for system-level components such as Wayland/X11 and GPU.
- nix-pills: Nix Pills provides an in-depth explanation of how to use Nix to build software packages. It is written in a clear and understandable way and is worth reading, as it is also sufficiently in-depth.
After becoming familiar with Nix Flakes, you can try some advanced techniques. Here are some popular community projects to try:
- flake-parts: Simplify the writing and maintenance of configuration through the Module module system.
- flake-utils-plus: A third-party package for simplifying Flake configuration, which is apparently more powerful.
- digga: A large and comprehensive Flake template that combines the functionality of various useful Nix toolkits, but has a complex structure and requires some experience to navigate.
- etc.
And many other useful community projects to explore, here are some of them:
- devenv: development environment management
- agenix: secrets management
- colmena: NixOS deployment tools
- nixos-generator: generate iso/qcow2/… from nixos configuration
- lanzaboote: enable secure boot for NixOS
- impermanence: used to make NixOS stateless, to imporve the reproduciability of NixOS system.
References
The feedback and discussion of the article is mainly on this Reddit post, you can also comment directly at the bottom of this page.
Here are some useful resources that I have referred to:
- Zero to Nix - Determinate Systems: A beginner-friendly Nix Flakes tutorial that is worth reading.
- NixOS series: LanTian’s NixOS series, which are very clear and easy to understand, a must-read for beginners.
- Nix Flakes Series: An official Nix Flakes tutorial series, which provides a relatively detailed introduction and is suitable for beginners.
- Nix Flakes - Wiki: The official Nix Flakes wiki, which provides a relatively rough introduction.
- ryan4yin/nix-config: My NixOS configuration repository, which also lists other configuration repositories that I have referred to in the README.