com um clique
nix
Expert guidance on Nix, NixOS, and home-manager best practices. USE WHEN working with Nix expressions, NixOS configuration, home-manager, flakes, or Nix package development.
Menu
Expert guidance on Nix, NixOS, and home-manager best practices. USE WHEN working with Nix expressions, NixOS configuration, home-manager, flakes, or Nix package development.
| name | Nix |
| description | Expert guidance on Nix, NixOS, and home-manager best practices. USE WHEN working with Nix expressions, NixOS configuration, home-manager, flakes, or Nix package development. |
Expert guidance on Nix, NixOS, and home-manager following best practices.
This skill activates when:
flake.nix, default.nix, shell.nix, or configuration.nix.nix filesnix build, nixos-rebuild, or home-manager are mentionedWhen the user's request matches specific Nix operations, route to the appropriate workflow:
| Workflow | Trigger | File |
|---|---|---|
| Build | "build nix package", "nixos-rebuild build", "compile nix" | workflows/Build.md |
| Debug | "debug nix", "nix error", "troubleshoot build", "evaluation error" | workflows/Debug.md |
| Develop | "development shell", "nix develop", "devShell", "direnv" | workflows/Develop.md |
| Deploy | "deploy nixos", "nixos-rebuild switch", "remote deployment" | workflows/Deploy.md |
| Package | "create package", "nix derivation", "buildGoModule", "package app" | workflows/Package.md |
| Flakes | "create flake", "flake.lock", "update inputs", "flake outputs" | workflows/Flakes.md |
| Secrets | "manage secrets", "agenix", "encrypt secrets", "age encryption" | workflows/Secrets.md |
| Security | "harden nixos", "apparmor", "firewall", "security hardening" | workflows/Security.md |
| Troubleshoot | "hash mismatch", "nix failing", "common errors", "fix nix issue" | workflows/Troubleshoot.md |
When to use workflows:
# Good: Declarative
services.nginx.enable = true;
# Bad: Imperative
systemd.services.nginx.postStart = "systemctl start nginx";
Same inputs = Same outputs
Break configurations into focused, reusable modules
# Good: Modular
imports = [
./hardware.nix
./networking.nix
./services.nix
];
# Bad: Everything in one file
Flakes provide:
# systems/<hostname>/
├── boot.nix # Bootloader, initrd, kernel modules
├── hardware.nix # Hardware settings, filesystems, mounts
├── extra.nix # Optional: additional host-specific config
└── home.nix # Optional: host-specific home-manager config
# In flake.nix
nixosConfigurations = {
hostname = libx.mkHost {
hostname = "hostname";
system = "x86_64-linux";
hardwareType = "desktop"; # or "rpi4"
desktop = "sway"; # or "niri", or null
nixpkgs = nixpkgs; # or nixpkgs-25_05 for stable
};
};
systems/common/
├── base/ # Essential base configuration
├── desktop/ # Desktop environment configs
├── hardware/ # Hardware-specific modules
├── programs/ # Application configurations
├── services/ # System services
└── users/ # User account definitions
Always check globals.nix for:
{ config, lib, pkgs, ... }:
{
options = {
services.myservice = {
enable = lib.mkEnableOption "my service";
port = lib.mkOption {
type = lib.types.port;
default = 8080;
description = "Port to listen on";
};
configFile = lib.mkOption {
type = lib.types.path;
description = "Path to configuration file";
};
};
};
config = lib.mkIf config.services.myservice.enable {
# Implementation
};
}
Common types:
types.bool - Boolean valuestypes.int - Integerstypes.str - Stringstypes.path - File system pathstypes.port - Network ports (1-65535)types.listOf types.str - Liststypes.attrs - Attribute setstypes.package - Nix packages# Conditional configuration
config = lib.mkIf config.services.myservice.enable {
# ...
};
# Merge multiple configurations
config = lib.mkMerge [
{ always.present = true; }
(lib.mkIf condition { conditional.value = true; })
];
# Provide defaults that can be overridden
services.myservice.port = lib.mkDefault 8080;
# In pkgs/default.nix
{
mypackage = pkgs.callPackage ./mypackage { };
mytool = pkgs.callPackage ./mytool { };
}
# pkgs/mypackage/default.nix
{ lib
, stdenv
, fetchFromGitHub
, buildGoModule # or rustPlatform, python3Packages, etc.
}:
buildGoModule rec {
pname = "mypackage";
version = "1.0.0";
src = fetchFromGitHub {
owner = "owner";
repo = "repo";
rev = "v${version}";
hash = "sha256-...";
};
vendorHash = "sha256-...";
meta = with lib; {
description = "Package description";
homepage = "https://example.com";
license = licenses.mit;
maintainers = with maintainers; [ ];
platforms = platforms.linux;
};
}
# overlays/default.nix
{ inputs }:
{
additions = final: _prev: import ../pkgs { pkgs = final; };
modifications = final: prev: {
# Override existing packages
somepackage = prev.somepackage.overrideAttrs (old: {
version = "custom";
});
};
}
# Lock dependencies
nix flake lock
# Update all inputs
nix flake update
# Update specific input
nix flake update nixpkgs
# Check flake validity
nix flake check
# Show flake outputs
nix flake show
# Show flake metadata
nix flake metadata
{
description = "Flake description";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
};
outputs = { self, nixpkgs }: {
nixosConfigurations = { ... };
homeConfigurations = { ... };
packages = { ... };
devShells = { ... };
};
}
home.sessionVariables = {
EDITOR = "vim";
VISUAL = "vim";
BROWSER = "firefox";
};
# Symlink static files
xdg.configFile."myapp/config.yml".source = ./myapp-config.yml;
# Generate files dynamically
xdg.configFile."myapp/generated.conf".text = ''
setting1 = ${someValue}
setting2 = value2
'';
# Make executable
xdg.configFile."bin/script.sh" = {
source = ./script.sh;
executable = true;
};
# User-level systemd service
systemd.user.services.myservice = {
Unit = {
Description = "My Service";
After = [ "network.target" ];
};
Service = {
ExecStart = "${pkgs.mypackage}/bin/myservice";
Restart = "on-failure";
};
Install = {
WantedBy = [ "default.target" ];
};
};
# secrets.nix
let
user = "ssh-ed25519 AAAAC3...";
system = "ssh-ed25519 AAAAC3...";
in {
"secret.age".publicKeys = [ user system ];
}
{
age.secrets.mySecret = {
file = ../secrets/mySecret.age;
owner = "myuser";
group = "mygroup";
};
# Reference in config
services.myservice.passwordFile = config.age.secrets.mySecret.path;
}
# Encrypt a secret
agenix -e secrets/mySecret.age
# Re-key all secrets
agenix -r
# Build configuration
nixos-rebuild build --flake .#<hostname>
# Dry run (show what would change)
nixos-rebuild dry-build --flake .#<hostname>
# Test without adding to bootloader
nixos-rebuild test --flake .#<hostname>
# List generations
nixos-rebuild list-generations
# Rollback to previous generation
nixos-rebuild switch --rollback
# Switch to specific generation
nixos-rebuild switch --switch-generation <number>
nix-collect-garbage -dimports = [
./base.nix
] ++ lib.optionals (desktop != null) [
./desktop/${desktop}
];
# Simple
message = "Hello ${name}";
# Multi-line
config = ''
setting1 = ${value1}
setting2 = ${value2}
'';
# Escape $
script = ''
echo "Nix variable: ${nixVar}"
echo "Shell variable: ''${shellVar}"
'';
# Concatenation
all = list1 ++ list2;
# Filter
filtered = lib.filter (x: x > 5) list;
# Map
doubled = map (x: x * 2) list;
# Merge
merged = set1 // set2;
# Recursive merge
merged = lib.recursiveUpdate set1 set2;
# Filter attributes
filtered = lib.filterAttrs (n: v: v != null) attrs;
# Map attributes
mapped = lib.mapAttrs (n: v: v * 2) attrs;
# Use lib.traceVal for debugging
value = lib.traceVal someExpression;
# Trace with message
value = lib.traceValSeq "message" someExpression;
# Evaluate Nix expression
nix eval .#nixosConfigurations.hostname.config.services.nginx.enable
# Show derivation
nix show-derivation .#package
# Inspect store path
nix path-info .#package
# Update hash for fetchFromGitHub
nix-prefetch-github owner repo --rev <commit-hash>
# Update vendor hash for Go modules
# Set vendorHash = lib.fakeSha256;
# Build will fail with correct hash
lib.mkIf to break cyclesnix-direnv for development shellsimportbuiltins wiselyNixOS provides unique security advantages through its declarative model and immutable store, but requires active hardening for production systems.
{
# 1. Enable firewall (default deny)
networking.firewall.enable = true;
# 2. Harden SSH
services.openssh.settings = {
PermitRootLogin = "no";
PasswordAuthentication = false;
};
# 3. Automatic security updates
system.autoUpgrade = {
enable = true;
allowReboot = false;
};
# 4. Enable AppArmor
security.apparmor.enable = true;
# 5. Use encrypted secrets
age.secrets.mySecret.file = ../secrets/mySecret.age;
}
For security-critical systems, use the hardened profile:
imports = [
<nixpkgs/nixos/modules/profiles/hardened.nix>
];
See workflows/Security.md for comprehensive hardening guidance.
/systems/<hostname> with boot.nix, hardware.nixflake.nix using libx.mkHostglobals.nix with machine metadatasecrets.nix if using secrets/pkgs/<package-name>/default.nix/pkgs/default.nix with callPackagenix build .#<package-name>make switchmake fmtmake cleanmake host/<hostname>/switch (ask first!)Remember: Nix is about reproducibility and declarative configuration. When in doubt, consult the manuals and follow the patterns established in the repository.
Example 1: Creating a Nix package
User: "Package this Go application for Nix"
→ Creates derivation with buildGoModule
→ Adds proper vendorHash for dependencies
→ Includes meta attributes (description, license, etc.)
→ Tests build with nix-build
→ Adds to home-manager or NixOS configuration
→ Result: Application properly packaged for Nix
Example 2: Debugging Nix build issues
User: "My Nix build is failing, can you help?"
→ Reviews error message from nix-build
→ Checks for common issues (missing dependencies, wrong hash)
→ Uses nix-shell for interactive debugging
→ Tests fix incrementally
→ Updates derivation with correct values
→ Result: Build succeeds, issue resolved
Example 3: Using Nix flakes
User: "Convert this to use flakes"
→ Creates flake.nix with inputs and outputs
→ Migrates configuration to flake structure
→ Updates flake.lock with nix flake update
→ Tests with nix build or nix develop
→ Documents flake usage in README
→ Result: Modern Nix flake structure