Skip to main content

Add Packages and Run Your Project with uv

UV Series · Daily Workflow

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

Goal

Learn the day-to-day project commands you will use most often.

Main idea

Use uv add to declare dependencies and uv run to execute code in the project environment.

Outcome

You will understand the loop of add, run, sync, upgrade, and remove.

The key beginner upgrade Stop thinking of package installation as something you do to your computer. In a uv project, you add packages to the project, not to your machine in general.
Add a dependency

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.toml with the dependency declaration
  • it updates uv.lock with 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.

Use the dependency

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.

What 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.

Manual sync

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.

Good default habit Use uv run for everyday work until you have a reason to activate the environment yourself. It keeps the beginner workflow simpler and more consistent.
Upgrade and cleanup

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.

A practical checklist

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.

FAQ

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.

Next in the series

Add Ruff to Automate Python Code Quality

Raell Dottin

Comments