This repository builds a consistent shell and developer environment across NixOS-WSL, generic Linux, and macOS. Nix is the primary configuration engine, Home Manager provides reusable user-level capabilities, and Homebrew supports company-managed Macs where Nix is unavailable.
The final pre-Nix version is preserved by the pre-nix tag.
| Profile | Configuration owner | Intended use |
|---|---|---|
chev-desktop |
NixOS + Home Manager | Native NVIDIA gaming and development desktop |
nixos-wsl |
NixOS + Home Manager | Primary Windows development environment |
linux |
Home Manager | Ubuntu and other Linux distributions with Nix |
macos-managed |
Homebrew + repository links | Macs where /nix cannot be installed |
macos |
Home Manager | Apple Silicon Macs without nix-darwin |
darwin-macos |
nix-darwin + Home Manager | Personally managed Apple Silicon Macs |
Flake outputs use wsl, linux, and macos-arm64 consistently inside their
respective NixOS, Home Manager, and nix-darwin namespaces. The shorter macOS
profile names remain as compatibility aliases.
dotctl detects the normal profile automatically, so routine maintenance is:
dotctl apply
updoot
dotctl doctorupdoot is an alias for dotctl apply --update. Updates happen in a staging
checkout with isolated Neovim state. Before staging, local changes are saved,
the branch is rebased onto its latest upstream, and the local changes are
restored. New lockfiles are accepted only after Neovim automation and all-system
Nix evaluation succeed. Neovim, Lazy, Mason, and Treesitter progress is streamed
directly to the terminal. The isolated phase updates only Lazy plugin pins;
installed Mason tools and Treesitter parsers are updated once in the persistent
runtime after validation. After applying, updoot commits every outstanding
change and fetches again. Any late upstream changes are rebased, validated, and
reapplied before the current branch is pushed. dotctl update refreshes pins
without applying, committing, or pushing them.
On NixOS-WSL, apply and updoot also reconcile the latest Windows applications
declared in platforms/windows/winget.json through WinGet. Neovide, WezTerm,
1Password, and the Codex desktop app are managed there.
Interactive Lazy updates write to nvim/lazy-lock.json in a writable
DOTFILES_ROOT or ~/.dotfiles checkout. When the Neovim module is consumed
without a checkout, Lazy uses a writable lockfile under Neovim's state directory
instead of the immutable Home Manager configuration.
Clone over HTTPS so first setup does not depend on an SSH agent:
git clone --filter=blob:none https://github.com/AlexAllocated/.dotfiles.git ~/.dotfiles
cd ~/.dotfilesThe first apply prompts for a machine-local Git author name and email. For
unattended setup, set DOTFILES_GIT_NAME and DOTFILES_GIT_EMAIL.
From an existing WSL distribution:
cd ~/.dotfiles
./dot-bootstrap nixos-wslThe bootstrap downloads a pinned NixOS-WSL image, verifies its checksum, and installs it beside the existing distribution. Inside the new distribution:
git clone --filter=blob:none https://github.com/AlexAllocated/.dotfiles.git ~/.dotfiles
cd ~/.dotfiles
./scripts/dotctl apply nixos-wsl
wsl.exe -t NixOSAfter reopening NixOS, run dotctl doctor. See
docs/nix-wsl-rollout.md for Windows links and the
optional shared Codex conversation migration.
The native NixOS profile uses Plasma Wayland, the open NVIDIA kernel module,
PipeWire, Steam/Proton, Sunshine/NVENC, WiVRn, and ALVR. It uses systemd-boot
with the existing Windows EFI partition mounted at /efi and a separate 2 GiB
XBOOTLDR partition mounted at /boot.
WezTerm is the default terminal and Alacritty remains installed as the fast,
minimal alternative. Both use the BigBlueTerm Nerd Font and Gruvbox Dark
palette.
Konsole gets a non-destructive managed profile with the same font and palette.
Tmux is available everywhere with its stock Ctrl+B bindings, plus portable
true color, clipboard forwarding, mouse scrolling, and extended scrollback.
On chev-desktop, ordinary local and SSH tmux commands share one system-owned
server, so sessions survive compositor, terminal, and user-service restarts.
Run tmux-cheatsheet for the local quick reference.
Plasma remains the default and remote-recovery desktop. SDDM also offers niri
and Mango sessions. Both optional compositors use Noctalia for their bar,
launcher, notifications, and session controls. Common bindings are
Super+Return for WezTerm, Super+Space for the launcher,
Super+Shift+D for the fallback launcher, and Super+Shift+E for the session
menu. Ctrl+Alt+Delete safely restarts the current experimental session if the
shell fails. Mango remaps its upstream Super+M quit binding to minimize the
focused window instead. The iPad dummy uses its native 2732x2048 mode beside
the 3440x1440 LG while streaming, and remains active when it is the only
connected display so remote recovery cannot leave the compositor headless.
Both connectors have Gruvbox meadow art. Niri evacuates LG workspaces to the
dummy when the LG powers off and restores only those workspaces when it
returns.
First-run Noctalia settings select Gruvbox Dark and hide lock, suspend, and
hibernate until the workstation password has been intentionally set and
tested.
Sunshine runs as one persistent system service below SDDM and every selectable Wayland session. It captures the DP-2 dummy through KMS and follows the dummy's transient KMS display number when the LG powers off or returns, so Moonlight remains a recovery path without requiring the physical display.
Build the local-first internal installer with:
nix build path:.#chev-installer-iso
nix build path:.#chev-installer-fat32-checkThe image embeds this flake plus the confirmation-gated installation and Codex
handoff tools. See
docs/chev-desktop-migration.md for the
storage contract, operator commands, and versioned capsule format.
cd ~/.dotfiles
./scripts/dotctl apply macos-managed
exec zsh -lThe tracked platforms/macos-managed/Brewfile declares host software and
platforms/macos/Brewfile declares shared GUI apps. Homebrew owns global tools,
runtimes, Neovide, WezTerm, 1Password, and the Codex desktop app; Bun owns
npm-registry CLIs such as Codex. Mise is available for project-local runtime
versions but does not own global tools.
Applying this profile removes services, containers, and host runtime files left
by the retired macOS Docker workshop. Its home and builder volumes are preserved
by default; set DOTFILES_PURGE_LEGACY_DOCKER_WORKSHOP=1 for one apply to remove
those volumes and the old local workstation image too.
./dot-bootstrap linux # use macos on macOS
# Open a new shell after Nix installation.
./scripts/dotctl apply linuxUse macos instead of linux for a Home Manager-only Apple Silicon Mac. On a
personal Mac using nix-darwin, apply darwin-macos. Native Linux installs
Neovide, WezTerm, and 1Password through Nix. OpenAI currently publishes the
Codex desktop app for Windows and macOS only; Linux uses the managed Codex CLI.
The reusable Home Manager API is identity-neutral:
{
inputs.dotfiles.url = "github:AlexAllocated/.dotfiles";
outputs = { home-manager, nixpkgs, dotfiles, ... }: {
homeConfigurations.me = home-manager.lib.homeManagerConfiguration {
pkgs = nixpkgs.legacyPackages.x86_64-linux;
modules = [
dotfiles.homeModules.shell
dotfiles.homeModules.git
dotfiles.homeModules.nvim
dotfiles.homeModules.codex
{
home.username = "me";
home.homeDirectory = "/home/me";
home.stateVersion = "26.05";
}
];
};
};
}Available modules:
foundation: core command-line utilitiesshell: zsh, Powerlevel10k, navigation, and shell integrationsgit: Git, Delta, and Lazygit without an embedded author identitynvim: the complete Neovim configuration and runtime dependenciesneovide: native Neovide, BigBlueTerm Nerd Font, and shared GUI settingscodex: Codex, Bun, and Node; user settings, plugins, MCP servers, and rules stay machine-localdevelopment: compilers, language runtimes, formatters, and build toolscloud: Kubernetes and cloud CLIsterminal: Alacritty, WezTerm, Konsole styling, and portable tmuxcompositors: optional niri/Mango configs, shared Noctalia shell, and portable output policywindows: Windows-side link helperdefault: the complete workstation composition
nixosModules.compositors enables the two optional display-manager sessions
while preserving the caller's desktop policy. nixosModules.wsl exposes the
WSL host module with neutral defaults; set
dotfiles.wsl.user and dotfiles.wsl.userDescription in the consuming NixOS
configuration.
Consumers set their own home.stateVersion, username, home directory, and Git
identity.
Containers are distribution and emergency-repair artifacts, not the recommended daily workstation boundary.
nix build .#docker-linux
nix build .#docker-pocket-knife
docker load < resultThe full image contains the workstation toolset. The smaller pocket knife keeps
the shell, Git, Neovim, Codex, and practical repair utilities. Both use the
neutral dev user and are published for AMD64 and ARM64 Linux:
docker run --rm -it -v "$PWD:/work" \
ghcr.io/alexallocated/dotfiles-pocket-knife:latestCommit-addressed sha-<commit> tags are published alongside latest.
nix develop
nix fmt
dotctl checkChecks cover Nix formatting and evaluation, ShellCheck, Bash syntax, Lua syntax, Stylua, Python compilation, the public Home Manager module API, and container smoke tests in CI.
The NixOS-WSL profile also reconciles the Windows side of the workstation. It installs or updates WezTerm, Neovide, and the official ChatGPT/Codex desktop app through WinGet; installs the locked BigBlueTerm Nerd Font; deploys Neovide settings; maintains WSL-backed application links; and registers terminal Neovim and Neovide with Windows and Codex's Open with menu. Neovide is the Codex default.
Existing Windows files are backed up before replacement. The link reconciler can still be run directly for troubleshooting:
pwsh ./scripts/windows/apply-wsl-links.ps1 -DistroName NixOSCodex CLI and desktop share the Windows Codex home while keeping SQLite on WSL
ext4. The profile maintains only the required Windows/WSL routing and editor
handler fields. Model preferences, TUI settings, plugins, MCP servers, rules,
auth, conversations, and runtime state stay machine-local. Migrating
pre-existing separate conversation stores remains an explicit
dotctl codex-share migrate operation because both clients must be closed.
Neovide is installed Windows-native and starts Neovim in the default WSL distro; do not install the Linux Neovide package for this workflow.
Shared Git behavior is tracked in .gitconfig; author identity stays in
~/.config/git/identity. Optional machine-only Git overrides belong in
~/.config/git/local.