Skip to content

Instantly share code, notes, and snippets.

@kinncj
Last active July 17, 2026 15:27
Show Gist options
  • Select an option

  • Save kinncj/1df9ecb409f310842c7a6ebfdf3e1a73 to your computer and use it in GitHub Desktop.

Select an option

Save kinncj/1df9ecb409f310842c7a6ebfdf3e1a73 to your computer and use it in GitHub Desktop.
[KINNCJ] NIX.DEV

🌌 Universal Dev Environment (Nix + Home Manager)

A reproducible, single-file development environment for macOS, native Linux (Ubuntu/Fedora/Arch/CachyOS), and WSL.

It supports your shell mix:

  • macOS: Zsh (+ Oh My Zsh)
  • Ubuntu: Bash (+ Oh My Bash)
  • CachyOS: Fish (+ Oh My Fish)

πŸ‘€ Maintainer

Kinn <kinncj@protonmail.com>
This is Kinn’s personal cross-platform Home Manager setup.


πŸ› οΈ What's Included

  • Editors: Neovim (isolated LazyVim profile), VS Code (disabled on WSL).
  • Terminal & Shell: Zsh/Bash/Fish profiles via Home Manager, Ghostty with platform-aware packaging.
  • AI Tooling: GitHub Copilot CLI, Claude Code (where available), RTK, Code Review Graph, Pi (pi-agent), OpenCode (opencode).
  • Core Agents & Runtime: MAPLE (by Kinn), Herdr, Heimdall (by Kinn).
  • Toolchain: Node.js 22, Python 3, Pipx, Cargo (Rust), Go, GitHub CLI, GCC, Make, Git, gnutar.

πŸš€ Setup Instructions (Fresh Machine)

1) Install Nix

curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh

Restart your terminal after install.

2) Bootstrap Home Manager

nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
nix-channel --update
nix-shell '<home-manager>' -A install

3) Place home.nix

mkdir -p ~/.config/home-manager
nano ~/.config/home-manager/home.nix

4) Deploy

home-manager switch

Reload your active shell:

  • zsh: exec zsh
  • bash: exec bash
  • fish: exec fish

πŸ”„ Updating Later

home-manager switch

If channels are stale:

nix-channel --update
home-manager switch

🧭 Platform Notes

Ghostty mapping in Nixpkgs

  • macOS: pkgs.ghostty-bin
  • native Linux: pkgs.ghostty
  • WSL: GUI package skipped

macOS app links

GUI apps are linked into:

  • /Applications/Home Manager Apps

Launch examples:

open "/Applications/Home Manager Apps/Ghostty.app"
open "/Applications/Home Manager Apps/Visual Studio Code.app"

🐚 Shell Frameworks


⌨️ Quick Commands

  • lvim β€” Open Neovim with NVIM_APPNAME=lazyvim-nix
  • gh copilot β€” GitHub Copilot CLI
  • claude β€” Claude Code (if available on platform/channel)
  • rtk init -g β€” Initialize Rust Token Killer
  • crg install β€” Install Code Review Graph mapping
  • pi-agent β€” Start Pi agent
  • opencode β€” Start OpenCode

Runtime installers (user space)

  • install-maple β€” installs MAPLE to ~/.tools/maple/bin
  • install-herdr β€” installs Herdr to ~/.local/bin/herdr
  • install-heimdall β€” installs Heimdall dashboard + daemon tooling

βœ… Ensure Herdr Works

After home-manager switch, run:

install-herdr
command -v herdr
herdr --help

Expected:

  • command -v herdr returns ~/.local/bin/herdr (or equivalent)
  • herdr --help prints usage text

If not found, confirm PATH contains ~/.local/bin:

echo $PATH

Then restart your shell (exec zsh / exec bash / exec fish).


🧰 Tools & Profile

Declarative PATH / Env

PATH includes:

  • ~/.tools/maple/bin
  • ~/.tools/heimdall/bin
  • ~/.local/bin
  • ~/.cargo/bin
  • ~/.go/bin
  • /usr/local/bin

Editors

  • Neovim + LazyVim bootstrap (~/.config/lazyvim-nix)
  • VS Code profile settings managed by Home Manager

AI / Context

  • Claude Code
  • GitHub Copilot CLI
  • RTK
  • Code Review Graph
  • Pi Coding Agent
  • OpenCode
  • MAPLE (by Kinn)
  • Heimdall (by Kinn)
  • Herdr

🧼 Clean Reset

rm -rf ~/.tools/maple ~/.tools/heimdall ~/.local/bin/herdr ~/.local/bin/code-review-graph ~/.cargo/bin/rtk ~/.cargo/git/checkouts/rtk-*
home-manager switch
exec zsh   # or bash/fish
install-maple
install-herdr
install-heimdall

πŸ”— Tool Links (Official)

Editors & IDE

Shells & Frameworks

Terminal

Source Control / CLI

AI / Agent Tooling

Kinn’s Tools

Other Core Runtime Tool

Runtimes / Build


πŸ“š References

# ~/.config/home-manager/home.nix
{ config, pkgs, lib, ... }:
let
isDarwin = pkgs.stdenv.isDarwin;
isLinux = pkgs.stdenv.isLinux;
isWSL =
isLinux
&& builtins.pathExists "/proc/sys/kernel/osrelease"
&& (builtins.match ".*([Mm]icrosoft|WSL).*"
(builtins.readFile "/proc/sys/kernel/osrelease") != null);
includeLinuxGUI = isLinux && (!isWSL);
envHome = builtins.getEnv "HOME";
envUser = builtins.getEnv "USER";
envShell = builtins.getEnv "SHELL";
usingZsh = lib.hasSuffix "/zsh" envShell;
usingBash = lib.hasSuffix "/bash" envShell;
usingFish = lib.hasSuffix "/fish" envShell;
homeDirectory =
if envHome != "" then envHome
else if isDarwin then "/Users/${envUser}"
else "/home/${envUser}";
usernameFromHome =
let m = builtins.match ".*/([^/]+)$" homeDirectory;
in if m == null then envUser else builtins.elemAt m 0;
has = name: builtins.hasAttr name pkgs;
commonAliases = {
lvim = "nvim";
crg = "code-review-graph";
pi-agent = "npx @mariozechner/pi-coding-agent";
opencode = "npx opencode-ai";
code-insiders = "code-insiders";
install-maple = "curl -fsSL https://raw.githubusercontent.com/kinncj/MAPLE/main/scripts/install.sh | bash";
# Replace with official Herdr installer command from https://herdr.dev/ when ready
install-herdr = "echo 'Please install Herdr from https://herdr.dev/'";
install-heimdall = "curl -fsSL https://raw.githubusercontent.com/kinncj/Heimdall/main/scripts/install.sh | sh -s -- dashboard && curl -fsSL https://raw.githubusercontent.com/kinncj/Heimdall/main/scripts/install.sh | sh -s -- daemon";
};
in
{
home.username = usernameFromHome;
home.homeDirectory = homeDirectory;
home.stateVersion = "24.11";
nixpkgs.config.allowUnfree = true;
home.packages =
[
pkgs.neovim
pkgs.gh
pkgs.git
pkgs.nodejs # Keeps the default Node.js (and drops duplicate nodejs_22)
pkgs.gnumake
pkgs.gcc
pkgs.curl
pkgs.gnutar
pkgs.go
pkgs.cargo
pkgs.pipx
pkgs.python312
pkgs.fish
pkgs.bashInteractive
]
++ lib.optionals (has "github-copilot-cli" && isLinux) [ pkgs.github-copilot-cli ]
++ lib.optionals (has "claude-code" && isLinux) [ pkgs.claude-code ]
++ lib.optionals (isDarwin && has "ghostty-bin") [ pkgs.ghostty-bin ]
++ lib.optionals (includeLinuxGUI && has "ghostty") [ pkgs.ghostty ]
++ lib.optionals isDarwin [ pkgs.libiconv ];
home.sessionPath = [
"$HOME/.npm-global/bin"
"$HOME/.tools/maple/bin"
"$HOME/.tools/heimdall/bin"
"$HOME/.local/bin"
"$HOME/.cargo/bin"
"$HOME/.go/bin"
"/usr/local/bin"
];
home.sessionVariables = {
NVIM_APPNAME = "lazyvim-nix";
GOPATH = "${homeDirectory}/.go";
NPM_CONFIG_PREFIX = "$HOME/.npm-global";
};
programs.zsh = {
enable = true;
shellAliases = commonAliases;
oh-my-zsh = {
enable = true;
theme = "robbyrussell";
plugins = [ "git" "sudo" "history" ];
};
initExtra = ''
# Nix fallback bootstrap (handles macOS updates wiping Nix hooks)
if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then
. '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'
fi
'';
};
programs.bash = {
enable = true;
shellAliases = commonAliases;
initExtra = ''
if [ -f "$HOME/.oh-my-bash" ]; then
export OSH="$HOME/.oh-my-bash"
export OSH_THEME="font"
plugins=(git)
source "$HOME/.oh-my-bash/oh-my-bash.sh"
fi
'';
};
programs.fish = {
enable = true;
shellAliases = commonAliases;
interactiveShellInit = ''
set -g fish_greeting
'';
};
programs.vscode =
if isWSL then
{ enable = false; }
else
{
enable = true;
package = if isDarwin then pkgs.vscode else pkgs.vscode.fhs;
profiles.default.userSettings = {
"editor.fontSize" = 13;
"window.titleBarStyle" = if isDarwin then "custom" else "native";
"telemetry.telemetryLevel" = "off";
};
};
home.activation = {
setupLazyVim = config.lib.dag.entryAfter [ "writeBoundary" ] ''
if [ ! -d "$HOME/.config/lazyvim-nix" ]; then
echo "πŸ“¦ Initializing LazyVim..."
${pkgs.git}/bin/git clone https://github.com/LazyVim/starter "$HOME/.config/lazyvim-nix"
fi
'';
setupAgentExtensions = config.lib.dag.entryAfter [ "writeBoundary" ] ''
export PATH="$HOME/.go/bin:$HOME/.cargo/bin:$HOME/.local/bin:${pkgs.gcc}/bin:$PATH"
${lib.optionalString isDarwin ''export LIBRARY_PATH="${pkgs.libiconv}/lib:${"$"}{LIBRARY_PATH:-}"''}
if ! command -v code-review-graph >/dev/null 2>&1; then
echo "πŸ€– Installing Code Review Graph via pipx..."
${pkgs.pipx}/bin/pipx install --python ${pkgs.python312}/bin/python3 code-review-graph
fi
if ! command -v rtk >/dev/null 2>&1; then
echo "πŸ¦€ Installing RTK..."
${pkgs.cargo}/bin/cargo install --git https://github.com/rtk-ai/rtk
fi
'';
setupOhMyBash = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
${lib.optionalString usingBash ''
if [ ! -d "$HOME/.oh-my-bash" ]; then
echo "🐚 Installing Oh My Bash..."
${pkgs.git}/bin/git clone https://github.com/ohmybash/oh-my-bash.git "$HOME/.oh-my-bash"
fi
''}
'';
setupOhMyFish = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
${lib.optionalString usingFish ''
if [ ! -d "$HOME/.local/share/omf" ]; then
echo "🐟 Installing Oh My Fish..."
${pkgs.fish}/bin/fish -c '${pkgs.curl}/bin/curl -L https://get.oh-my.fish | fish'
fi
''}
'';
linkDarwinApps = lib.hm.dag.entryAfter [ "linkGeneration" ] (lib.mkIf isDarwin ''
set -euo pipefail
appDir="/Applications/Home Manager Apps"
mkdir -p "$appDir"
if [ -d "$HOME/.nix-profile/Applications" ]; then
find "$HOME/.nix-profile/Applications" -maxdepth 1 -name "*.app" -print0 \
| while IFS= read -r -d "" app; do
ln -sfn "$app" "$appDir/$(basename "$app")"
done
fi
${lib.optionalString (has "ghostty-bin") ''
if [ -d "${pkgs.ghostty-bin}/Applications" ]; then
find "${pkgs.ghostty-bin}/Applications" -maxdepth 1 -name "*.app" -print0 \
| while IFS= read -r -d "" app; do
ln -sfn "$app" "$appDir/$(basename "$app")"
done
fi
''}
if [ -d "${pkgs.vscode}/Applications" ]; then
find "${pkgs.vscode}/Applications" -maxdepth 1 -name "*.app" -print0 \
| while IFS= read -r -d "" app; do
ln -sfn "$app" "$appDir/$(basename "$app")"
done
fi
'');
};
programs.home-manager.enable = true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment