{"id":50585040,"url":"https://github.com/pr0d1r2/nix-home-manager-claude-code","last_synced_at":"2026-06-05T05:30:52.761Z","repository":{"id":360923772,"uuid":"1252241841","full_name":"pr0d1r2/nix-home-manager-claude-code","owner":"pr0d1r2","description":"Declarative home-manager module for Claude Code — settings, hooks, MCP, plugins, skills, presets, all merge-safe","archived":false,"fork":false,"pushed_at":"2026-05-28T12:52:54.000Z","size":96,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-28T13:23:58.375Z","etag":null,"topics":["ai-tools","claude-code","declarative-configuration","home-manager","llm","nix","nix-flakes"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pr0d1r2.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-28T10:25:41.000Z","updated_at":"2026-05-28T12:52:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pr0d1r2/nix-home-manager-claude-code","commit_stats":null,"previous_names":["pr0d1r2/nix-home-manager-claude-code"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/pr0d1r2/nix-home-manager-claude-code","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pr0d1r2%2Fnix-home-manager-claude-code","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pr0d1r2%2Fnix-home-manager-claude-code/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pr0d1r2%2Fnix-home-manager-claude-code/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pr0d1r2%2Fnix-home-manager-claude-code/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pr0d1r2","download_url":"https://codeload.github.com/pr0d1r2/nix-home-manager-claude-code/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pr0d1r2%2Fnix-home-manager-claude-code/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33932040,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-05T02:00:06.157Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-tools","claude-code","declarative-configuration","home-manager","llm","nix","nix-flakes"],"created_at":"2026-06-05T05:30:51.267Z","updated_at":"2026-06-05T05:30:52.750Z","avatar_url":"https://github.com/pr0d1r2.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nix-home-manager-claude-code\n\n[![CI](https://github.com/pr0d1r2/nix-home-manager-claude-code/actions/workflows/ci.yml/badge.svg)](https://github.com/pr0d1r2/nix-home-manager-claude-code/actions/workflows/ci.yml)\n\nDeclarative home-manager module for Claude Code configuration. Manages settings, MCP servers, hooks, commands, rules, keybindings, CLAUDE.md, permissions, and plugins — all merge-safe with mutable `~/.claude/` files.\n\n## Quick Start\n\nAdd to your flake inputs:\n\n```nix\n{\n  inputs.nix-home-manager-claude-code = {\n    url = \"github:pr0d1r2/nix-home-manager-claude-code\";\n    inputs.nixpkgs.follows = \"nixpkgs\";\n  };\n}\n```\n\nImport the module and enable:\n\n```nix\n{\n  imports = [ nix-home-manager-claude-code.homeManagerModules.default ];\n\n  programs.claude-code = {\n    enable = true;\n    model = \"claude-sonnet-4-6\";\n    settings.theme = \"dark\";\n  };\n}\n```\n\n**Note:** You must disable home-manager's built-in claude-code module to avoid conflicts:\n\n```nix\n{\n  disabledModules = [ \"programs/claude-code.nix\" ];\n}\n```\n\n## Options\n\n### Core\n\n| Option | Type | Default | Description |\n| ------ | ---- | ------- | ----------- |\n| `enable` | bool | `false` | Enable Claude Code module |\n| `package` | package or null | `null` | Claude Code package (null = installed externally) |\n| `model` | string or null | `null` | Claude model to use |\n| `thinkingBudget` | enum or null | `null` | Thinking budget: none/low/medium/high/max |\n| `settings` | attrs | `{}` | Freeform settings merged into settings.json |\n| `env` | attrs | `{}` | Environment variables |\n| `credentials.source` | path or null | `null` | Path to credentials.json (symlinked to ~/.claude/.credentials.json) |\n\n### MCP Servers\n\n```nix\nprograms.claude-code.mcpServers = {\n  my-server = {\n    type = \"stdio\";\n    command = \"my-mcp-server\";\n    args = [ \"--port\" \"3000\" ];\n    env.API_KEY = \"...\";\n  };\n  my-http-server = {\n    type = \"streamable-http\";\n    url = \"http://localhost:8080/mcp\";\n  };\n};\n```\n\n### Hooks\n\n```nix\nprograms.claude-code.hooks = {\n  UserPromptSubmit = [\n    {\n      hooks = [\n        {\n          type = \"command\";\n          command = \"echo 'prompt submitted'\";\n          timeout = 5;\n        }\n      ];\n    }\n  ];\n};\n```\n\n### Hook Scripts\n\nScripts placed at `~/.claude/hooks/`:\n\n```nix\nprograms.claude-code.hookScripts = {\n  \"my-hook.sh\".text = ''\n    #!/usr/bin/env bash\n    echo \"hook ran\"\n  '';\n  \"other-hook.sh\".source = ./hooks/other.sh;\n  \"with-deps.sh\" = {\n    text = ''\n      echo '{}' | jq '.foo = \"bar\"'\n    '';\n    runtimeInputs = [ pkgs.jq ];\n  };\n};\n```\n\nWhen `runtimeInputs` is set, the script is wrapped with `writeShellApplication` so listed packages are on `PATH`.\n\n### Commands\n\n```nix\nprograms.claude-code.commands = {\n  \"my-command\".content = \"Do the thing described here.\";\n  \"from-file\".source = ./commands/my-command.md;\n  \"humor\" = {\n    source = ./commands/humor;\n    recursive = true;\n  };\n};\n```\n\n### Rules\n\n```nix\nprograms.claude-code.rules = {\n  \"no-console\".content = \"Never use console.log in production code.\";\n  \"style-guide\".source = ./rules/style.md;\n};\n```\n\n### CLAUDE.md Composition\n\n```nix\nprograms.claude-code.claudeMd.fragments = [\n  { content = \"# Project Rules\"; order = 0; }\n  { content = \"Always use TypeScript.\"; order = 10; }\n  { source = ./claude-fragments/testing.md; order = 20; }\n];\n```\n\n### Permissions\n\n```nix\nprograms.claude-code.permissions = {\n  allow = [ \"Bash(npm test)\" \"Bash(npm run build)\" ];\n  deny = [ \"Bash(rm -rf *)\" \"Bash(git push --force *)\" ];\n};\nprograms.claude-code.defaultMode = \"auto\";\n```\n\n### Keybindings\n\n```nix\nprograms.claude-code.keybindings = [\n  { key = \"ctrl+k\"; command = \"clear\"; }\n];\n```\n\n### Spinner Verbs\n\n```nix\nprograms.claude-code.spinnerVerbs = {\n  mode = \"replace\";\n  verbs = [ \"Thinking hard\" \"Computing\" \"Reasoning\" ];\n};\n```\n\n### Status Line\n\n```nix\nprograms.claude-code.statusLine = {\n  command = \"echo 'status'\";\n  refreshInterval = 5;\n};\n```\n\n### Plugins\n\nInstall plugin marketplaces from Nix sources:\n\n```nix\nprograms.claude-code.plugins = {\n  my-marketplace = {\n    src = inputs.my-marketplace;\n    subPlugins = [ \"plugin-a\" \"plugin-b\" ];\n  };\n};\n```\n\nEach marketplace is symlinked to `~/.claude/nix-plugins/\u003cname\u003e` and registered in `extraKnownMarketplaces`. Sub-plugins are added to `enabledPlugins` automatically.\n\nBlock specific plugins:\n\n```nix\nprograms.claude-code.blockedPlugins = [ \"bad-plugin@some-marketplace\" ];\n```\n\nRemove data dirs for plugins no longer in config on rebuild:\n\n```nix\nprograms.claude-code.cleanPluginData = true;\n```\n\n## Presets\n\nEnable built-in presets for common configurations:\n\n```nix\nprograms.claude-code.presets = {\n  security = true;   # Deny rules for destructive operations\n  caveman = true;    # Caveman mode hooks (SessionStart + UserPromptSubmit)\n  doomer = true;     # Doomer spinner verbs (mutually exclusive with skeptic)\n  skeptic = true;    # Skeptic spinner verbs (mutually exclusive with doomer)\n};\n```\n\n## Migration\n\nMigrate from manually managed `~/.claude/` to Nix-managed:\n\n```bash\n# See what would be backed up\nbash scripts/migrate.sh --dry-run\n\n# Back up existing files (renames to .backup, never deletes)\nbash scripts/migrate.sh --backup\n\n# Show home.file attr paths to remove from old config\nbash scripts/migrate.sh --nix-config\n```\n\nMigration is idempotent — files already backed up are skipped.\n\n## Detecting Plugins\n\nScan for manually installed plugins not yet in your Nix config:\n\n```bash\n# Output Nix snippets ready to paste\nbash scripts/detect-plugins.sh\n\n# Machine-readable JSON\nbash scripts/detect-plugins.sh --json\n```\n\n## Templates\n\nBootstrap new plugin or marketplace repos:\n\n```bash\n# Single plugin\nnix flake init -t github:pr0d1r2/nix-home-manager-claude-code#plugin\n\n# Plugin marketplace\nnix flake init -t github:pr0d1r2/nix-home-manager-claude-code#marketplace\n```\n\n## NixOS Usage\n\nThis module works inside NixOS via `home-manager.users.\u003cname\u003e`:\n\n```nix\n{\n  inputs = {\n    home-manager.url = \"github:nix-community/home-manager/release-25.11\";\n    nix-home-manager-claude-code.url = \"github:pr0d1r2/nix-home-manager-claude-code\";\n  };\n}\n```\n\n```nix\nhome-manager.users.myuser = {\n  imports = [\n    nix-home-manager-claude-code.homeManagerModules.default\n  ];\n\n  disabledModules = [ \"programs/claude-code.nix\" ];\n\n  programs.claude-code = {\n    enable = true;\n    model = \"claude-opus-4-6\";\n    thinkingBudget = \"medium\";\n    credentials.source = ./secrets/credentials.json;\n    presets.security = true;\n  };\n};\n```\n\n## Merge Behavior\n\nSettings, MCP servers, and blocklist are **merge-managed**: Nix-declared keys are deep-merged into existing files, preserving manual edits. Managed keys are tracked in `.nix-managed-keys.json` / `.nix-managed-mcp-keys.json` — stale keys are automatically removed on rebuild.\n\nAll other files (hooks, commands, rules, keybindings, CLAUDE.md) are **fully owned** by Nix via `home.file`.\n\n## Development\n\n```bash\n# Enter dev shell\ndirenv allow\n\n# Run tests\nbats tests/\n\n# Check everything\nnix flake check\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpr0d1r2%2Fnix-home-manager-claude-code","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpr0d1r2%2Fnix-home-manager-claude-code","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpr0d1r2%2Fnix-home-manager-claude-code/lists"}