atvari-eu/nix-skills

nix-flake

Set up a reproducible Nix development environment for any Git repository — create a flake.nix with a devshell so nix develop provides the project's toolchain (cargo/clippy, go/gopls, python/pytest/black, node, ...) without global installs, fix a missing or…

Ver código fuente

Cómo usar

  1. Copia el comando y revisa el paquete antes de instalarlo en tu entorno de agente.
  2. Consulta las herramientas, credenciales y entornos necesarios en el documento original.
  3. Describe las entradas y el resultado deseado; contrasta la salida con las fuentes.
npx skills add https://github.com/atvari-eu/nix-skills --skill nix-flake

Antes de empezar

  • La instalación no incluye suscripción al modelo, cuota API ni permisos sobre tus archivos.
  • Las estrellas e instalaciones reflejan actividad, no una prueba independiente de calidad o seguridad.
Documento original del Skill

Contenido del repositorio de origen con títulos, ejemplos, código, tablas, enlaces e imágenes preservados.

Nix Flake

Every repository an agent works in should have a flake.nix. It gives you — and any human or agent that comes after you — a one-command, reproducible toolchain: nix develop drops into a shell with the project's compiler, package manager, and linters, independent of whatever happens to be installed on the host.

This skill covers two things: noticing when a repo is missing its flake.nix, and writing a good one. The template below is the official default since August 2026 (NixOS/templates#103), explained in depth by Nixcademy.

Checking for a flake

When you start working in a Git repository, check whether a flake.nix already exists at the repo root:

bash
test -f "$(git rev-parse --show-toplevel)/flake.nix"
  • If it exists, carry on with the user's task. Nothing to do here.

(Exception: if it uses flake-utils, you may offer a migration — see Migrating away from flake-utils.)

  • If it is missing, offer to add one as part of your work: a single

sentence like "This repo has no flake.nix — want me to add one with a dev shell for <detected stack>?" Then continue with what the user actually asked. Do not silently create files in someone else's project, but do not nag either: if they decline, drop it and move on.

  • Ask which toolchain belongs in the dev shell only if the project type is

genuinely ambiguous. Usually marker files tell you everything (see below).

Skip the offer entirely for checkouts that aren't the user's own work (e.g. vendored dependencies) or repos where Nix clearly isn't wanted.

The template

Write the flake.nix directly from this skeleton instead of running nix flake init: standard Nix now produces exactly this shape, but other distributions (e.g. Determinate) ship different templates, and you would have to rewrite the result anyway.

nix
# file: flake.nix
{
  description = "<project> development environment";

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

  outputs = inputs: {
    # Enter with `nix develop`
    devShells = builtins.mapAttrs (system: pkgs: {

      default = pkgs.mkShell {
        packages = [
          pkgs.git
          # ... toolchain picked from the table below
        ];
      };

    }) inputs.nixpkgs.legacyPackages;
  };
}

Buildable packages follow the same pattern:

nix
    # Build with `nix build`
    packages = builtins.mapAttrs (system: pkgs: {

      my-tool = pkgs.callPackage ./my-tool.nix { };
      default = inputs.self.packages.${system}.my-tool;

    }) inputs.nixpkgs.legacyPackages;

Why this pattern and not flake-utils

Do not use flake-utils, eachDefaultSystem, or hand-written system lists:

  • builtins.mapAttrs over inputs.nixpkgs.legacyPackages walks every

platform nixpkgs supports, so the flake automatically gains or loses platforms together with nixpkgs — no hardcoded list to go stale.

  • Every extra input inflates the flake.lock of your flake and of every

flake that depends on it. Projects commonly end up pinning dozens of redundant copies of flake-utils; zero inputs beyond nixpkgs avoids that entirely.

  • legacyPackages reuses the pkgs instance the nixpkgs flake already

built, so evaluation stays fast even in larger dependency trees. The name only means "not subject to the flat flake output schema" — the packages are current.

direnv integration

If the repo has no .envrc, add one next to the flake so direnv users get the dev shell automatically on cd:

bash
# file: .envrc
use flake
dotenv

Leave an existing .envrc alone (offer switching legacy use nix lines to use flake while you're at it).

Tailoring the dev shell

Pick the toolchain from marker files at the repo root, then read the README if nothing matches:

MarkerPackages
Cargo.tomlrustc cargo clippy rustfmt rust-analyzer
go.modgo gotools gopls
package.jsonnodejs, plus pnpm/yarn/bun matching the lockfile
pyproject.toml/requirements.txtpython3 uv
*.csproj/*.slndotnet-sdk
mix.exselixir
composer.jsonphp composer
Gemfileruby

Always include git — the repo is a Git checkout. Add linters/formatters the project configures (e.g. ruff, prettier, golangci-lint) and native libraries that build scripts expect.

Language-specific notes:

  • Rust: nixpkgs' rustc/cargo are fine to start. If the repo pins an

exact toolchain via rust-toolchain.toml and builds fail over version mismatch, reach for the community rust-overlay input rather than fighting nixpkgs — that's a real need, unlike platform enumeration.

  • Python: pip cannot install into nixpkgs' Python directly. Prefer uv

in the shell (uv venv && uv sync) so dependency management stays with the project's lockfile. For a Python package from nixpkgs to be importable, wire it via python3.withPackages instead of listing it side-by-side.

  • If a shell.nix or default.nix already exists, port its packages and

envvars into the flake's dev shell instead of inventing a parallel set, and leave the old file in place unless the user asks to remove it.

If nixos-unstable currently breaks one of the toolchains you need (this happens regularly on staging transitions), pinning to the latest stable release branch (nixos-25.05) is the right call — say so in a brief comment in the flake so readers know why.

Adding packages

For projects that should also expose a buildable package, put the derivation in its own file and wire it up with callPackage inside the mapAttrs block, as shown above. If your package must be visible inside pkgs (because it overrides an existing package or other packages depend on it), extend pkgs with an overlay instead:

nix
packages = builtins.mapAttrs (
  system: pkgs':
  let
    pkgs = pkgs'.extend (final: prev: {
      my-tool = final.callPackage ./my-tool.nix { };
    });
  in
  {
    inherit (pkgs) my-tool;
    default = pkgs.my-tool;
  }
) inputs.nixpkgs.legacyPackages;

A side effect of the overlay route: the package also becomes available through variants like pkgs.pkgsStatic and pkgs.pkgsCross.

Custom nixpkgs configuration

legacyPackages uses nixpkgs' default configuration. When you need allowUnfree, CUDA support, or baked-in overlays, instantiate nixpkgs per selected system yourself with this 5-line helper — still no extra inputs:

nix
outputs =
  inputs:
  let
    systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" ];

    eachSystem =
      systems: f:
      builtins.foldl' (
        a: s: a // builtins.mapAttrs (k: v: (a.${k} or { }) // { ${s} = v; }) (f s)
      ) { } systems;
  in
  eachSystem systems (
    system:
    let
      pkgs = import inputs.nixpkgs {
        inherit system;
        config.allowUnfree = true;
      };
    in
    {
      packages.default = pkgs.hello;
      devShells.default = pkgs.mkShell {
        inputsFrom = [ inputs.self.packages.${system}.default ];
      };
    }
  );

Decision guide:

  1. Default case → mapAttrs over legacyPackages.
  2. Package must live inside pkgs → pkgs.extend overlay.
  3. Custom nixpkgs config needed → eachSystem helper above.
  4. Reach for flake-parts only if you actually use its features, never just

for platform enumeration.

Verification

Never hand back an unverified flake:

  1. Parse: nix-instantiate --parse flake.nix
  2. Evaluate: nix flake show (lists all outputs across systems)
  3. Enter: nix develop --command true, or better, run the project's own

build/test command through it: nix develop --command cargo build

  1. Show the user what was added (git status); do not commit unless asked.

If the repo's README documents setup steps, a one-line pointer to nix develop is usually appreciated — ask or mention it, don't silently rewrite docs.

Migrating away from flake-utils

If an existing flake uses flake-utils.lib.eachDefaultSystem or similar:

  1. Replace the helper with builtins.mapAttrs ... inputs.nixpkgs.legacyPackages,

keeping the body of the callback unchanged.

  1. Delete the flake-utils input from inputs.
  2. Run nix flake lock and confirm flake-utils no longer appears in

flake.lock.

  1. Re-verify per the checklist above — output paths stay identical

(.#packages.<system>.<name>), so nothing downstream breaks.

Relacionados por tarea

del mismo repositorio

Más Skills

Todos los Skills
atvari-eu
Comunidad

find-skills

Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill. Also handles managing existing installs — use it whenever the user wants to update, upgrade, refresh, reinstall, or remove already-installed skills ("update my skills", "upgrade the pdf skill", "i

instalaciones
2
GitHub Stars
0
Actualizado
26 ago
atvari-eu
Comunidad

nix-hash

Handles SRI (Subresource Integrity) hashes for Nix, including converting between hash formats (SRI, hex, base32), computing hashes of files and strings, using nix hash commands, and working with fixed-output derivations. Use this skill whenever the user mentions nix hashes, SRI hashes, hash conversion, hash prefetching, fixed-output derivations, fetchFromGitHub hashes, fetchurl hashes, or any task involving Nix hash manipulation.

instalaciones
2
GitHub Stars
0
Actualizado
26 ago
atvari-eu
Comunidad

nix-init

Generates Nix packages from repository URLs using nix-init — hash prefetching, dependency inference, and license detection included. Use this skill whenever the user wants to package a GitHub/GitLab/Gitea repo for Nix, add a tool or library that is missing from nixpkgs to their flake or home-manager config, prepare a pkgs/by-name contribution, or mentions nix-init directly. Also use it when asked to "package X for Nix", "create a derivation from this URL", "add this repo as a Nix package", or to

instalaciones
2
GitHub Stars
0
Actualizado
26 ago
atvari-eu
Comunidad

terranix

Write OpenTofu/Terraform infrastructure-as-code in Nix with terranix instead of hand-writing HCL — scaffold a terranix project (flake + config.nix), convert existing .tf HCL files to terranix, fix ${} interpolation clashes between Nix and Terraform ("undefined variable 'var'" / "variable not found" errors), wire up tofu workflows that consume generated config.tf.json, manage secrets via TFVAR and sensitive variables, or verify a terranix setup with tofu init/validate. Use whenever the user menti

instalaciones
2
GitHub Stars
0
Actualizado
26 ago