Deploying Packages
Deploy plain Nix packages to machines as user-level tools with the packages installable type.
The packages type deploys via nix profile add (nix profile install when Lix is detected), with no rollback and no activation script. It is ideal for standalone tools and editor configurations on machines that already have a system configuration; attrpath resolution and the activation/rollback skip are defined by the preset, see Output Types.
Packages are always user-level: set user to install into a specific user’s profile (activation runs via su -l <user> -c); when user is empty, the package installs as the SSH user. See Configuration Model for the canonical user field semantics.
Flake Setup
Section titled “Flake Setup”Export derivations under packages.<system>.<name>:
{ inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
outputs = { self, nixpkgs }: let systems = [ "x86_64-linux" "aarch64-linux" ]; forAllSystems = nixpkgs.lib.genAttrs systems; in { packages = forAllSystems (system: let pkgs = nixpkgs.legacyPackages.${system}; in { default = pkgs.hello; my-tool = pkgs.callPackage ./my-tool.nix { }; } ); };}The attribute name in your panix YAML must match packages.<system>.<name> in the flake.
Panix Configuration
Section titled “Panix Configuration”fleet: flakes: my-tools: url: path:../my-tools-flake
installables: packages: my-tool: # Must match packages.<system>.my-tool user: alice # Install into alice's nix profile machines: workstation: ssh: hostname: ws.lan username: root # SSH as root, activate as aliceA common pattern is deploying the system config as root and user tools as the target user, by defining both installable types under one flake. See Configuration Model for that layout.
Packages-specific nix flags (profile_add_default_flags, profile_add_env) follow the same inheritance and override semantics as other nix flags.
Deploying nixvim
Section titled “Deploying nixvim”nixvim configures Neovim declaratively and produces a wrapped derivation. It does not export a pre-built package, so evaluate your config and export the result from your flake’s packages output:
packages.${system}.default = nixvim.lib.nixvim.modules.buildNixvimWith { inherit system; modules = [{ plugins.treesitter.enable = true; }];};The panix YAML is the same as any packages installable. For module-based integration with generation rollback and XDG config management, deploy nixvim through a homeConfigurations installable using nixvim.homeModules.nixvim.
Deploying nvf
Section titled “Deploying nvf”nvf is the successor to neovim-flake. Evaluate configs via nvf.lib.neovimConfiguration and use .neovim as the package:
packages.${system}.default = (nvf.lib.neovimConfiguration { inherit pkgs; modules = [ ./nvf-config.nix ]; }).neovim;The panix YAML is identical to the nixvim case.
Deploying nix-maid
Section titled “Deploying nix-maid”nix-maid manages declarative dotfiles and systemd user units through a bundle activated via bin/activate (systemd-tmpfiles + sd-switch), rather than nix profile add. Build a bundle under a maidConfigurations output using its callable flake API:
maidConfigurations.my-config = nix-maid pkgs { file.home.".gitconfig".text = "[user]\n name = Example"; packages = [ pkgs.hello ];};fleet: flakes: my-infra: installables: maidConfigurations: my-config: user: myuser machines: workstation:Limitations
Section titled “Limitations”- No rollback for
packagesandmaidConfigurations: Panix rollback is skipped (no profile path). Forpackages, usenix profile historyandnix profile rollbackon the target machine directly. - No activation modes: both types activate immediately, no
switch,boot,test, ordry-activatemodes. - Profile conflicts (
packagesonly):nix profile adduses the user’s default profile. Useprofile_add_default_flags: ["--priority", "N"]to control priority.