Automated summary
Interactive guide to building a Nix-based dotfiles repository from scratch, using a reference architecture.
Strengths
- Step-by-step interactive approach adapted to the detected environment
- Uses the official nixos-unified template for a standard base
- Covers Nix installation, system configuration, and adding modules
Limitations
- Requires basic familiarity with Nix and the terminal
- Does not cover advanced custom configurations or Nix flakes
- Can be time-consuming due to the activation step
When you want to set up your dotfiles with Nix for the first time.
If you already have a working Nix configuration and only need to add a single module.
Security analysis
SafeThe skill guides a user through creating Nix dotfiles using local template scripts and standard Nix commands. It does not instruct the execution of any destructive, exfiltrating, or obfuscated actions. The discovery script only gathers local environment information for configuration, and all generated code is transparent and user-reviewed. No external downloads or unsafe commands are invoked.
No concerns found
How this analysis is madeExamples
I want to set up my dotfiles using Nix from scratch. Use this repo as a reference architecture.Guide me through creating a nixos-unified dotfiles repository. I have a fresh Linux install.I'd like to move away from chezmoi to Nix for my dotfiles on macOS. Help me build a new repo.name: nix-dotfiles description: Guides a developer through building their own nixos-unified dotfiles repository from scratch, using this repo as a reference architecture. Use when someone wants to set up Nix-based system configuration or dotfiles management.
Build Your Own Nix Dotfiles
An interactive skill that guides you through building a nixos-unified dotfiles repository from scratch, using this repo as a reference architecture.
Environment Discovery
The following was detected automatically:
!`${CLAUDE_SKILL_DIR}/scripts/discover.sh`
Instructions
You are guiding a developer through creating their own Nix-based dotfiles from scratch. This repo (scotttrinh/dotfiles) is the reference — the user is NOT forking it, they are building their own.
Work through the phases below in order. Each phase is interactive: ask questions, run discovery commands, and generate files incrementally. Do not dump everything at once.
Use the discovery output above to pre-fill values and suggest sensible defaults throughout.
Phase 1: Confirm Discovery
Summarize the detected environment to the user. Confirm:
- OS and architecture
- Whether Nix is installed (if not, guide them to install it first via the Determinate installer)
- Username and hostname (these become file names in the config)
- What tools are already installed (to suggest modules later)
Phase 2: Identity Setup
Ask the user for:
- Full name — for git commits (e.g., "Jane Smith")
- Email — for git config (e.g., "jane@example.com")
- GitHub username — for the repository name
Store these for use in generated Nix code.
Phase 3: Bootstrap from Template
Use the official nixos-unified template to scaffold the repo. Pick the template based on the detected OS:
- macOS (Darwin):
macos - Linux (NixOS):
linux - Home-manager only (no system config):
home
Run the bootstrap script:
${CLAUDE_SKILL_DIR}/scripts/bootstrap.sh <template> <output-dir>
For example: ${CLAUDE_SKILL_DIR}/scripts/bootstrap.sh macos ~/dotfiles
After bootstrapping, the template provides the standard nixos-unified structure. Walk the user through the generated files and customize them:
configurations/home/<username>.nix— setme.username,me.fullname,me.emailfrom Phase 2configurations/darwin/<hostname>.nix(ornixos/) — setnixpkgs.hostPlatform,networking.hostName,system.primaryUsermodules/home/— review what the template provides, then enhance with modules from Phase 4
See templates.md for reference versions of each file if the template needs adjustment.
Have the user run nix run .#activate to verify the base config works before adding modules.
Phase 4: Incremental Module Interview
After the minimal config is working, walk through each category below one at a time. For each:
- Ask if the user wants it
- If yes, generate the module file(s)
- Explain what the module does
- Have them activate and verify
Use discovery results to suggest sensible defaults (e.g., if ghostty is installed, suggest configuring it).
Category: Packages
Common development packages. Ask what languages and tools they use.
# modules/home/packages.nix
{ pkgs, ... }:
{
home.packages = with pkgs; [
ripgrep
fd
tree
jq
less
];
programs = {
bat.enable = true;
fzf.enable = true;
jq.enable = true;
btop.enable = true;
};
}
Extend home.packages based on what the user needs:
- Node.js:
nodejs_24 corepack_24 - Python:
python312 uv - Rust: add
rust-overlayinput, thenrust-bin.stable.latest.default - Go:
go
Category: Direnv
Automatic environment loading for Nix projects. Strongly recommend this for any Nix user.
# modules/home/direnv.nix
{ ... }:
{
programs.direnv = {
enable = true;
enableZshIntegration = true;
nix-direnv.enable = true;
config.global.hide_env_diff = true;
};
}
Category: Editor
Ask which editor they use. Only generate the module for their choice.
Emacs:
# modules/home/emacs.nix
{ pkgs, ... }:
{
programs.emacs = {
enable = true;
extraPackages = epkgs: with epkgs; [
vterm
treesit-grammars.with-all-grammars
];
};
}
Neovim:
# modules/home/neovim.nix
{ pkgs, ... }:
{
programs.neovim = {
enable = true;
defaultEditor = true;
viAlias = true;
vimAlias = true;
};
}
VS Code / Cursor: These are typically installed via Homebrew casks on macOS. Add to the darwin module's homebrew.casks list rather than a home-manager module.
Category: Terminal
Ask which terminal they use. Terminals on macOS are typically Homebrew casks.
Ghostty (recommended — already a cask in reference config):
Add "ghostty" to homebrew.casks in modules/darwin/default.nix. Configuration lives at ~/.config/ghostty/config — optionally manage it via home.file.
Kitty:
# modules/home/kitty.nix
{ ... }:
{
programs.kitty = {
enable = true;
settings = {
font_size = 14;
window_padding_width = 4;
};
};
}
Category: Window Manager (macOS only)
AeroSpace — tiling window manager. Uses a TOML config file.
# modules/home/aerospace/default.nix
{ ... }:
{
home.file.".config/aerospace/aerospace.toml".source = ./aerospace.toml;
}
Create modules/home/aerospace/aerospace.toml with the user's preferred keybindings. The reference repo has a working config to draw from.
Category: Homebrew Extras (macOS only)
Ask what GUI apps they want managed via Homebrew. Add to homebrew.casks in the darwin module or the host-specific config.
Common casks: "1password", "slack", "discord", "raycast", "orbstack", "docker".
Category: AI/LLM Tools
Ask if they use any AI coding tools. For simple setups (no secrets), install via packages:
# Add to modules/home/packages.nix:
# First add the input to flake.nix:
# llm-agents.url = "github:numtide/llm-agents.nix";
# Then in packages.nix:
home.packages = [
flake.inputs.llm-agents.packages.${pkgs.system}.claude-code
];
For advanced setups with API keys and custom settings, follow the option-driven pattern from the reference repo's modules/home/claude-code/ module.
Category: Secrets Management
Only offer this if the user has API keys or tokens to manage. Requires sops-nix and age.
- Add inputs to
flake.nix:
sops-nix.url = "github:Mic92/sops-nix";
sops-nix.inputs.nixpkgs.follows = "nixpkgs";
- Create
modules/home/sops.nix:
{ flake, config, ... }:
{
imports = [ flake.inputs.sops-nix.homeManagerModules.sops ];
sops.age.keyFile = "${config.home.homeDirectory}/.config/sops/age/keys.txt";
}
- Generate an age key:
mkdir -p ~/.config/sops/age
age-keygen -o ~/.config/sops/age/keys.txt
- Create
.sops.yamlwith the public key andsecrets.yamlwith encrypted values.
Walk the user through each step — secrets management is the most error-prone part.
Phase 5: Per-Machine Overrides
If the user has multiple machines (e.g., work + personal), show how to add machine-specific config. The pattern is:
# configurations/darwin/<hostname>.nix
home-manager.users.<username> = { lib, config, ... }: {
# Machine-specific packages
home.packages = with pkgs; [ git-lfs ];
# Machine-specific option overrides
someModule.someSetting = "override-value";
};
Create a new configurations/darwin/<hostname>.nix for each machine. The base user config in configurations/home/<username>.nix is shared across all machines.
Phase 6: Verification
After all modules are set up:
- Run
nix fmtto format all Nix files - Run
nix flake checkto verify evaluation - Run
nix run .#activateto apply the full configuration - Verify key programs are available:
which git,which zsh, etc. - Suggest committing and pushing to GitHub
Reference Patterns
These patterns from the reference repo should be followed when generating Nix code. For detailed templates, see templates.md.
Auto-Import
Every .nix file (and subdirectory with default.nix) in modules/home/ is automatically imported. No manual import list to maintain.
Option-Driven Modules
For complex modules, define typed options and use mkIf for conditional config:
{ config, lib, ... }:
let cfg = config.myModule; in
{
options.myModule = {
enable = lib.mkEnableOption "my module";
setting = lib.mkOption {
type = lib.types.str;
default = "value";
description = "Description of the setting";
};
};
config = lib.mkIf cfg.enable {
home.packages = [ /* ... */ ];
};
}
Flake Input Access
Modules access flake inputs via the flake argument:
{ flake, pkgs, ... }:
let
inherit (flake) inputs;
in
{
home.packages = [
inputs.some-flake.packages.${pkgs.system}.default
];
}
Configuration Hierarchy
configurations/darwin/<host>.nix -> system-level (macOS)
configurations/nixos/<host>.nix -> system-level (Linux)
configurations/home/<user>.nix -> user-level (shared across machines)
host.nix: home-manager.users.<user> -> per-machine user overrides
Activation
nix run .#activate # Apply configuration
nix run .#update # Update flake.lock
nix fmt # Format all .nix files
nix flake check # Verify evaluation
From the file to a first result
The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.
View the source and supporting filesThis download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.
1. Download the file
Download SKILL.mdFrom the root of a test project, save the file as .skill-downloads/build-your-own-nix-dotfiles-mmh8qrws/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.
Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.
mkdir -p '.skill-downloads/build-your-own-nix-dotfiles-mmh8qrws' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/build-your-own-nix-dotfiles-mmh8qrws/download' --output '.skill-downloads/build-your-own-nix-dotfiles-mmh8qrws/SKILL.md.part' && mv '.skill-downloads/build-your-own-nix-dotfiles-mmh8qrws/SKILL.md.part' '.skill-downloads/build-your-own-nix-dotfiles-mmh8qrws/SKILL.md'2. Check prerequisites
Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.
No recognized prerequisites section in this file. This does not mean it is self-contained: libraries, tools and access requirements may be mentioned elsewhere in the content or source repository.
The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.
3. Load the skill
After inspection, copy the complete folder into your project using one of the commands below, then open a new tool session. The command stops if a folder with the same name already exists: compare the files before replacing it.
Claude Code
test -f '.skill-downloads/build-your-own-nix-dotfiles-mmh8qrws/SKILL.md' && test -s '.skill-downloads/build-your-own-nix-dotfiles-mmh8qrws/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/nix-dotfiles' && cp -R '.skill-downloads/build-your-own-nix-dotfiles-mmh8qrws' '.claude/skills/nix-dotfiles'OpenSkills
OpenSkills must already be installed. The local install/read procedure is checked with OpenSkills 1.5.0, which requires Node.js ≥ 20.6.0. Catalog slugs are not resolved automatically.
Official OpenSkills installationopenskills install './.skill-downloads/build-your-own-nix-dotfiles-mmh8qrws'openskills read 'build-your-own-nix-dotfiles-mmh8qrws'Reading should display the installed file content and its base directory. It does not run the skill or install its dependencies.
For an agent that reads AGENTS.md, then sync the index. This command changes AGENTS.md: review the diff before using it.
openskills syncManual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.
4. Try a first task
Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:
Read .skill-downloads/build-your-own-nix-dotfiles-mmh8qrws/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.
React Hook Form Best Practices
Development
Master React Hook Form: avoid anti-patterns, manage subscriptions, and handle reset, dirty state, and controlled inputs correctly.
Emotion to Mantine Migration
Development
Migrate Emotion styled-components to Mantine components with style props and CSS modules. Use when converting .styled.tsx files or removing @emotion imports.
Scope Creep Detector
Development
Analyzes git diffs against a stated intent to detect scope creep, unrelated files, broad PRs, and oversized changes, then suggests keep, split, or justify actions.