搜索

PythonReactSEOPDF
GitHub Skill

nix-guidelines

Use when writing Nix code for flakes, modules, or packages

trash-panda-v91-beta☆ 1 仓库 Stars0 仓库 Forks

安装与使用

请根据来源仓库和你的 AI 工具说明安装此技能。先阅读技能文件和依赖要求,再添加到工作流。

查看来源 ↗使用指南

技能说明

Nix Guidelines

Guidelines for idiomatic Nix code with flakes and modules.

When to Use

  • Writing flake.nix files
  • Creating NixOS/Home Manager modules
  • Writing Nix packages
  • Reviewing Nix code
  • Fixing "attribute not found" errors
  • Debugging infinite recursion issues

When NOT to Use

  • Bash scripting (use writeShellApplication)
  • Runtime configuration (use normal config files)
  • Non-reproducible workflows

Critical Rule: No with Statements

NEVER use with statements. They:

  • Break static analysis tools (nixd, nil)
  • Create scope ambiguity
  • Cripple IDE features
# ❌ WRONG
environment.systemPackages = with pkgs; [ git vim ];
meta = with lib; { license = licenses.mit; };

# ✅ CORRECT
environment.systemPackages = [ pkgs.git pkgs.vim ];
meta = { license = lib.licenses.mit; };

Core Principles

  1. Explicit over Implicit - Always use explicit attribute paths
  2. Declarative Design - Think in systems, not scripts
  3. Pure Functions - Leverage Nix's functional nature
  4. nixfmt-rfc-style - Standard formatter

Flake Structure

{
  description = "My project";

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

  outputs = { self, nixpkgs, home-manager, ... }: {
    nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        ./configuration.nix
        home-manager.nixosModules.home-manager
      ];
    };
  };
}

Module Structure

{
  lib,
  config,
  pkgs,
  ...
}:
let
  cfg = config.myNamespace.myModule;
in
{
  options.myNamespace.myModule = {
    enable = lib.mkEnableOption "my module";

    package = lib.mkOption {
      type = lib.types.package;
      default = pkgs.myPackage;
      description = "The package to use";
    };

    settings = lib.mkOption {
      type = lib.types.attrsOf lib.types.str;
      default = { };
      description = "Configuration settings";
    };
  };

  config = lib.mkIf cfg.enable {
    environment.systemPackages = [ cfg.package ];

    assertions = [
      {
        assertion = cfg.settings != { };
        message = "myModule.settings cannot be empty when enabled";
      }
    ];
  };
}

Best Practices Checklist

  • No with statements
  • Explicit destructuring in function signatures
  • nixfmt-rfc-style formatting
  • Options properly namespaced
  • Input follows optimized (for flakes)
  • Prefer let-in over rec
  • lib.mkIf for conditional config
  • Assertions for validation
  • Comments for complex logic

Common Patterns

Conditional Configuration
config = lib.mkMerge [
  (lib.mkIf cfg.enable {
    services.myService.enable = true;
  })

  (lib.mkIf (cfg.enable && cfg.monitoring.enable) {
    services.prometheus.exporters.myService.enable = true;
  })

  {
    # Always applied with lower priority
    services.myService.port = lib.mkDefault 8080;
  }
];
Package Definition
{ lib, stdenv, fetchurl, openssl }:
stdenv.mkDerivation {
  pname = "mypackage";
  version = "1.0";

  src = fetchurl {
    url = "https://example.com/source.tar.gz";
    sha256 = lib.fakeSha256;
  };

  buildInputs = [ openssl ];

  meta = {
    description = "My package";
    license = lib.licenses.mit;
  };
}
Script Wrapper
pkgs.writeShellApplication {
  name = "my-script";
  runtimeInputs = [ pkgs.jq pkgs.curl ];
  text = ''
    curl -s https://api.example.com | jq .
  '';
}

Anti-Patterns to Avoid

Don't Use rec
# ❌ Avoid rec
rec {
  a = 1;
  b = a + 1;
}

# ✅ Use let-in
let
  a = 1;
in {
  inherit a;
  b = a + 1;
}
Explicit Destructuring
# ❌ Wrong
args: with args; stdenv.mkDerivation { ... }

# ✅ Correct
{ stdenv, fetchurl, lib }: stdenv.mkDerivation { ... }

Performance Tips

  • Use inputs.nixpkgs.follows to deduplicate inputs
  • Split outputs for granular dependencies
  • Profile with NIX_SHOW_STATS=1 nix build
  • Consider builtins.readFile for large strings

Validation Commands

# Check flake
nix flake check

# Format code
nixfmt-rfc-style .

# Evaluate without building
nix eval .#packages.x86_64-linux.default

# Show flake outputs
nix flake show

Quick Reference

Type Syntax Purpose
Bool lib.types.bool Boolean value
String lib.types.str Text value
Package lib.types.package Nix package
List lib.types.listOf type Homogeneous list
AttrSet lib.types.attrsOf type Key-value pairs
Optional lib.types.nullOr type Nullable type

Common Errors

Error Cause Fix
"infinite recursion" Circular dependency in rec Use let-in instead
"attribute not found" Typo or missing import Check spelling, add to inputs
"cannot coerce to string" Wrong type Explicitly convert with toString
"with is a bad pattern" Using with statement Use explicit paths

Remember

Minor verbosity from explicit patterns is a feature - it makes code self-documenting and machine-readable.

使用示例

查看来源仓库中的使用示例与配置说明。

查看来源 ↗

来源历史

收录时间
2026-01-20
索引更新时间
2026-01-26
Branch
main

收录与同步日期属于本站记录。源码修改历史请查看来源仓库。

GitHub ↗

chat Comments (0)

chat_bubble_outline

No comments yet. Be the first to share your thoughts!