How to Run Python CLI Tools with uvx: Complete Command Guide
Tired of installing one-off Python CLI tools that clutter your system? I was too - until I discovered uvx. It lets me run Python CLI tools without polluting my environment, and it’s 10-100x faster than pip.
Let me show you every uvx command you’ll actually use.
What is uvx?
uvx is simply an alias for uv tool run. It’s Astral’s answer to running Python tools ephemerally - meaning the tool runs in an isolated environment, does its job, and leaves no trace on your system.
Think of it as “npx for Python” - you run a tool once without installation, and it just works.
Why this matters:
- No environment pollution: Your system stays clean
- Version isolation: Each tool runs with its exact dependencies
- Blazing fast: uv is 10-100x faster than pip for resolution and installation
Basic uvx Commands
Running a tool is straightforward:
# Basic syntaxuvx <tool-name>
# Real examplesuvx pycowsay 'Hello World'uvx ruff check .uvx black .uvx mypy src/The first run downloads and caches the tool. Subsequent runs are much faster.
When you run uvx, you’ll see output like:
Resolved 1 package in 167msInstalled 1 package in 12msThis shows uvx resolving the package, installing it to its cache, and running it - all in milliseconds.
Passing Arguments to Tools
Everything after the tool name gets passed directly to the tool:
# Pass arguments to the tooluvx pycowsay 'Custom message here'uvx ruff check . --fixuvx black src/ --checkuvx http https://example.comThis is intuitive - uvx passes your arguments through to the underlying tool without interference.
Version Pinning and Constraints
Need a specific version? Use the @ syntax:
# Run exact version
# Run latest versionuvx ruff@latest checkFor more complex version requirements, use the --from flag with PEP 440 specifiers:
# Version rangeuvx --from 'ruff>0.2.0,<0.3.0' ruff check
# Minimum versionuvx --from 'ruff>=0.3.0' ruff checkThe --from flag changes the package source entirely, which is useful when you need fine-grained control over versions.
Running Tools from Different Packages
Sometimes the CLI command name differs from the package name. Use --from to specify the package explicitly:
# httpie CLI is in the 'httpie' packageuvx --from httpie http
# Sometimes needed for conflicting namesuvx --from package-name tool-nameThis solves the “tool not found” problem when a package provides multiple CLI commands.
Using Extras
Many packages have optional extras that include additional tools:
# Install with extrasuvx --from 'mypy[faster-cache,reports]' mypy --xml-report report
# Common extras patternsuvx --from 'package[extra1,extra2]' tool-nameExtras are useful for enabling specific features without installing everything.
Running from Git Sources
Want to test an unreleased version or a PR? Run directly from git:
# From git repositoryuvx --from git+https://github.com/httpie/cli httpie
# From specific branch or taguvx --from git+https://github.com/user/repo@branch-name tool-name
# From pull requestuvx --from git+https://github.com/user/repo@pull/123/head tool-nameThis is invaluable for testing bleeding-edge features or contributing to open source.
Adding Plugins with —with
Need a temporary plugin? Use --with:
# Add plugins temporarilyuvx --with mkdocs-material mkdocs --help
# Multiple pluginsuvx --with plugin1 --with plugin2 tool-nameCommon use cases:
- mkdocs themes
- pytest plugins
- black configurations
The --with flag adds packages to the tool’s environment without modifying your system.
Common Practical Examples
Here are commands I use daily:
Code Quality Tools
# Linting with ruffuvx ruff check .uvx ruff@latest check . --fix
# Code formattinguvx black .uvx isort .
# Type checkinguvx mypy src/uvx pyright src/Development Tools
# HTTP clientsuvx http GET https://api.example.comuvx httpie https://example.com
# Package toolsuvx pip-audit # Check for vulnerabilitiesuvx pip-tools compile # Compile requirements
# Testinguvx pytest tests/uvx coverage run -m pytestFun/Practical Tools
# Just for funuvx pycowsay 'Hello from uvx'uvx cowsay 'Welcome to uvx'
# Generate passwordsuvx --with passlib python -c "from passlib.hash import bcrypt; print(bcrypt.hash('password'))"uvx vs uv tool run
They’re exactly the same. uvx is a convenient alias for uv tool run. Use whichever reads better in your workflow:
# These are identicaluvx ruff check .uv tool run ruff checkPerformance Tips
- First run: Downloads and caches the tool (~1-2 seconds)
- Subsequent runs: Nearly instant (milliseconds)
- CI/CD: Pin versions for reproducibility
- Debugging: Use
--no-cachewhen troubleshooting
# Disable cache if neededuvx --no-cache ruff check .Troubleshooting Common Issues
Tool not found
# Try specifying package explicitlyuvx --from package-name tool-nameVersion conflicts
# Use version constraintsuvx --from 'package>1.0,<2.0' toolPermission errors: uvx handles this automatically. No sudo needed.
Quick Reference
| Use Case | Command |
|---|---|
| Basic run | uvx tool-name |
| With args | uvx tool arg1 arg2 |
| Specific version | uvx [email protected] |
| Version range | uvx --from 'tool>1.0' tool |
| From package | uvx --from pkg tool |
| With plugins | uvx --with plugin tool |
| From git | uvx --from git+https://... tool |
Conclusion
uvx is now my go-to for running Python CLI tools. No more pip install for one-off tools. No more environment pollution. Just run and done.
The key commands to remember:
uvx tool- basic usageuvx tool@version- version pinninguvx --from- flexible sourcinguvx --with- adding plugins
Try it now:
uvx pycowsay "uvx rocks!"Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments