How to update only a single app?

I sometimes have very low data for internet and I want to update just only one app. How to update just one one app?

I want to know in 2 different ways:

  1. Updating flake.lock and then updating selected app/apps

  2. Without updating flake.lock and just updating the selected app/apps to the latest input versions(basically to update inputs only once and not change flake.lock)

TL’DR: you can’t


You have to either copy the new package defintion from GH or do an equivalent override locally. Depending on the implementation of the drv, you have to instictively choose one over the other.

Details on how to actually use that package depend on some details, like does a module exist, and do you use it? Does this module have a package option? Do you use environment.systemPackages (or equivalent)? etc.

Often its not worth it, and you have to very likely build from source anyway.


An alternative method is to add another input that you use to install only this app from (and all of its dependencies, due to how nix works), and the usage still depends on the usage/installation details.

Most of the time, its easier to just wait for better internet or use a distro where partial updates are easily done (NixOS has the best but not the easiest support for them).


PS: I have a rather strict opinion about NixOS under bandwidth or diskspace constraints… In my opinion, its better to not use nix or related under those constraints, unless one knows how to deal with the imposed limitations before they become a problem.

1 Like

Thanks for the answer.
So the easiest possible way right now I could think of is,
To give a separate input for the flake for that particular app and run:

nix flake lock --update-input particular-pkgs

And then rebuild the system.

As said, that will also update all the dependencies in that applications closure. Depending on the application this can be nearly as heavy as updating the full system anyway…

1 Like

Makes sense. I wish there’s a way to do such individual package upgrades, so that nix can easy UX like other GUI package managers

This is not really different from others. pacman for example officially doesn’t support partial upgrades.

And if you downloaded a cached package before, but now you want to override the version, you’ll now be downloading the source + all the buildtime dependencies. This download can also be substantial.

If you want one way around this: set up a separate build server that has lots of bandwidth, build the override there.

But still, keep in mind that updating only one app will cause you to miss important security updates; IMO it’d be better to update the system once a week rather trying to piecemeal it.

Another option is the applyPatches function of nixpkgs: Nixpkgs/Patching Nixpkgs - NixOS Wiki

It saves you the trouble of figuring out the right override invocation (just give it the upgrade PR as patch), at the cost of writing another nixpkgs tree to the store. (And longer eval time.)

3 Likes

Interesting, I was not aware of that, I will definitely take a closer look, as it might come in handy for myself…

  1. If you update across a stdenv-rebuild, even installing the fresh build of a single application will require downloading the full closure.
  2. To update just one application, if you are OK with its closure but no more, I would recommend a completely separate way: look up the fresh build path on Hydra, then nix-store -r /nix/store/hash-path --add-root ~/fresh-package --indirect. Now you can just do ~/fresh-package/bin/application, and this will download the minimum required for the closure of the application.
  3. In general, Nix style of redownloading full paths even if the content is mostly identical is often suboptimal — but downloading a closure of a single application might still be smaller than a full update elsewhere (and partial updates are indeed flaky).
1 Like

Technically this is what you can do with nix run, nix shell, nix-shell and friends.
Aside: if you want to do yourself a favour, expose legacyPackages in your flake; import nixpkgs (or use its legacyPackages) like normal, slap all your overlays on top, and then use that in both your flake as the nixpkgs you are working with, as well as expose it under outputs.legacyPackages.
With the aside in mind (though there are other ways of doing this which may be more or less reliable depending on circumstance), you can do something like nix run /path/to/your/flake#some-application and it will run the application from the exact same flake inputs that are currently locked in your flake.lock.
You can then --refresh --no-write-lock-file --override-input nixpkgs github:NixOS/nixpkgs/nixos-unstable and use the same nix run command to pull exactly that one application from the newer nixpkgs. Note that this will pull the entire closure as others have mentioned before, however it will just pull that one application and its dependencies.

Edit: this will not integrate well into your existing system of course (you could do that by using two nixpkgs inputs and pulling the stuff you want from one to the other with an overlay, the way people pull nixos-unstable packages into stable for instance). However if you want to just use that one updated application for a bit, that’s a thing you can do. And hey, if you then rebuild your system with the same nixpkgs version it will properly reuse the pulled packages since they are already in your store, making this somewhat incremental.

Edit 2: if you want to really just update the application but not its dependencies you can use the usual overrideAttrs dance (didn’t find a better source for info on that on short notice), where you could .overrideAttrs { version = "1.2.3"; src = pkgs.fetchFromGitHubOrSomething {}; }, and updating hashes as needed, but that can get unwieldy very quick if you’re dealing with Rust or Go packages for instance, and the most important part; it requires the build time dependencies. If those aren’t already in your system (because you like having your favourite language around), then you will have to potentially pull a compiler, dev outputs of libraries, and all those, to build the changed application (assuming that nixpkgs did update the dependencies, otherwise why go this route instead of the above one, given that the difference in closure would be small anyway). And speaking from experience, pulling llvm is usually a bigger download than the rest of your dependencies.

Edit 2½: if you have any questions about any of the things I badly described in this post, feel free to ask. I’m happy to elaborate on specifics of that (it’s just that summing up the entire plethora of options without knowing which parts are useful to you is a bit difficult).

1 Like

Thanks for the reply👍. Makes sense.
And the easiest I could find is just giving a separate input in configuration. :smiling_face_with_tear:

Continuing the aside, but if you have highly constrained bandwidth one option is to trade off against cpu, and build everything from source. Often, packages are rebuilt several times because of changes in their dependency tree, when the package itself hasn’t changed - and neither has its source. Sometimes, those changes are also something else in nix that means even the changed dependency hasn’t updated its source. And, of course, source is small, compresses well, and can often be updated with just differences (e.g for nixpkgs itself).

Disk space is a different issue, but if you’re already building from source you can optimise that build specifically for the constrained hardware too.

So distributions like nixos (or gentoo, etc) that allow seamless building from source can actually be advantageous choices, in the generally fairly rare these days but not unheard-of circumstances where you have limited bandwidth as the primary constraint. Not great when everything is constrained, and this kind of customisation will be tricky to do reliably for any distribution in that case.

2 Likes