Prerequisites
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
diffandapplycommand.
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 configurecommand
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:
- Build a new system profile without that package
- Switch to the new profile
- 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
-
Explicit "absent" lists: Maintain a separate list of packages that should NOT be present
packages_present: - Google.Chrome - Git.Git packages_absent: - Microsoft.Edge # Explicitly remove -
State diffing: Build tooling that compares current state vs desired state and generates removal tasks
-
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 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:
# 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
- Decide on primary technology (DSC v3 vs custom TypeScript wrapper)
- Set up JSON schema → TypeScript type generation
- Create base configuration module
- Create first host configuration (gaming-pc)
- Document the "absent packages" pattern for uninstalls
- Test on fresh Windows 11 VM