From configuration.nix to Flake
On this page
What’s Up
Section titled “What’s Up”With less than 240 days until the Gaokao, time is tight and I don’t have much time to blog. But after getting roasted by my group chat friends — “at least write one post, otherwise this site will just sit here empty forever” — here I am. I do keep a diary, but it’s too personal to share with everyone.
Amid the chaos I did manage to get some things done. For example, last weekend I finally set up Flake, which I’d been wanting to do for ages. With the help of CodeX CLI it didn’t take much time — I let the AI Agent handle the trickiest parts and it was almost a one-shot. Here’s the current directory structure:
.├── flake.lock├── flake.nix├── home│ └── modules│ ├── dae.nix│ ├── fzf.nix│ └── niri.nix├── Justfile└── nixos ├── configs │ ├── dae │ │ └── config.dae │ └── niri │ └── config.kdl ├── hosts │ └── kokosa │ ├── default.nix │ └── hardware.nix └── modules ├── boot.nix ├── desktop.nix ├── locale.nix ├── networking.nix ├── nix-settings.nix ├── packages.nix ├── security.nix ├── services.nix └── users.nixOf the programs managed by Home Manager, only fzf is actually in use. The other two are planned for future use, so I wrote the configs in advance but they’re disabled in the settings.
Why Switch from Channels to Flakes?
Section titled “Why Switch from Channels to Flakes?”Compared to configuration.nix, Flake solves many problems. It can lock all packages and their dependency versions — one config file can restore the entire system precisely down to version numbers and commits, which configuration seemingly can’t do since it follows Channel updates.
| Feature | Channels | Flakes |
|---|---|---|
| Dependencies | Implicit (channels) | Explicit (inputs) |
| Rebuild | sudo nixos-rebuild switch | nh os switch . |
| Reproducibility | Depends on individual channel versions | flake.lock ensures consistency |
| Development | nix-shell | nix develop |
nh is a NixOS helper tool, but its configuration-mode support was a bit mysterious. After switching to Flake I found it to be a really nice tool — appreciated and recommended.
Additionally, Flake can easily reference other Flakes through Inputs, like sodiboo/niri-flake, enabling declarative management of software that isn’t officially supported. I don’t actually plan to use HM to manage Niri.
On the development environment side, you might have noticed that many open-source projects on GitHub/Codeberg now have a flake.nix file in their root directory. With this file you can easily reproduce the entire dev environment with Nix, isolated from your main system — with just a single nix develop. Most modern Nix projects (even non-Nix projects) are adopting this, because it genuinely works well.
Of course there are some drawbacks, like an unstable API (still “experimental” since 2019) and a mandatory Git dependency, among other pitfalls. Determinate Nix solves quite a few of these, but it’s partially closed-source (e.g. nixd). Despite Flake’s rough edges, it’s still more convenient than Channels. And now with AI managing my config, the migration wasn’t particularly complex.
File Showcase?
Section titled “File Showcase?”First, flake.nix:
{ description = "Kokosa's Nix Flake";
inputs = { # Nixpkgs & NUR nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; nur.url = "github:nix-community/NUR";
# Flake-parts flake-parts.url = "github:hercules-ci/flake-parts";
# Home Manager home-manager = { url = "github:nix-community/home-manager"; inputs.nixpkgs.follows = "nixpkgs"; };
# Other hid-bpf-uclogic.url = "github:dramforever/hid-bpf-uclogic"; };
outputs = inputs @ { nixpkgs, flake-parts, ... }: flake-parts.lib.mkFlake {inherit inputs;} { systems = ["x86_64-linux"];
perSystem = {pkgs, ...}: { formatter = pkgs.alejandra; };
flake = { nixosConfigurations.kokosa = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; specialArgs = { inherit inputs; }; modules = [ ./nixos/hosts/kokosa/default.nix ]; }; }; };}The single file imported, default.nix, is what used to be my machine’s configuration.nix. It’s now been transformed beyond recognition — the original massive file has been sliced into many smaller files and unified through imports. Aside from that, this file only contains some Home Manager settings.
imports = [ inputs.home-manager.nixosModules.home-manager ../../modules/nix-settings.nix ../../modules/networking.nix ../../modules/security.nix ../../modules/packages.nix ../../modules/services.nix ../../modules/desktop.nix ../../modules/locale.nix ../../modules/users.nix ../../modules/boot.nix ./hardware.nix ];The rest isn’t much different from my old config. They haven’t been uploaded to GitHub yet — I’ll probably get around to it when I have time. To wrap up, here’s a screenshot:
