Hi
I’m trying to understand what I’m doing wrong with my current setup.
For now, I’m using a mostly “classic” NixOS configuration while gradually introducing flakes. I’d like to spend some time understanding the trade-offs and the controversy around flakes before fully committing to them.
I’m importing flakes using builtins.getFlake
The issue I’m seeing is that packages pulled from the flake are sometimes not updated correctly when I run: sudo nixos-rebuild switch --upgrade -I nixos-config=/home/myuser/.dotfiles/nixos-config/configuration.nix
Strangely, running nixos-rebuild a second time seems to always update the package to the latest version. This package has been automatically updated in the past, which makes the behavior even more confusing.
My understanding is that --upgrade only updates channels. Because of that, I’m struggling to explain the behavior I’m seeing.
Since this is not a flake-based configuration, I don’t have a flake.lock file and therefore cannot use nix flake update . My expectation was that builtins.getFlake would resolve and update independently of channel updates, but that doesn’t seem to match what I’m observing.
One theory is that a channel update (when pointer change occurs) somehow causes Nix to refresh whatever cached information is associated with builtins.getFlake.
That would explain why the package appeared to update automatically in the past.
However, it doesn’t explain why the package now seems to require a second nixos-rebuild before the update is picked up, nor why --upgrade appears to influence the result at all.
Here’s my setup hopefully that illustrates how things are configured
Setup
configuration.nix
{
config,
lib,
pkgs,
…
}:
{
imports = \[
...
./users.nix
\];
...
nix.settings.experimental-features = \[
“nix-command”
“flakes” # default registry https://github.com/NixOS/flake-registry/blob/cb70c9306b44501de412649c356dee503a25f119/flake-registry.json
\];
...
users.nix
{
config,
lib,
pkgs,
...
}:
let
home-manager = builtins.fetchTarball https://github.com/nix-community/home-manager/archive/release-25.11.tar.gz;
in
{
imports =
[
(import "${home-manager}/nixos")
];
# Define a user account. Don't forget to set a password with ‘passwd’.
users.users.myuser = {
isNormalUser = true;
extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
};
home-manager.users.myuser = import ./users/myuser.nix;
}
myuser.nix
{ pkgs, ... }:
{
imports = [
./manga.nix
];
...
home.stateVersion = "25.11";
}
manga.nix
{ pkgs, ... }:
let
moku = builtins.getFlake "github:moku-project/Moku";
in
{
# WEBKIT_DISABLE_DMABUF_RENDERER
home.packages = [
moku.packages.${builtins.currentSystem}.default
];
}
Part of my confusion is that I could have imported the application using builtins.fetchTarball instead of builtins.getFlake . In both cases there is no local lock file, so I’m trying to understand what determines when Nix refreshes the remote source.
When using:
builtins.getFlake "github:moku-project/Moku"
with no explicit revision, tag, or lock file:
- When is the GitHub repository re-fetched?
- Is there a cache TTL involved?
- Is there a way to force a refresh?
- Should
nixos-rebuild --upgradehave any effect on this process?
Am I misunderstanding how builtins.getFlake is expected to behave in a non-flake configuration?