← Back to list
name: writing-nix
description: Writes idiomatic, performant, and maintainable Nix code. Covers best practices, anti-patterns to avoid (like
1. The
2. Recursive Attributes (

writing-nix
by khaneliman
Nix configuration for my systems supporting macOS, NixOS, and WSL.
⭐ 303🍴 14📅 Jan 23, 2026
SKILL.md
name: writing-nix
description: Writes idiomatic, performant, and maintainable Nix code. Covers best practices, anti-patterns to avoid (like with), module system design, and performance optimization.
Writing Nix
Core Principles
- Declarative over Imperative: Describe what, not how.
- Explicit over Implicit: Avoid magic scoping or hidden dependencies.
- Hermetic: No side effects, no network access during build (except fixed-output derivations).
Critical Anti-Patterns
1. The with Statement
NEVER use with. It breaks static analysis, tools (LSP), and readability.
# BAD
meta = with lib; { license = licenses.mit; };
# GOOD
meta = { license = lib.licenses.mit; };
2. Recursive Attributes (rec)
Avoid rec when let-in suffices. rec can cause infinite recursion and
expensive evaluation.
# BAD
rec {
version = "1.0";
name = "pkg-${version}";
}
# GOOD
let
version = "1.0";
in {
inherit version;
name = "pkg-${version}";
}
Module System
Standard Pattern
All modules must follow this structure:
{ config, lib, pkgs, ... }:
let
cfg = config.khanelinix.path.to.module;
inherit (lib) mkIf mkEnableOption mkOption types;
in {
options.khanelinix.path.to.module = {
enable = mkEnableOption "module description";
# Other options...
};
config = mkIf cfg.enable {
# Configuration implementation
};
}
Option Design
- Namespacing: Always prefix with
khanelinix.. - Types: Use strict types (
types.bool,types.str,types.listOf types.package). - Defaults: Use
mkDefaultfor overridable values.
Performance Optimization
Evaluation
- Laziness: Nix is lazy. Don't force evaluation of unused attributes.
- Imports: Avoid importing large files if only a small part is needed.
- Regex: Avoid expensive regex operations in hot loops.
Build
- Closure Size: Split outputs (
dev,doc,lib) to reduce runtime dependencies. - Filters: Use
lib.cleanSourceornix-filterto avoid rebuilding on irrelevant file changes (e.g., README updates).
Idiomatic Functions
Destructuring
Always destructure arguments in function headers.
# BAD
args: stdenv.mkDerivation { name = args.pname; ... }
# GOOD
{ stdenv, pname, version, ... }: stdenv.mkDerivation {
inherit pname version;
...
}
Overrides
override: Change function arguments (inputs).overrideAttrs: Change derivation attributes (steps, build inputs).
Formatting
- Use
nixfmt(ortreefmt). camelCasefor variables.kebab-casefor attributes/files.
See Also
- Validation: See validating-nix for checking syntax, formatting, and building code
- Module scaffolding: See ../../khanelinix/scaffolding-modules/ for creating new modules with proper structure
Score
Total Score
65/100
Based on repository quality metrics
✓SKILL.md
SKILL.mdファイルが含まれている
+20
○LICENSE
ライセンスが設定されている
0/10
○説明文
100文字以上の説明がある
0/10
✓人気
GitHub Stars 100以上
+5
✓最近の活動
1ヶ月以内に更新
+10
✓フォーク
10回以上フォークされている
+5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
✓タグ
1つ以上のタグが設定されている
+5
Reviews
💬
Reviews coming soon
