pipx: The Right Way to Install Python CLI Tools
pip installs libraries. pip --user installs globally without sudo but still into a shared environment. pipx installs CLI tools each into their own isolated environment and exposes them on PATH. Knowing the difference changes how you manage your Python toolchain.
There are three ways to install a Python package globally on your machine: pip install, pip install --user, and pipx install. They are not interchangeable. Each installs into a different location with different isolation guarantees, and choosing the wrong one for CLI tools creates dependency conflicts that are difficult to diagnose and tedious to clean up.
pip install and the Shared Environment Problem
pip install installs into whichever Python environment is currently active. Without an active virtual environment, that is the system Python’s site-packages directory, which requires elevated permissions on most systems. Everything installed here is shared across every Python process on the machine. If two tools require different versions of the same dependency, only one can exist, and whichever was installed last wins.
pip install —user and Why It Is Not Enough
pip install --user avoids the permission issue by installing into a user-level site-packages directory, typically ~/.local/lib/python3.x/site-packages on Linux and macOS. No sudo is required. But the isolation problem remains. All packages installed with pip install --user share the same directory. Dependency conflicts between tools are still possible, uninstalling a tool still leaves its transitive dependencies behind, and nothing prevents one tool’s dependencies from interfering with another’s.
pip install --user is a permission workaround, not an isolation solution.
pipx and Isolated Tool Environments
pipx takes a different architectural position. When you install a tool with pipx install, it creates a dedicated virtual environment for that tool alone, installs the package and all its dependencies into that environment, and then exposes only the tool’s binary on your system PATH. The tool is available everywhere on your machine, but its dependencies are completely isolated from every other tool and from any project environment.
The consequence of this design is that two tools can depend on conflicting versions of the same library and both work correctly, because they never share an environment. Uninstalling a tool with pipx uninstall removes its environment entirely and leaves nothing behind.
# Install pipx
brew install pipx
pipx ensurepath
# Install a tool
pipx install black
# Run it anywhere
black --version
What to Install with pipx
The distinction is straightforward: pipx is for CLI tools, not for libraries your project code imports. If you import it in your source files, it belongs in your project’s virtual environment via pip, Poetry, or uv. If you run it as a command in your terminal, it belongs in pipx.
Code quality
pipx install black # code formatter
pipx install ruff # linter and formatter
pipx install flake8 # linter
pipx install pylint # linter
pipx install pyright # static type checker
Dependency management
pipx install poetry # dependency manager
pipx install pipenv # dependency manager
pipx install pdm # dependency manager
Testing and coverage
pipx install pytest
pipx install tox
pipx install coverage
Security
pipx install bandit # static security analysis
pipx install safety # known vulnerability scanning
pipx install pip-audit # dependency audit
Debugging and profiling
pipx install pdbpp # enhanced Python debugger
pipx install line-profiler
Build and release
pipx install build
pipx install twine
pipx install bump2version
pipx install semver
Documentation
pipx install mkdocs
pipx install sphinx
Scaffolding and productivity
pipx install cookiecutter # project templates
pipx install pre-commit # git hook manager
pipx install glances # system monitor
pipx install rich-cli # terminal formatting
pipx install yt-dlp # media downloader
Upgrading and Managing Tools
# Upgrade a single tool
pipx upgrade black
# Upgrade everything installed via pipx
pipx upgrade-all
# List all installed tools and their versions
pipx list
# Uninstall a tool cleanly
pipx uninstall black
What You Can Do Now
If you have CLI tools currently installed globally with pip or pip —user, migrate them:
# See what is installed globally
pip list
pip list --user
# Uninstall from the shared environment
pip uninstall black ruff flake8
# Reinstall properly with pipx
pipx install black
pipx install ruff
pipx install flake8
Run pipx list afterwards to confirm each tool has its own isolated environment. Your project virtual environments will be cleaner, your tools will not conflict with each other, and uninstalling any one of them will leave no trace behind.