There's a short explanation in this section: https://nixos.org/manual/nixos/stable/#sec-option-types-submodule (look for specialArgs) and in this section: https://nixos.org/manual/nixpkgs/stable/#module-system-lib-evalModules-param-specialArgs. I don't know whether it's documented properly somewhere.
comments
Any sites you can link that explain the differences and how to use it?
I have experimented with something very similar in the past. I think the main issue is that it is quite confusing to read, being familiar with what the old <> syntax does.
BTW, you shouldn't really need extraSpecialArgs in most cases; setting a _module.args config option should be enough.
really fits the snowflake vibe too
extraSpecialArgs has real_escape_string energy
Sooo right. Trying to learn nix, flakes, and home-manager in parallel without realizing extraSpecialArgs exists isn't fun.
Skill issue, maybe, but it's an ergonomic issue too!
copes
I don't have an exact example to hand because I'm not using a custom substituter for now. I have a remnant of that in my config still, here: https://github.com/balsoft/nixos-config/blob/master/flake.nix#L5 . But it should be relatively straightforward: add nix.settings.trusted-substituters = [ "http://your-substituter/" ]; to your (client device) NixOS config (e.g. in configuration.nix); add nixConfig.extra-substituters = [ "http://your-substituter/" ]; to your config flake.nix; answer yes when prompted by nixos-rebuild, and you should be good.
As for remote builders, I don't really dig them myself. They require fully trusting all users who wish to build on them and are finicky to set up. Instead I just ssh into the build machine, build whatever I need there, and nix copy it back to my laptop. That said,
intent on modifying root ssh configs in spite of security practices
You can set up your nix-daemon to run as its own user nowadays, mitigating all issues related to root entirely.
botch use of substituters on the remote builder
Never had this issue so don't really know how to help
is awkward or incompatible with non-interactive sudo sessions
This one is pretty much unfixable due to how remote building works
works for nixos build but not to switch
You should probably use nixos-rebuild switch --use-remote-sudo and run it as your user rather than root.
Do you know of a complete example or live config I could read through as a reference for that first method recommended?
I'd also be interested in complete examples for a working pair of remote builder and local client (both NixOS multi user), as all the documentation I've come across thus far are either:
-
intent on modifying root ssh configs in spite of security practices
-
botch use of substituters on the remote builder
- causing needles recompilation, ignoring upstream cache.nix.org
-
is awkward or incompatible with non-interactive sudo sessions
-
works for nixos build but not to switch
-
https://nix.dev/manual/nix/2.30/advanced-topics/distributed-builds
-
https://discourse.nixos.org/t/nixos-rebuild-use-remote-sudo-prompts-me-for-a-password-3-times/56003
-
https://discourse.nixos.org/t/remote-nixos-rebuild-works-with-build-but-not-with-switch/34741
From the video notes, this alternative to nix-serve looks promising:
I think the current best solution to this is to add your substituter to trusted-substituters and then add it to the nixConfig.extra-substituters attribute of your system config flake (or do some NIX_CONFIG hackery in your .envrc if you're not using flakes). That way if that substituter dies, you can easily disable it (by removing it from your system flake) without rebuilding the configuration.
Oh, and BTW, Nix has a --fallback option that will rebuild locally if a substituter is not available, but that will make things painfully slow, better to use the method I previously mentioned.
There's work being done to make this possible in the future https://fzakaria.com/2025/03/10/an-early-look-at-nix-dynamic-derivations
Thanks for the answer!
Nix builds go through 2 phases, first downloading the dependencies into the nix store (which can also go through a nix build) and then executing the builder with access to the nix store but without network access. This is done for purity because network access can lead to non-reproducible builds.
Most languages and tools are complex but can output URLs to their depdencies or download them, but that cannot happen during the build (no network access). So, either a tool predownloads stuff and they can be put into the nix store by the "simple" nix derivation, or the tool (pip, docker compose, cargo,...) has to be rewritten either partially or completely in nix. The latter is much harder and in most cases would just lead to repeating the work. Nix may be a functional language but it's missing important language features like static typing.
This post exactly expresses my thoughts from some months ago. However, I wasn't motivated enough to actually post it. Thanks for reading in my mind and asking that for me, I appreciate it.
Could you say a bit more about that? I was actually wondering about the exact same thing as OPs question. Is the performance so bad that it doesn't even make sense to consider this as an option? Idk, just like OP I feel like it's such an obvious use case that it really should be a thing.
@6d03@rutrum more it's performance impact
@rutrum isn't it because of the fear of import from derivation?
Nix-ld is only used by unpatched executables that use the link loader at
/libor/lib64. If you use for example python from nixpkgs than it will not pick upNIX_LD_LIBRARY_PATHandNIX_LDsince these types of binaries are configured to use a glibc from the nix store.
Ah, I guess that's why I've seen folks recommend just having uv install the python interpreter as well, so everything python uses the same link loder from nix-ld.
you can also use:
require("nvim-treesitter.configs").setup({
ensure_installed = {
"foo",
"bar
},
})
in your neovim config if :TSInstall isn't good enough
Yep! What I wanted was for a "just works" experience as much as possible. Having to manually install lsps and treesitter parsers manually with nix felt like a bummer, honestly. It does work though
Mason doesn't really work with Neovim but you can use Treesitter and install parsers using with it. What I do is use programs.neovim.extraPackages = [] to install the language servers.
Will check it out. Thanks for the replies
Actually I think your right. I thought I required SteamLink to play on another machine. Thats on me for not checking properly! Will get back once I've tested it.
This is the correct way to configure Steam to use remote play, but OP is looking for how to install the Steam Link application, which can be installed separately from Steam. Its good for low power devices like a raspberry pi.