## Prerequisites ```powershell winget install -e --id Git.Git winget install -e --id Oven-sh.Bun winget install -e --id Microsoft.DSC winget install -e --id Casey.Just winget install -e --id junegunn.fzf winget install -e --id Microsoft.PowerShell ``` I really love my nixos config. I install it on all my linux boxes and it makes it dead simple to configure them exactly how I want them. I want a taste of that experience for my windows boxes. I am trying to evaluate different approaches. Can you help me evaluate a few different approaches? - I do not like python so ansible sounds not great but I would like to know what all features they have configured out of the box - I really like typescript and projects like sst and pulumi. They seem to have a lot of overlap with what I want to do, given they have a `diff` and `apply` command. I cloned my nixos-config to docs\nixos-config and I cloned several of the tools I am evaluating to docs\cloned-repos-as-docs I think it would be very useful for you to grep through all of that and get an understanding of what each tool can do what. The main things I want: - Be able to declare what programs are installed on the box - Declare that wsl2 be enabled - Declare that there should be a specific wsl distro installed. - Declare the `"C:\Users\ethan\.wslconfig"` settings - Declare the windows theme (dark) - Have the system be modular so I can enable/disable some programs for different hosts. # WinOS Config A declarative configuration system for Windows 11, inspired by NixOS. The goal is to describe the complete state of a Windows machine in version-controlled configuration files. ## Project Goals - **Declarative**: Define _what_ the system should look like, not _how_ to get there - **Reproducible**: Apply the same config to multiple machines with identical results - **Version controlled**: Track all configuration changes in git - **Modular**: Compose configurations for different hosts (gaming-pc, work-laptop, htpc) ## Current Status: Research & Planning This project is in the early research phase. We are evaluating technologies and documenting what is/isn't possible on Windows. --- ## Technology Options Under Consideration ### 1. DSC v3 (Microsoft Desired State Configuration) **Pros:** - Actively maintained (v3.1.2 released Nov 2025, v3.2.0-preview.8 in progress) - Complete rewrite in Rust - no PowerShell dependency - Cross-platform (Windows, macOS, Linux) - JSON/YAML configuration files - JSON Schema available for validation/type generation - Resources can be written in any language - Adapters for legacy PowerShell DSC resources - WinGet integration via `microsoft/winget-dsc` **Cons:** - No official TypeScript/Python/Go SDKs or language bindings - Configuration is YAML/JSON (not a real programming language) - **Does NOT auto-uninstall packages when removed from config** - Limited built-in resources - most functionality requires adapters - No native WSL configuration resource - No Start Menu/taskbar pin configuration **Resources:** - Repo: https://github.com/PowerShell/DSC - Docs: https://learn.microsoft.com/en-us/powershell/dsc/overview - Schemas: https://github.com/PowerShell/DSC/tree/main/schemas - WinGet DSC: https://github.com/microsoft/winget-dsc - Samples: https://aka.ms/dsc.yaml ### 2. Ansible **Pros:** - Mature ecosystem with large community - YAML-based with inventory system for multi-host - Idempotent task execution - Good Windows support via WinRM **Cons:** - Requires control node (Linux/WSL) to run FROM - YAML configuration (not a real language) - **Does NOT auto-uninstall packages when removed from config** - requires explicit `state: absent` - Windows modules less mature than Linux ### 3. PowerShell DSC v2 (Legacy) **Pros:** - Full PowerShell language features - Native Windows integration - Can compose configurations programmatically **Cons:** - Being superseded by DSC v3 - MOF-based, more complex - **Does NOT auto-uninstall when removed from config** ### 4. Custom TypeScript Tooling **Pros:** - Full language features (types, functions, loops, conditionals) - Can generate DSC v3 YAML from TypeScript - Type safety via JSON Schema → TypeScript generation - Familiar tooling (Bun, npm ecosystem) **Cons:** - Must build/maintain the tooling ourselves - Thin wrapper around DSC v3 CLI ### 5. WinGet Configuration (standalone) **Pros:** - Native Windows, simple YAML - Built on DSC v3 under the hood - `winget configure` command **Cons:** - Single file per configuration (limited modularity) - **Does NOT auto-uninstall when removed from config** --- ## The Uninstall Problem ### NixOS Behavior (What We Want) In NixOS, removing a package from `configuration.nix` and running `nixos-rebuild switch` will: 1. Build a new system profile without that package 2. Switch to the new profile 3. The package is no longer available ### Windows Reality (What We Get) **No Windows configuration tool provides true "remove on deletion" behavior.** | Tool | Behavior When Package Removed From Config | |------|-------------------------------------------| | DSC v3 | Stops managing it - package remains installed | | Ansible | Nothing happens - requires explicit `state: absent` | | WinGet Config | Nothing happens - package remains installed | | Chocolatey DSC | Nothing happens - package remains installed | ### Workarounds 1. **Explicit "absent" lists**: Maintain a separate list of packages that should NOT be present ```yaml packages_present: - Google.Chrome - Git.Git packages_absent: - Microsoft.Edge # Explicitly remove ``` 2. **State diffing**: Build tooling that compares current state vs desired state and generates removal tasks 3. **Full reset approach**: Periodically wipe and reapply (not practical for daily use) --- ## What Can Be Configured ### Fully Supported | Category | Method | Notes | |----------|--------|-------| | **Package Installation** | WinGet DSC | Searches winget-pkgs repository | | **Registry Settings** | `Microsoft.Windows/Registry` | Theme, Explorer options, etc. | | **Environment Variables** | PSDscResources adapter | System and user variables | | **Windows Services** | PSDscResources adapter | Start/stop, startup type | | **Windows Features** | PSDscResources adapter | Enable/disable optional features | ### Partially Supported | Category | Method | Limitations | |----------|--------|-------------| | **WSL Enable** | WindowsOptionalFeature | Works via adapter | | **WSL Distro Install** | WinGet | Install only, no config | | **File Creation** | Script resource | Not declarative, imperative script | ### Not Supported (Manual/Script Required) | Category | Why | |----------|-----| | **`.wslconfig` file** | No file content resource in DSC v3 | | **Start Menu Layout** | Complex binary format, export/import only | | **Taskbar Pinned Apps** | Complex, no resource exists | | **Default Browser** | Requires user interaction | | **File Associations** | Registry-based but complex | | **Microsoft Account Sync** | Cloud-based, not local config | --- ## Package Availability (WinGet Repository) WinGet uses the community-maintained [winget-pkgs](https://github.com/microsoft/winget-pkgs) repository. You can search at https://winget.run ### Common Developer Tools | App | WinGet ID | Available | |-----|-----------|-----------| | Chrome | `Google.Chrome` | Yes | | Firefox | `Mozilla.Firefox` | Yes | | Cursor | `Anysphere.Cursor` | Yes | | VS Code | `Microsoft.VisualStudioCode` | Yes | | Git | `Git.Git` | Yes | | Bun | `Oven-sh.Bun` | Yes | | Node.js | `OpenJS.NodeJS` | Yes | | Python | `Python.Python.3.12` | Yes | | Rust | `Rustlang.Rust.MSVC` | Yes | ### Entertainment | App | WinGet ID | Available | |-----|-----------|-----------| | Spotify | `Spotify.Spotify` | Yes | | Discord | `Discord.Discord` | Yes | | Steam | `Valve.Steam` | Yes | | Epic Games | `EpicGames.EpicGamesLauncher` | Yes | ### Utilities | App | WinGet ID | Available | |-----|-----------|-----------| | 7-Zip | `7zip.7zip` | Yes | | PowerToys | `Microsoft.PowerToys` | Yes | | Windows Terminal | `Microsoft.WindowsTerminal` | Yes | | WinRAR | `RARLab.WinRAR` | Yes | --- ## Registry Paths for Common Settings ### Theme & Appearance ``` # Dark mode (apps) HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize AppsUseLightTheme = 0 (dark) | 1 (light) # Dark mode (system) HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize SystemUsesLightTheme = 0 (dark) | 1 (light) # Taskbar alignment (Windows 11) HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced TaskbarAl = 0 (left) | 1 (center) # Accent color on title bars HKCU\SOFTWARE\Microsoft\Windows\DWM ColorPrevalence = 0 (off) | 1 (on) ``` ### Explorer Settings ``` # Show file extensions HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced HideFileExt = 0 (show) | 1 (hide) # Show hidden files HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced Hidden = 1 (show) | 2 (hide) # Show full path in title bar HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\CabinetState FullPath = 1 (show) | 0 (hide) ``` ### Privacy & Telemetry ``` # Disable Cortana HKLM\SOFTWARE\Policies\Microsoft\Windows\Windows Search AllowCortana = 0 (disabled) | 1 (enabled) # Telemetry level (requires admin) HKLM\SOFTWARE\Policies\Microsoft\Windows\DataCollection AllowTelemetry = 0 (security) | 1 (basic) | 2 (enhanced) | 3 (full) ``` --- ## DSC v3 JSON Schema (For TypeScript Generation) DSC v3 publishes JSON schemas that can be used to generate TypeScript types: ```bash # Download bundled schema curl -o schemas/dsc-config.schema.json \ https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/config/document.json # Generate TypeScript types bunx json-schema-to-typescript schemas/dsc-config.schema.json > src/types/dsc-config.d.ts ``` --- --- ## What This Project Will NOT Track Some things are better left out of declarative config: | Category | Reason | |----------|--------| | **User documents/files** | Use cloud sync (OneDrive, git) | | **Browser bookmarks/extensions** | Use browser sync | | **Application-specific settings** | Often stored in AppData, use app's sync | --- ## Next Steps 1. [ ] Decide on primary technology (DSC v3 vs custom TypeScript wrapper) 2. [ ] Set up JSON schema → TypeScript type generation 3. [ ] Create base configuration module 4. [ ] Create first host configuration (gaming-pc) 5. [ ] Document the "absent packages" pattern for uninstalls 6. [ ] Test on fresh Windows 11 VM --- ## References - [NixOS Config (inspiration)](https://github.com/ethan/nixos-config) - [DSC v3 Repository](https://github.com/PowerShell/DSC) - [WinGet DSC Resources](https://github.com/microsoft/winget-dsc) - [WinGet Package Search](https://winget.run) - [DSC v3 Documentation](https://learn.microsoft.com/en-us/powershell/dsc/overview)