18 releases
Uses new Rust 2024
| new 0.3.2 | Jan 12, 2026 |
|---|---|
| 0.3.1 | Jan 11, 2026 |
| 0.2.12 | Jan 10, 2026 |
| 0.1.1 | Jan 4, 2026 |
#294 in Command line utilities
540KB
12K
SLoC
🍨 scoop
⚠️ Work in Progress — Under active development. API may change.
One scoop, endless envs — pyenv-style Python environment manager powered by uv
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) |
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 → "I want THIS flavor here"
.python-version → "pyenv compatibility mode"
~/.scoop/version → "My usual order"
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
Step 2: Verify
scoop --version
# → scoop 0.3.1 🍨
What this enables
- ✅ Auto-activation — enter a directory with
.scoop-version, environment activates - ✅ Tab completion — commands, environments, Python versions
- ✅ Shell wrapper —
scoop activate/deactivateworks correctly - ✅ Migration ready — import from pyenv, conda, virtualenvwrapper
- ✅ Multi-language — Korean (ko) and English (en) supported
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
Quick Start 🍨
# Stock up the freezer 🧊
scoop install 3.12
# Mix a new flavor 🍦
scoop create myproject 3.12
# Pick your flavor for this directory (auto-activates!)
scoop use myproject
(myproject) $ pip install requests
# Check what's in the freezer
scoop list # List all flavors
scoop list --pythons # List Python versions
scoop list --json # For the data nerds 🤓
# Clean up
scoop remove myproject # Melt it away 💧
Commands 🍨
Tip: All commands support
--jsonfor machine-readable output.
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 @<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) |
scoop lang --list |
List supported languages |
scoop lang --reset |
Reset to system default |
Shell Integration
| Command | Description |
|---|---|
scoop init <shell> |
Output shell initialization script |
scoop completions <shell> |
Generate completion script |
Shells supported:
bash,zsh,fish,powershell
For complete command reference, see docs/commands.md.
Architecture 🏗️
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)
├── uv/ # ⚡ uv CLI wrapper
├── output/ # 🎨 Terminal UI & JSON output
├── i18n.rs # 🌏 Internationalization (en, ko)
├── 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.
Documentation 🍨
| Guide | Description |
|---|---|
| Installation | Prerequisites and setup |
| Quick Start | Get started in 5 minutes |
| Commands | Complete command reference |
| Shell Integration | Auto-activation and configuration |
| Contributing | Development guide |
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 🍨)!
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.
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.
Dependencies
~24–43MB
~569K SLoC