This Python version requirement determines what syntax is valid in the project and affects the versions of dependencies which can be used (they must support the same Python range).
The `pyproject.toml` also lists dependencies of the project. uv supports modifying the standard dependency list from the command line with `uv add` and `uv remove`. uv also supports [extended package sources](./dependencies.md) for advanced users.
See the official [`pyproject.toml` guide](https://packaging.python.org/en/latest/guides/writing-pyproject-toml/) for more details on getting started with a `pyproject.toml`.
uv creates a virtual environment in a `.venv` directory next to the `pyproject.toml`. This virtual environment contains the project and its dependencies. It is stored inside the project to make it easy for editors to find — they need the environment to give code completions and type hints. It is not recommended to include the `.venv` directory in version control, it should be excluded via a `.gitignore` entry (or similar).
When `uv run` is invoked, it will create the project environment if it does not exist yet or ensure it is up to date if it exists. The project environment can also be explicitly created with `uv sync`.
It is _not_ recommended to modify the project environment manually, e.g., with `uv pip install`. For project dependencies, use `uv add` to add a package to the environment. For one-off requirements, use [`uvx`](./guides/tools.md) or [`uv run --with`](#running-commands-with-additional-dependencies).
## Lock file
uv creates a `uv.lock` file next to the `pyproject.toml`.
`uv.lock` is a "universal" lockfile that contains exact information about your
project's dependencies. Unlike the `pyproject.toml` which is used to specify the
broad requirements of your project, the lockfile contains the exact resolved versions
that are installed in the project environment. This file should be checked into version
control, allowing for consistent and reproducible installations across machines.
A "universal" lock file captures packages that would be installed across all possible Python markers such as operating system, architecture, and Python version.
A lock file ensures that developers working on the project are using a consistent set of package versions. Additionally, it ensures when deploying the project as an application that the exact set of used package versions is known.
The lock file is created and updated during uv invocations that use the project environment, i.e., `uv sync` and `uv run`. The lock file may also be explicitly updated using `uv lock`.
`uv.lock` is a human-readable TOML file but is managed by uv and should not be
edited manually. There is no Python standard for lock files at this time, so the format of this file is specific to uv and not generally not usable by other tools.
To avoid updating the lock file during `uv sync` and `uv run` invocations, use the `--frozen` flag.
To assert the lock file is up to date, use the `--locked` flag. If the lock file is not up to date, an error will be raised instead of updating the lock file.
## Managing dependencies
uv is capable of adding, updating, and removing dependencies using the CLI.
uv supports adding [editable dependencies](./dependencies.md#editable-dependencies), [development dependencies](./dependencies.md#development-dependencies), [optional dependencies](./dependencies.md#optional-dependencies), and alternative [dependency sources](./dependencies.md#dependency-sources). See the [dependency specification](./dependencies.md) documentation for more details.
uv will raise an error if the dependency cannot be resolved, e.g.:
When working on a project, it is installed into virtual environment at `.venv`. This environment is isolated from the current shell by default, so invocations that require the project, e.g., `python -c "import example"`, will fail. Instead, use `uv run` to run commands in the project environment:
Additional dependencies or different versions of dependencies can be requested per invocation.
The `--with` option is used to include a dependency for the invocation, e.g., to request a different version of `httpx`:
```console
$ uv run --with httpx==0.26.0 python -c "import httpx; print(httpx.__version__)"
0.26.0
$ uv run --with httpx==0.25.0 python -c "import httpx; print(httpx.__version__)"
0.25.0
```
The requested version will be respected regardless of the project's requirements. For example, even if the project requires `httpx==0.24.0`, the output above would be the same.
Scripts that declare inline metadata are automatically executed in environments isolated from the project. See the [scripts guide](./guides/scripts.md#declaring-script-dependencies) for more details.