Skip to content

benbenbang/uv-shell

Repository files navigation

uv-shell

A fast Rust binary that creates and activates Python virtual environments using uv. Zero external crate dependencies.

Features

  • uv-shell -- Create .venv if missing, set a smart prompt (<project>-py<version>), and spawn an activated subshell
  • uv-shell anchor -- Print shell commands that activate .venv in the current shell (for use in shell rc files)
  • All uv venv options forwarded transparently (--python, --seed, --clear, --prompt, etc.)
  • Cross-platform: Unix (exec), Windows (PowerShell + CMD)
  • Shell completions for bash, zsh, fish, nushell, and PowerShell
  • uv plugin wrapper (adds-on) -- Enables uv shell as a native subcommand and injects plugins into uv <TAB> completions

Install

Homebrew (macOS/Linux)

brew tap benbenbang/forge
brew install uv-shell

From source

cargo install --path .

Or build locally:

cargo build --release
# binary at target/release/uv-shell

Requirements: uv must be installed and on PATH.

Usage

Create and activate a virtual environment

# Create .venv (if missing) and spawn an activated subshell
uv-shell

# With a specific Python version
uv-shell -p 3.12

# With seed packages (pip, setuptools, wheel)
uv-shell --seed

# Re-create an existing venv
uv-shell --clear

# Override just the project name (keeps -pyX.XX suffix)
uv-shell --prefix myproject       # → myproject-py3.12

# Full custom prompt (replaces everything)
uv-shell --prompt my-env          # → my-env

All options are forwarded to uv venv. Run uv-shell --help or uv venv --help for the full list.

To exit the activated subshell, press Ctrl + D.

Auto-activate with anchor

Add to your shell rc file to auto-activate .venv when it exists in the current directory:

bash / zsh (~/.bashrc or ~/.zshrc):

eval "$(uv-shell anchor)"

fish (~/.config/fish/config.fish):

uv-shell anchor | source

PowerShell ($PROFILE):

uv-shell anchor | Invoke-Expression

nushell (config.nu):

# save to a file and source it
uv-shell anchor --shell nushell | save -f ~/.venv-anchor.nu
source ~/.venv-anchor.nu

The anchor command auto-detects your shell. Override with --shell:

uv-shell anchor --shell powershell
uv-shell anchor --shell fish
uv-shell anchor --shell cmd

Shell completions

# bash
eval "$(uv-shell completions bash)"

# zsh (add to fpath)
uv-shell completions zsh > "${fpath[1]}/_uv-shell"

# fish
uv-shell completions fish > ~/.config/fish/completions/uv-shell.fish

# nushell
uv-shell completions nushell | save -f ~/.config/nushell/uv-shell-completions.nu

# PowerShell (add to $PROFILE)
uv-shell completions powershell >> $PROFILE

uv plugin wrapper (adds-on)

The adds-on directory contains a small Rust binary also named uv that acts as a plugin dispatcher. When installed before the real uv in PATH, it enables:

  • uv shell → automatically finds and runs uv-shell
  • uv <any-plugin> → finds and runs uv-<plugin> from PATH
  • uv <TAB> → shows installed plugins alongside built-in uv subcommands
  • uv shell <TAB> → shows uv-shell's own options

Setup (after brew install uv-shell)

1. Add to ~/.zshrc (permanent, one line):

export PATH="$(brew --prefix uv-shell)/libexec/bin:$PATH"

2. Install completions once:

# zsh — auto-loaded every session, plugins discovered dynamically at tab-press time
uv generate-shell-completion zsh > "${fpath[1]}/_uv"

# nushell — then add `use ~/.config/nushell/completions/uv.nu` to config.nu
uv generate-shell-completion nushell | save ~/.config/nushell/completions/uv.nu

# bash
echo 'eval "$(uv generate-shell-completion bash)"' >> ~/.bashrc

# fish
uv generate-shell-completion fish > ~/.config/fish/completions/uv.fish

zsh: no eval, no reloading — new plugins appear at tab-press time automatically.

nushell / bash / fish: re-run the above after installing new plugins.

Optional: skip PATH scan on every uv call:

export UV_REAL_PATH="/opt/homebrew/bin/uv"

How it works

uv shell          →  finds uv-shell in PATH  →  exec uv-shell
uv add requests   →  no uv-add plugin found  →  exec real uv add requests
uv <TAB>          →  real uv completions + discovered plugins injected
uv shell <TAB>    →  delegates to _uv-shell() from uv-shell's own completions

Any executable named uv-<name> on PATH is automatically discovered — no registration needed.

How it works

Step What happens
1. Resolve path Canonicalize .venv relative to CWD
2. Create venv Run uv venv <path> with forwarded options (if .venv missing or --clear)
3. Update prompt Patch pyvenv.cfg with prompt = <project>-py<version> (skipped if --prompt given)
4. Activate Unix: exec $SHELL with VIRTUAL_ENV and PATH set (replaces process, no nesting) / Windows: spawn PowerShell or CMD with env vars

The anchor command prints shell-appropriate commands to set VIRTUAL_ENV, PIP_REQUIRE_VIRTUALENV, and prepend the venv bin/Scripts directory to PATH.

License

MIT

About

A rust wrapper for uv - a python deps manager

Resources

License

Stars

Watchers

Forks

Sponsor this project

Packages

 
 
 

Contributors