#python-uv #python #pyenv #virtualenv #environment #uv

bin+lib scoop-uv

Scoop up your Python envs — pyenv-style workflow powered by uv

29 releases (7 breaking)

Uses new Rust 2024

0.8.3 Feb 25, 2026
0.7.2 Feb 15, 2026

#213 in Command line utilities

MIT/Apache

605KB
13K SLoC

scoop logo

🍨 scoop

⚠️ Work in Progress — Under active development. API may change.

One scoop, endless envs — pyenv-style Python environment manager powered by uv

CI Crates.io Downloads docs.rs

🍨 More badges

Security Coverage MSRV License Dependencies

Stars Forks Issues PRs Contributors

Last Commit Commit Activity Repo Size Top Language

Platform Rust Powered by uv Maintained PRs Welcome


What is scoop? 🍨

scoop scoops up uv's blazing speed — centralizing all your Python virtual environments in one place.

🍨 Think of it like running an ice cream parlor:

  • The Freezer (~/.scoop/) keeps all your flavors fresh
  • Flavors are your virtualenvs — mix once, serve anywhere
  • One scoop is all you need to get the right env
The Old Way (Yuck 🫠) The scoop Way (Fresh 🍨)
.venv scattered across projects ~/.scoop/virtualenvs/ centralized
Manual source .venv/bin/activate Auto-activate on directory entry
pyenv-virtualenv is slow uv-powered, 100x+ faster
Which Python? Which venv? Chaos. scoop doctor checks everything
Migrating envs? Manual nightmare. scoop migrate all does it all
English-only CLI Multi-language support (en, ko, ja, pt-BR)

60-Second Quick Start ⚡

# 1. Install prerequisites
curl -LsSf https://astral.sh/uv/install.sh | sh  # uv
cargo install scoop-uv                           # scoop

# 2. Initialize your shell (zsh example)
echo 'eval "$(scoop init zsh)"' >> ~/.zshrc && source ~/.zshrc

# 3. Create your first environment
scoop install 3.12
scoop create myproject 3.12

# 4. Use it (auto-activates when you enter the directory!)
scoop use myproject
(myproject) $ pip install -r requirements.txt

That's it! 🎉 Your environment is ready. For detailed docs, see Full Documentation →

Set Python 3.11.0 as Global Default

Use this when you want new shell sessions to default to an environment built on Python 3.11.0:

scoop install 3.11.0
scoop create py311 3.11.0
scoop use py311 --global

This writes py311 to ~/.scoop/version. Priority still applies: SCOOP_VERSION (shell override) and local .scoop-version take precedence.

Create a Project Env with Python 3.9.5

Use this when you want a new project environment pinned to an exact Python patch version:

scoop install 3.9.5
scoop create myproject 3.9.5
scoop info myproject

If 3.9.5 is missing, check available versions with uv python list and scoop list --pythons, then install and retry.

Uninstall Python + Associated Envs

Use this to remove one Python version and every environment using it:

# Optional preview
scoop list --python-version 3.12

# Remove Python 3.12 and all dependent environments
scoop uninstall 3.12 --cascade

# Verify cleanup
scoop list --pythons
scoop doctor

For CI/scripts, add --force to skip confirmation.

List Python Versions + Associated Envs

Use this to inspect what scoop currently manages:

# All managed Python versions
scoop list --pythons

# All environments and their Python versions
scoop list

# Environments associated with one Python version
scoop list --python-version 3.12

For scripts, use --json or --bare.

Integrate Custom or Pre-Existing Python

If the required version is not available from default scoop/uv sources:

# Recommended: explicit interpreter path
scoop create myenv --python-path /opt/python-debug/bin/python3

# Alternative: PATH-based discovery
export PATH="/opt/python-debug/bin:$PATH"
scoop create myenv 3.13

Verify integration with uv python list, scoop info myenv, and scoop doctor -v.

Project-Scoped Auto-Activation Control

Need temporary or directory-specific behavior without touching global settings?

# Temporary: current shell only
export SCOOP_NO_AUTO=1
unset SCOOP_NO_AUTO

# Directory-local behavior (writes .scoop-version in current directory)
scoop use system      # force system Python for this project
scoop use myproject   # pin this project to a specific env

# Terminal-only override (no file changes)
scoop shell system
scoop shell --unset

Installation 🍨

Prerequisites

Dependency Install Why
uv curl -LsSf https://astral.sh/uv/install.sh | sh The secret ingredient 🔮
Rust curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh Build from source

Install scoop

cargo install scoop-uv
💡 scoop: command not found?

Cargo installs binaries to ~/.cargo/bin. Ensure it's in your PATH:

# Add to ~/.zshrc or ~/.bashrc
export PATH="$HOME/.cargo/bin:$PATH"

Or restart your terminal after installing Rust.

Shell Setup

Step 1: Add to your shell config

Zsh (macOS default):

echo 'eval "$(scoop init zsh)"' >> ~/.zshrc
source ~/.zshrc

Bash:

echo 'eval "$(scoop init bash)"' >> ~/.bashrc
source ~/.bashrc

Fish:

echo 'eval (scoop init fish)' >> ~/.config/fish/config.fish
source ~/.config/fish/config.fish

PowerShell (Core or Windows PowerShell):

Add-Content $PROFILE 'Invoke-Expression (& scoop init powershell)'
. $PROFILE

Step 2: Verify

scoop --version
# → scoop 0.8.0 🍨

What this enables

  • Auto-activation — enter a directory with .scoop-version, environment activates
  • Tab completion — commands, environments, Python versions
  • Shell wrapperscoop activate/deactivate works correctly
  • Migration ready — import from pyenv, conda, virtualenvwrapper
  • Multi-language — English, 한국어, 日本語, Português (BR)

Using with pyenv

Add scoop after pyenv in your rc file (order matters — scoop gets the last scoop! 🍨):

# ~/.zshrc
eval "$(pyenv init -)"       # 1. pyenv first
eval "$(scoop init zsh)"     # 2. scoop second

Options

Variable Effect
SCOOP_NO_AUTO=1 Disable auto-activation
SCOOP_HOME=/path Custom freezer location (default: ~/.scoop)
# Example: disable auto-activation
echo 'export SCOOP_NO_AUTO=1' >> ~/.zshrc

The Freezer 🧊

Your ice cream parlor lives here:

~/.scoop/                    # 🧊 The Freezer
├── virtualenvs/             # 🍨 All your flavors
│   ├── myproject/           #    → Python 3.12 flavor
│   ├── webapp/              #    → Python 3.11 flavor
│   └── experiment/          #    → Python 3.13 flavor
└── version                  # 🥄 Default scoop preference

Version file priority (first match wins):

SCOOP_VERSION (env)"Override for this shell session" (set by scoop shell)
.scoop-version       →  "I want THIS flavor here" (local + parent walk)
~/.scoop/version     →  "My usual order" (global default)

Note: .python-version is not supported. Use .scoop-version for version pinning.


Commands 🍨

Tip: Most commands support --json for machine-readable output.

Essential Commands

Command Description
scoop create <name> [version] Create a new environment
scoop use <name> Activate environment (auto-activates in directory)
scoop list List all environments
scoop remove <name> Delete an environment
scoop install [version] Install Python version
scoop doctor Health check your setup

For the complete command reference, see Commands Documentation →

📖 Full command reference (click to expand)

Everyday Scooping

Command Description
scoop create <name> [version] Mix a new flavor (default: latest Python)
scoop use <name> Pick your flavor (auto-activates)
scoop use <name> --link Also create .venv symlink for IDE
scoop use <name> --global Set as your usual order
scoop list What's in the freezer?
scoop list --pythons What Python versions do we have?
scoop list --json Output as JSON
scoop info <name> Show detailed info about a flavor
scoop info <name> --json Output info as JSON
scoop remove <name> Melt a flavor away

Managing the Freezer

Command Description
scoop install [version] Stock up on Python (default: latest)
scoop install --stable Get the oldest supported Python (3.10)
scoop uninstall <version> Remove a Python version

Health Check 🩺

Command Description
scoop doctor Is everything fresh? Check your setup!
scoop doctor --fix Auto-fix issues where possible
scoop doctor --json Output diagnostics as JSON

Migration 🚚

Command Description
scoop migrate list Show environments to migrate
scoop migrate @env <name> Migrate a single environment
scoop migrate all Migrate all environments

Supported sources: pyenv-virtualenv, virtualenvwrapper, conda

Language 🌏

Command Description
scoop lang Show current language
scoop lang <code> Set language (en, ko, ja, pt-BR)
scoop lang --list List supported languages
scoop lang --reset Reset to system default

🌍 Want to help translate? We welcome translations in any language! See #44 to contribute.

Shell Integration

Command Description
scoop init <shell> Output shell initialization script
scoop completions <shell> Generate completion script
scoop use system Switch to system Python
scoop shell <name> Set shell env (eval required)
scoop shell --unset Clear shell env setting

Shells supported: bash, zsh, fish, powershell


Documentation 📚

📖 Read the Full Documentation →

Guide Description
Installation Guide Prerequisites, shell setup, and troubleshooting
Quick Start Get productive in 5 minutes
Command Reference Detailed documentation for every command
Shell Integration Auto-activation, version files, and configuration
Migration Guide Move from pyenv, conda, or virtualenvwrapper
Contributing Development setup and contribution guidelines

Minimum Supported Rust Version (MSRV) 🦀

Current MSRV: 1.85 (required by Rust Edition 2024)

scoop follows an N-1 MSRV policy — we support the current stable Rust and one previous version (~6 week lag).

User Type MSRV Impact Action
Binary users ✅ None Download from releases or cargo install
Source builders ⚠️ Rust >= 1.85 required Run rustup update if needed
Contributors 🔧 Test on MSRV before PR cargo +1.85 test --all-features
📋 Full MSRV policy (click to expand)

About N-1 Policy

We support the current stable Rust and one previous version (~6 week lag). MSRV updates are considered non-breaking for binary users per Cargo RFC 3537.

When We Bump MSRV

We bump when:

  • New Rust features provide significant user benefits
  • Critical dependencies require newer versions
  • Security fixes only available in newer Rust

We don't bump for:

  • Time-based schedules without clear benefits
  • Minor syntax sugar or aesthetic preferences
  • Personal developer preferences

All MSRV changes are documented in CHANGELOG.md with clear rationale.

Edition 2024 Constraints

scoop uses Rust Edition 2024, which requires:

  • Minimum Rust 1.85 (hard floor)
  • MSRV-aware resolver enabled by default
  • Cannot downgrade below 1.85 without changing edition to 2021

Automation

  • CI: Tests on both MSRV (1.85) and stable automatically
  • cargo-msrv: Verifies MSRV on Cargo.toml changes in CI
  • Badge: README badge auto-updates from Cargo.toml via shields.io
  • Local: rust-toolchain.toml auto-selects 1.85 in project directory

For more details, see our MSRV bump guide in CONTRIBUTING.md.


🏗️ Architecture (for contributors and curious minds)

Built with Rust for speed and reliability:

src/
├── cli/           # 🎮 Command parsing (clap)
│   └── commands/  # Individual command handlers
├── core/          # 🧠 Domain logic
│   ├── version    # Version file resolution
│   ├── metadata   # Virtualenv metadata (JSON)
│   ├── virtualenv # Virtualenv entity
│   ├── doctor     # Health diagnostics
│   └── migrate/   # Migration (pyenv, conda, venvwrapper)
├── shell/         # 🐚 Shell integration (bash, zsh, fish, powershell)
├── uv/            # ⚡ uv CLI wrapper
├── output/        # 🎨 Terminal UI & JSON output
├── i18n.rs        # 🌏 Internationalization (en, ko, ja, pt-BR)
├── config.rs      # ⚙️ User configuration
└── error, paths, validate  # Utilities

Design principle: The CLI outputs shell code to stdout, your shell evaluates it. Just like pyenv — battle-tested pattern.


License

Licensed under either of:

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this work shall be dual licensed as above, without any additional terms or conditions.


Support 🍨

If you find this project useful, consider buying me a coffee (or an ice cream 🍨)!

Buy Me A Coffee


Contributors ✨

Thanks goes to these wonderful people (emoji key):

azamarassy
azamarassy

🌍
Murillo Bazilio
Murillo Bazilio

🌍
Tosinibikunle
Tosinibikunle

📖

Acknowledgments 🍨

This project stands on the shoulders of giants:

  • uv by Astral — The blazing-fast Python package manager that powers scoop's backend. Without uv's incredible speed and reliability, scoop wouldn't exist. Thank you to Charlie Marsh and the entire Astral team for revolutionizing Python tooling.

  • pyenv & pyenv-virtualenv — The original inspiration for scoop's workflow. pyenv taught us how Python version management should feel, and pyenv-virtualenv showed us how to centralize virtual environments elegantly.

  • virtualenv by PyPA — The pioneer of Python virtual environments. Thank you to Ian Bicking for the original concept that changed how we isolate Python projects.

  • Python — The language that made programming accessible to everyone. scoop exists to make Python development even more delightful. Thank you to Guido van Rossum and the Python community.

  • Rust — The language that makes scoop fast, safe, and reliable. Thank you to the Rust team and Ferris 🦀 for proving that systems programming can be both powerful and enjoyable.


scoop ferris

I built scoop because I needed it — and now it's yours too. 🍨

Grab a scoop, enjoy the flavor, and if you have thoughts to share, the door to the ice cream parlor is always open.

Issues · Discussions · PRs Welcome

Dependencies

~24–42MB
~557K SLoC