Skip to main content

How uv run Works, Including flet build and flet run

Python · uv · Command execution

The whole command becomes much easier to reason about once you stop treating it as magic and start treating it as an explicit handoff between environment preparation and target execution.

UV Series

Main claim

uv run prepares the project context, then hands control to the command you actually want to run.

Repository examples

The python-uv repo uses uv run for nox, pytest, ruff, ty, pre-commit, and MkDocs.

Reader outcome

You should leave able to identify exactly which part of a command line belongs to uv and which part does not.

Thesis

uv run Prepares the Context. The Target Command Owns the Rest.

The best explanation of uv run is also the simplest: it is the boundary between environment preparation and actual execution. When you invoke uv run inside a project, uv ensures that the project environment is up to date before it hands execution off to the target command.

That handoff model is what allows one command family to run Python entry points, external executables, linters, formatters, documentation servers, and even framework-specific build tools without becoming conceptually muddy.

The rule that clarifies everything uv owns preparation. The invoked command owns meaning.
Repository examples

How the Handoff Looks in a Serious Repository

In the python-uv repository, uv run is the standard entry point for ordinary work. But notice what that means. uv is not “being” pytest, nox, ruff, ty, or mkdocs. It is preparing the project environment in which those commands are then executed.

uv run nox -s test
uv run pytest tests/tools/test__logger.py
uv run ruff format .
uv run ruff check . --fix
uv run ty check
uv run mkdocs serve

Each line follows the same logic. uv run gives the command the correct project context; the command that follows decides what happens after the handoff.

Argument ownership

Why Flags Sometimes Seem to “Belong to the Wrong Tool”

Most confusion around uv run is really confusion about argument ownership. Options intended for uv must appear before the target command. Everything after the command belongs to that command.

uv run --python 3.12 -- python -c "import sys; print(sys.version)"
uv run ruff check . --fix
uv run pytest -q
uv run mkdocs serve

In the first example, --python 3.12 belongs to uv. In the second, third, and fourth examples, the options belong to the command that uv is running. This is not an incidental syntactic rule. It is the consequence of the handoff model itself.

What uv run guarantees

Why It Is Better Than “Just Activate the Environment and Hope”

In a project, uv run checks that the lockfile is current with respect to pyproject.toml and that the environment is current with respect to the lockfile before it runs the command. That is why it is so useful in a team setting: it reduces the number of silent ways contributors drift from the declared project state.

You can, of course, activate the virtual environment manually after uv sync. There is nothing unlawful about that. But uv run is the cleaner default because it keeps execution tied to the project lifecycle rather than to whatever state your shell happens to be in.

Including Flet

The Same Logic Applies to flet run and flet build

The title mentions Flet for a reason. It is an unusually good way to see the handoff clearly.

uv run flet run app.py
uv run flet build macos

In both examples, only uv run belongs to uv. The words flet, run, build, and macos belong to Flet's command interface. Once you see that division, the mental model becomes stable enough to generalize to any other tool.

Do not misassign the flags If an option “does not work,” the first question is usually not whether uv is broken. It is whether the option was mentally assigned to the wrong command surface.
One more useful capability

uv run Can Also Request Extra Dependencies for a Single Invocation

There is one more reason uv run deserves respect: it can temporarily request additional dependencies for a single invocation.

uv run --with httpx==0.26.0 python -c "import httpx; print(httpx.__version__)"

That is a strong example of what uv is doing. It is not only running a command. It is shaping the environment in which the command runs.

FAQ

Frequently Asked Questions

These are the practical questions that a careful reader should be able to answer before treating the workflow as production-ready.

What does uv run do before executing a command in a project?

It ensures the project environment is up to date before handing execution off to the target command.

Who owns the flags after the target command name?

The target command does. Options intended for uv must appear before the command you are invoking.

Why use uv run instead of activating .venv manually?

Because it keeps execution tied to the project's declared and synchronized state instead of relying on ambient shell state.

What part of uv run flet build macos belongs to uv?

Only uv run. The rest belongs to Flet.

Can uv run add extra dependencies for one invocation?

Yes. The --with option can request additional dependencies or alternate versions for a single run.

References

References

uv projects guide: running commands

uv project run concept

uv CLI reference: run

python-uv README

python-uv noxfile.py

Conclusion

The important habit is to read uv run as a handoff. Once you do, the command line stops feeling slippery: uv prepares the context, and the invoked tool owns the work that follows.

Comments