This repository is my declarative macOS setup built with Denix, nix-darwin, and Home Manager.
It currently manages two Apple Silicon hosts and uses Denix to compose host
definitions, reusable modules, and theme variants (“rices”) into both
user-level and system-level configurations. The day-to-day default host is
seiran.
What this repo optimizes for:
- reproducible workstation setup with Nix flakes
- modular configuration without hand-wired import trees
- themeable desktop and editor setup through reusable rices
- AI-heavy local tooling, including Codex, Claude Code, OpenCode, and MCP wiring
- a layout that future me can re-enter without reverse-engineering the whole tree
Denix auto-discovers .nix files under hosts/, modules/, and rices/.
That gives the repo its shape:
hosts/defines machine-specific facts such as platform, default rice, and host-only wiringmodules/contains reusable configuration split intoconfig/,programs/,services/, andtoplevel/rices/contains theme variants and inheritance-only theme bases
The important constraints are:
- Do not manually stitch modules together across those Denix discovery trees.
- Flakes only see git-tracked files, so new files must be added before evaluation or builds.
- Rices should stay data-oriented. Modules own package resolution and platform-specific wiring.
- Secrets are consumed through
config.sops.secrets.<key>.path, not hardcoded paths or plaintext values.
If you are entering the repo cold and need the actual module-boundary and
splitting rules, read docs/denix-architecture.md next. This README keeps the
high-level map only.
Hosts carry a performance tier (minimal, basic, standard, full) that
modules can use to scale behavior to machine capability. See
docs/host-tiers.md for the full contract.
Current default host/theme reality:
- Host:
seiran - Platform:
aarch64-darwin - Default rice:
catppuccin - Tier:
full - Display: notch-aware laptop layout
- Other selectable rices:
monochrome,everforest
Other host currently defined:
kurogane—aarch64-darwinlaptop, default ricemonochrome, tierbasic
A justfile provides short aliases for all common commands. Run just (from
nix develop) to see the full recipe list.
just home # Home Manager only (fastest)
just switch # Full system (darwin + home-manager)
just rice catppuccin # Switch rice
just apply # fmt → check → switch (safe full deploy)
just check # Validate flake
just fmt # Format via treefmt
just develop # Enter dev shell
just update # Update all flake inputs
just upgrade # Update + apply
just clean # Clean generations (keep 5)Override the default host or keep count:
just host=kurogane switch
just keep=3 cleanThe underlying commands are still available directly:
nh home switch
nh darwin switch . -H seiran -Lt
nix flake check
nix fmt
nix developTheme data lives in modules/config/colorschemes/ and rices/.
Rices choose colors, wallpaper, and theme-oriented option values; modules
consume those values to configure tools such as Ghostty, tmux, nixvim,
SketchyBar, and JankyBorders.
The inheritance-only rice at rices/inheritanceOnly/laptop.nix holds shared
laptop defaults. Concrete rices such as monochrome, catppuccin, and
everforest build on top of it.
Secrets are declared centrally in modules/toplevel/secrets.nix and consumed
through host-specific secret bindings when a host needs them. The encrypted
source of truth is managed with
sops-nix.
If you need the exact file paths or the rotation procedure, use
docs/secrets-key-rotation.md rather than expanding the root README.
This repo has first-class configuration for:
- Claude Code
- Codex
- OpenCode
- agent-browser
- shared MCP server wiring
The MCP source of truth lives in modules/programs/mcp-servers/default.nix.
That module owns server definitions, target-specific adapters, validation
assertions, and secret-aware runtime wiring.
Some MCP helpers come from node-packages/, which is a bun2nix-managed Node
package set used by the Nix wrappers in modules/config/node-packages.nix.
AquaSKK is installed declaratively via modules/programs/aquaskk/. The module
seeds required AquaSKK preferences at activation time using defaults write
into the jp.sourceforge.inputmethod.aquaskk domain. This runs after Home
Manager’s linkGeneration phase so that any previously managed symlink is
cleaned up before the real CFPreferences plist is created.
Input-source registration (com.apple.HIToolbox) is owned declaratively by the
AquaSKK module via the central aggregation interface in
modules/toplevel/nix-darwin/system/ime.nix.
If AquaSKK does not appear in Input Sources after activation:
- Log out and log back in (macOS discovers input methods on session start).
- If it still doesn’t appear, go to System Settings → Keyboard → Input Sources → Edit → Add Input Source, then search for “AquaSKK” and add it.
If activation warns about a symlink at
~/Library/Preferences/jp.sourceforge.inputmethod.aquaskk.plist, remove or
back up the symlink, then re-run activation:
rm ~/Library/Preferences/jp.sourceforge.inputmethod.aquaskk.plist
nh home switchThe flake defines a small maintenance shell with tools such as bun, deno,
just, nickel, stylua, and emmylua-ls. A justfile at repo root
provides short aliases for all common workflows. Formatting is configured
through treefmt.nix.
This is a Nix-native repo. Prefer changing the flake and modules over managing tool state outside the configuration, unless a local module explicitly requires it.
. ├── docs/ Stable policy docs and runbooks ├── hosts/ Host-specific definitions and bindings ├── modules/ Reusable Denix modules ├── node-packages/ bun2nix-managed Node packages for MCP-related wrappers ├── nickel/ Nickel experiments and support material ├── rices/ Theme variants and inheritance-only theme bases └── var/ Small repo-local artifacts and planning scratch files
Within modules/:
config/holds shared data and cross-cutting configuration helpersprograms/configures user-facing toolsservices/configures desktop services such as AeroSpace and SketchyBartoplevel/handles broad system/user wiring such as Nix, Home Manager, fonts, and secretstoplevel/nix-darwin/system/— shared OS policy (activation, host, security, IME aggregation)toplevel/nix-darwin/preferences/— shared macOS user preferences (appearance, dock, input, etc.)
You will also see directories such as .agents/, .claude/,
.agent-browser/, .opencode/, and .crush/. Those are local runtime or
tool-state directories, not the main declarative source of truth.
- Denix architecture and module-splitting guide:
docs/denix-architecture.md - Documentation policy:
docs/documentation-policy.md - Claude Code entry guidance:
CLAUDE.md - Other coding agents entry guidance:
AGENTS.md - Module tree guidance:
modules/CLAUDE.md - Config-specific notes:
modules/config/CLAUDE.md - Toplevel/secrets notes:
modules/toplevel/CLAUDE.md
See LICENSE.