Back to Articles
#windows#tooling#powershell#devops#learning

Why I Use Scoop: The Clean Package Manager for Windows Developers

How Scoop replaced my custom scripts with user-space developer tooling, shims, version retention, and manifest-defined persistence.

10 min read
2,138 words

As a software engineer working on Windows, my terminal is my primary workspace. On any given day, I rely on dozens of command-line utilities, runtimes, and developer tools: rg (ripgrep), uv, golang, jdk, maven, ant, ffmpeg, curl, and many others.

For a long time, managing these tools on Windows was frustrating.

Traditional Windows installers (.exe and .msi wizards) have always felt heavy-handed for command-line utilities. They:

  • Force you through arbitrary “Next > Next > Finish” wizards with varying default settings.
  • Litter the Windows Control Panel’s Installed Apps list with tiny CLI tools.
  • Write obscure registry keys all over the operating system.
  • Require Administrator (UAC) elevation for tools that only need to run in user space.

To avoid this, I spent years doing things the manual way—and eventually wrote a custom tool in Go to automate it. But then I found Scoop, and it solved the problem better than any custom tool ever could.


The “Manual Zip” Era (and Its Limitations)

Before Scoop, my preferred workflow was downloading standalone .zip archives directly—mostly from GitHub releases. If a tool was a freeware application hosted on its own site, my Go utility would fetch the HTML page, parse out the latest version number, and download that .zip or standalone .exe directly:

  • Self-contained single executables (like rg, curl, or jq) went into a shared C:\tools\bin\ folder that was on my user PATH.
  • Full applications with complex directories, shared libraries, and assets (like VS Code, DBeaver, JDK, or Maven) had to be extracted into their own dedicated folders (e.g., C:\tools\vscode\, C:\tools\dbeaver\). Each one then required either appending yet another directory to PATH or writing custom wrapper scripts to launch them.

I wrote a custom CLI in Go to automate this entire pipeline: querying the GitHub releases API, scraping download pages, detecting new versions, and automatically downloading and unpacking the newest binaries. While this kept my Control Panel clean and ensured I was always running the latest versions without installer bloat, maintaining custom scraping and extraction logic created new headaches:

  • No Easy Rollbacks: If an update broke something, rolling back meant manually searching for and re-downloading older archives.
  • PATH Pollution & Conflicts: Managing separate application directories meant constantly editing PATH or dealing with conflicts when multiple tools shared common DLL names or helper scripts.
  • In-Place Upgrades: Replacing active executables in-place often required extra complexity to handle file locks or kill running processes before extracting new files.
  • Incomplete Uninstalls: Cleaning up meant hunting down specific files without an automated manifest or receipt.

Enter Scoop: Windows Package Management Done Right

Scoop is a command-line installer for Windows primarily implemented in PowerShell, accompanied by compiled helper binaries for shims. It is specifically designed around developer tools and portable workflows.

Instead of reinventing the wheel with complex system services, Scoop favors portable, self-contained application layouts and keeps package-managed files organized under its own directory tree.

Here is why Scoop completely replaced my custom scripts:

1. User-Space by Default (No Admin Required for Typical Workflows)

Scoop installs everything inside your user profile (C:\Users\<user>\scoop by default). You don’t need elevated admin rights to install common runtimes like Go or OpenJDK, meaning typical developer workflows proceed without UAC prompt interruptions.

Tip: You can customize where Scoop installs apps by setting the $env:SCOOP environment variable before installing. (Note that while ordinary developer packages need no elevation, certain specialized operations or symlink behaviors may require Developer Mode or elevation depending on your Windows setup.)

2. Predictable, Isolated Directory Layouts

Each application is installed in its own versioned directory under Scoop’s app tree:

~/scoop/apps/<app-name>/<version>/

Scoop normally maintains a current directory junction pointing to the active version (though a NO_JUNCTION configuration option exists if junctions are undesirable in your environment). When you upgrade, Scoop unpacks the new version alongside the old one and switches the junction.

3. Manifest-Defined State & Config Persistence (persist/)

One classic headache with portable tools is losing your application configuration, plugins, or history whenever an update replaces the folder.

Scoop solves this through manifest-defined persistence:

  • Package authors explicitly declare in the manifest which configuration or application-data paths should survive upgrades (via the "persist" property).
  • Scoop moves those paths into ~/scoop/persist/<app>/ and links them back into ~/scoop/apps/<app>/current/ using NTFS directory junctions for folders and hard links for individual files.
  • When an app updates to a new version, the old version folder is retired, the new version points to current, and the persisted directories remain intact.
  • Because persistence is explicit and manifest-driven, Scoop doesn’t magically capture undeclared files or configs stored outside its tree (such as in global %APPDATA% or ~/.config), keeping behavior predictable and traceable.

4. Clean PATH Management via Shims

With traditional tools or manual scripts, every new tool either dumps binaries into a shared folder or appends another directory to your system PATH, eventually resulting in an unmaintainable PATH variable thousands of characters long.

Scoop solves this elegantly using shims powered by ScoopInstaller/Shim:

  • Scoop normally exposes applications by adding just one directory to your PATH: ~/scoop/shims.
  • When you install ripgrep or ffmpeg, Scoop drops a tiny, lightweight proxy executable (rg.exe, ffmpeg.exe) into ~/scoop/shims.
  • When invoked, the shim forwards commands and arguments directly to the active application binary in ~/scoop/apps/<app>/current/.
  • While shims are the primary mechanism keeping your PATH clean, manifests can also declare env_add_path or env_set when an application genuinely requires direct environment modifications.

Your PATH stays completely clean regardless of whether you have 5 tools or 200 tools installed.

5. Manifest Integrity & Clean Lifecycle

Every package in Scoop is defined by a declarative JSON manifest specifying download sources, extraction rules, and generated shims. Manifests also declare cryptographic hashes—SHA-256 by default (with support for SHA-512, SHA-1, and MD5)—ensuring Scoop automatically validates download integrity before extracting binaries.

When you run:

scoop uninstall ffmpeg

Scoop cleanly removes the shims and deletes the managed application installation directory. Persistent application data is kept by default so it can survive reinstallations; when you want to purge that data as well, simply pass the -p (or --purge) flag:

scoop uninstall -p ffmpeg

Cached package archives can also be reclaimed at any time with scoop cache rm *.

6. Effortless Upgrades, Version Retention & Switching

Because Scoop manifests point directly to official upstream releases (GitHub releases, vendor download pages, SourceForge, and project mirrors), updating your entire developer environment is as simple as:

# Update scoop and all bucket manifests
scoop update

# Update all installed packages to their latest releases
scoop update *

For engineering projects where stability or legacy compatibility matters, Scoop provides convenient version retention and switching:

  • Retained Versions: Scoop keeps previous versions installed alongside new ones until you run scoop cleanup <app> (or scoop cleanup *), giving you a safety buffer after upgrades.
  • Pin a version: scoop hold <app> prevents accidental upgrades during global updates.
  • Switch versions: If you have multiple versions installed (e.g. different JDK or Go versions), scoop reset <app>@<version> switches the active version by flipping the current junction and updating shims immediately.

7. Custom & Private Buckets

Scoop’s ecosystem is divided into “buckets” (Git repositories containing JSON manifests). Beyond the default main and extras buckets, you can create your own private bucket on GitHub, GitLab, or any Git remote:

# Add your team's private bucket
scoop bucket add internal-tools https://github.com/your-org/scoop-bucket.git

# Install private internal CLI tools
scoop install internal-cli

This makes onboarding teammates or setting up a fresh development machine instantaneous and reproducible.

8. Seamless GUI Apps & Desktop Integration

Scoop isn’t restricted to command-line utilities. Through the official extras bucket, you can install full desktop applications like VS Code, DBeaver, or Postman.

Scoop is best understood as semi-portable: it prioritizes self-contained archives over traditional setup installers, but provides desktop integration where manifests specify it:

  • Start Menu Shortcuts: For manifests that declare shortcut definitions, Scoop generates user-level Start Menu shortcuts. You can tap the Windows key, type “VS Code” or “DBeaver”, and launch them seamlessly like any natively installed app.
  • Optional Registry Integration: While Scoop avoids dumping uninstall strings into Control Panel by default, manifests can perform targeted OS integration when needed (for example, VS Code’s manifest includes optional registry integration for Windows Explorer context menus).
  • Clean Removal: When you run scoop uninstall <app>, Scoop removes the app files and deletes the generated Start Menu shortcuts automatically.

9. Environment Reproducibility (scoop export)

Setting up a new development workstation usually takes hours of manual software downloads. With Scoop, you can export your entire tooling setup into a JSON manifest:

# Export all installed apps and configured buckets
scoop export > scoopfile.json

# Restore on a new machine
scoop import scoopfile.json

Why Scoop vs. WinGet or Chocolatey?

When talking about Windows package managers, people often ask: “Why not just use Microsoft’s WinGet or Chocolatey?”

The difference comes down to fundamental design philosophy:

Feature Scoop WinGet Chocolatey
Primary model Portable & developer-oriented packages General Windows package manager Windows software deployment & automation
Portable packages Core strength Supported (configurable portable root) Supported (portable / zip packages)
Native installers Supported for select packages Strongly supported (EXE, MSI, MSIX, etc.) Strongly supported (EXE, MSI, MSIX, etc.)
User-scope installs Core workflow (~/scoop) Supported, installer-dependent Supported, but less universal
Shims Core workflow (~/scoop/shims) Not the central model Core feature for portable packages (bin/ shims)
GUI applications Supported (via extras, shortcuts) Broadly supported Broadly supported
System integration Usually minimized (manifest-defined) Often available / expected Depends on package / script
Admin-free operation Strong fit (user space by default) Supported, package-dependent Supported, package-dependent
Best fit Developer tooling & portable CLI apps Broad Windows desktop software management Enterprise Windows deployment & automation

Differing Philosophy and Architecture

Windows package managers are often compared as if they are interchangeable, but they have fundamentally different centers of gravity:

  • WinGet (Windows Package Manager) is Microsoft’s official general-purpose package manager. It supports a broad array of installer types—EXE, MSI, INNO, NULLSOFT, MSIX, APPX, and portable packages with a configurable user-scope root. WinGet excels at installing system-wide consumer and enterprise desktop software. However, because many WinGet manifests invoke vendor installers, packages frequently trigger UAC elevation prompts, run installer wizards in the background, and register entries in the Control Panel Installed Apps list.
  • Chocolatey is a mature, automation-focused package manager built largely for Windows system administrators. It can manage traditional installers as well as standalone binaries, and Chocolatey itself uses a bin shim directory similar in concept to Scoop. But Chocolatey’s default installation model is machine-wide and administrative, designed for provisioning complete enterprise Windows workstations.
  • Scoop is laser-focused on the individual developer workflow: portable CLI tools, runtimes, and self-contained desktop applications. Instead of managing full system installations, Scoop keeps everything inside a user-owned directory tree, routes commands through shims, and uses manifest-defined persistence to protect configurations across updates.

Where Scoop Falls Short (And When WinGet Wins)

Engineering is about choosing the right tradeoffs. Scoop favors user-space, portable layouts and avoids administrative elevation for its core workflow. It is therefore intentionally not suitable for:

  • System hardware drivers (GPU drivers, audio controllers).
  • Low-level network adapters and packet capture services (VPN clients, Wireshark/Npcap).
  • Deep virtualization or kernel components (WSL kernels, Hyper-V features).

For these system-level applications, Microsoft’s WinGet or official vendor installers remain the appropriate tool.

My Rule of Thumb: I use WinGet for system-level software that truly requires deep OS integration (like GPU drivers, VPN clients, or PowerToys). For everything else—programming runtimes (golang, jdk, uv), command-line tools (rg, ffmpeg, maven), and developer GUI apps (vscode, dbeaver)—Scoop is my go-to choice.


Summary

If you appreciate standalone portable binaries and dislike system-polluting installers, Scoop offers the best developer experience on Windows:

  • PowerShell-First: Built natively for Windows terminal workflows, with lightweight compiled shims.
  • User-Space by Default: Safe, predictable installations in your user profile without administrative elevation for typical developer tools.
  • Centralized Shims: A single PATH entry for all your tools, eliminating PATH pollution.
  • Manifest-Defined Persistence: Explicitly declared settings and app data survive upgrades inside ~/scoop/persist/.
  • Version Retention & Switching: Retain older versions until cleanup, and switch active versions instantly with reset.
  • Desktop Integration: Optional Start Menu shortcuts and context integration where manifests declare them.
  • Declarative Lifecycle: Transparent JSON manifests with cryptographic integrity checks and clean uninstall options (scoop uninstall -p).

Check it out at scoop.sh.