khaneliman

managing-flakes

@khaneliman/managing-flakes
khaneliman
302
14 forks
Updated 1/18/2026
View on GitHub

Manages Nix flakes, inputs, dependency resolution, and performance optimization. Use when working with flake.nix, updating inputs, debugging evaluation errors, optimizing flake performance, or composing multi-flake architectures.

Installation

$skills install @khaneliman/managing-flakes
Claude Code
Cursor
Copilot
Codex
Antigravity

Details

Pathmodules/common/ai-tools/skills/nix/managing-flakes/SKILL.md
Branchmain
Scoped Name@khaneliman/managing-flakes

Usage

After installing, this skill will be available to your AI coding assistant.

Verify installation:

skills list

Skill Instructions


name: managing-flakes description: Manages Nix flakes, inputs, dependency resolution, and performance optimization. Use when working with flake.nix, updating inputs, debugging evaluation errors, optimizing flake performance, or composing multi-flake architectures.

Managing Flakes

Flake Schema & Evaluation

Master the Nix flake schema, evaluation mechanics, and advanced patterns.

Evaluation Phases

  1. Input resolution: Lock file generation (flake.lock)
  2. System parameters: Flake function evaluation
  3. Output construction: packages, apps, devShells
  4. Lazy boundaries: Only evaluate what is requested

Common Outputs

  • packages.${system}.default: Main package
  • devShells.${system}.default: Development environment
  • nixosConfigurations.${hostname}: System config
  • apps.${system}.default: Runnable applications

Composition Patterns

Multi-Flake Architecture

  • Separation of concerns: Split monolithic flakes into logical components
  • Shared configuration: Use centralized flakes for common settings
  • Inheritance: Pass inputs from parent to child flakes

Modular Design

  • Components: Break flakes into modules/
  • Reusability: Export reusable functions in lib output
  • Extension: Use generic flake inputs for plugins

Common Tasks

Task 1: Update a single input

# Update specific input
nix flake update nixpkgs

# Or update all inputs
nix flake update

Task 2: Add a new input

# In flake.nix
inputs = {
  nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";

  # Add new input
  new-input = {
    url = "github:owner/repo";
    inputs.nixpkgs.follows = "nixpkgs";  # Deduplicate nixpkgs
  };
};

Why follows?: Prevents multiple nixpkgs versions in closure, speeds up evaluation.

Task 3: Use a local development flake

# Point to local directory during development
nix registry add my-flake path:/home/user/my-flake

# Now can reference without full path
nix shell my-flake#package

Task 4: Debug slow evaluation

# Show evaluation trace
nix eval .#nixosConfigurations.<host>.config --show-trace

# Profile evaluation
NIX_SHOW_STATS=1 nix eval .#nixosConfigurations.<host>.config

# Look for:
# - Large imports (can these be lazy-loaded?)
# - Repeated nixpkgs imports (use follows?)
# - Unnecessary full-package-set evaluations

Input Management & Follows

Input Management Decision Tree

Adding a new dependency:

  1. Is it in nixpkgs already?

    • Yes → No new input needed, just reference pkgs.package-name
    • No → Continue to step 2
  2. Does it depend on nixpkgs?

    • Yes → Add inputs.nixpkgs.follows = "nixpkgs" to deduplicate
    • No → Skip follows
  3. Is it from GitHub?

    • Yes → Use github:owner/repo (faster, cached)
    • No → Use appropriate URI scheme (git+ssh, path, file)
  4. Is this for development only?

    • Yes → Consider registry instead of hard input
    • No → Add as regular input

Example: Adding home-manager

inputs = {
  nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";

  home-manager = {
    url = "github:nix-community/home-manager";
    inputs.nixpkgs.follows = "nixpkgs";  # Step 2: Deduplicate
  };
};

Optimization

  • Deduplication: Use inputs.<name>.follows to share dependencies
  • Circular dependencies: Avoid loops in follows chains
  • Registry: Map local flakes for development (nix registry add)

URI Schemes

  • github:owner/repo: GitHub repository
  • git+ssh://...: Private Git repository
  • path:.: Local directory (requires absolute path or git tracking)
  • file:///...: Local file system (no git requirement)

Performance Optimization

Best Practices

  • Laziness: Avoid import of unused large files
  • Filtering: Use nix-filter or lib.cleanSource to reduce context
  • Caching: Utilize eval-cache where possible
  • Profiling: Use nix build --show-trace to find bottlenecks

Anti-Patterns

  • Eagerly evaluating full package sets
  • Importing nixpkgs multiple times without follows
  • Checking in massive flake.lock files generated by poor input management

See Also

  • Validation: See validating-nix for debugging evaluation errors and build failures