Add Packages and Run Your Project with uv
Creating a project is only the starting point. The real beginner question is what to do next. This is where uv becomes practical: add a package, let uv update the lockfile and environment, run the code in that environment, and repeat without losing control.
UV Series
Learn the day-to-day project commands you will use most often.
Use uv add to declare dependencies and uv run to execute code in the project environment.
You will understand the loop of add, run, sync, upgrade, and remove.
Use uv add Instead of a Bare pip install
From inside your project folder, add a dependency:
uv add requests
This does three jobs in one motion:
- it updates
pyproject.tomlwith the dependency declaration - it updates
uv.lockwith exact resolved versions - it updates the project environment so the package is available immediately
That is the big beginner win. You do not have to separately remember to edit one file, generate another file, and install into the environment with a fourth command.
Write a Small Script That Proves the Dependency Is Real
Edit main.py so it imports the package you just added:
import requests
def main():
print("requests version:", requests.__version__)
if __name__ == "__main__":
main()
Now run it with:
uv run main.py
If the project is in sync, the script runs in the managed environment and prints the installed version.
This is the beginner loop you want to internalize: declare the dependency with uv add, then run the program with uv run.
uv run is doing
Why uv run Matters More Than It Looks
Before uv runs your command, it checks that the lockfile matches the project declaration and that the environment matches the lockfile. In other words, it helps keep the project aligned automatically.
That is why this works so well for beginners. Instead of remembering three maintenance steps, you learn one reliable way to run commands inside the project.
You can also run shell commands or CLIs this way:
uv run python main.py
uv run -- python -m http.server 8000
That second form with -- is useful when you want to be explicit that everything after it belongs to the command you are running.
When to Use uv sync Instead of Only uv run
uv run handles most beginner cases, but sometimes you want to update the environment first and then work inside it more manually. That is when uv sync becomes useful:
uv sync
After syncing, you can activate the environment yourself if you want:
source .venv/bin/activate
On Windows PowerShell, that activation command is different, but the broader point stays the same: uv sync prepares the environment, and activation is only needed when you want to run commands directly without uv run.
uv run for everyday work until you have a reason to activate the environment yourself. It keeps the beginner workflow simpler and more consistent.
Remove Packages and Upgrade Specific Ones
Projects change. uv gives you named commands for that too.
uv remove requests
uv add requests
uv lock --upgrade-package requests
uv remove removes the dependency from the project. uv lock --upgrade-package requests asks uv to update that one package while keeping the rest of the lockfile stable when possible.
That is a better long-term story than randomly upgrading everything because you happened to reinstall an environment from scratch.
The Everyday uv Project Loop
uv init my-project
cd my-project
uv add requests
uv run main.py
uv add --dev ruff
uv run ruff check .
uv add --dev ty
uv run ty check
You now know enough uv to work on normal Python projects without falling back to ad hoc package management. The next two articles use that project foundation to add tools that improve feedback and consistency automatically.
Frequently Asked Questions
These are the practical questions beginners usually ask at this stage of the uv workflow.
Why use uv add instead of pip install requests inside the environment?
Because uv add updates the project declaration, lockfile, and environment together. That keeps the project reproducible instead of relying on undocumented local state.
When should I use uv sync?
Use it when you want to prepare the environment explicitly before working inside it, especially if you plan to activate .venv or run several commands manually.
Does uv run always create a new environment?
No. It uses the project environment and keeps it in sync. It is not the same as a one-off temporary tool environment.
Can I still activate .venv if I want to?
Yes. uv does not forbid activation. It just makes it optional for most normal project commands.
What if I already have a requirements.txt file?
uv can help migrate that workflow too, but for a fresh beginner project it is easier to start with uv add and let pyproject.toml plus uv.lock become your source of truth.
Conclusion
A beginner who understands uv add and uv run is already in a much stronger place than someone who is still installing packages into whichever interpreter happens to be active.
Now that the project itself is stable, it is time to add tools that make the codebase cleaner and easier to maintain automatically.
Raell Dottin
Comments