# How to use a uv lockfile for reproducible Python environments

[Lockfiles](https://pydevtools.com/handbook/explanation/what-is-a-lock-file.md) ensure your Python project uses identical dependency versions across different machines and deployments. This guide shows how to use [uv](https://pydevtools.com/handbook/reference/uv.md)'s lockfile system to create reproducible environments.

## Creating your first lockfile

Start with a new project:

```bash
uv init reproducible-demo
cd reproducible-demo
```

Add some dependencies:

```bash
uv add requests pandas
```

uv automatically generates `uv.lock` with pinned versions of `requests`, `pandas`, and all their dependencies.

> [!IMPORTANT]
> The lockfile should be committed to version control.

## How uv sync works with lockfiles

Running `uv sync` ensures your environment matches your project configuration:

```bash
uv sync
```

uv's behavior depends on the lockfile state:
- If `uv.lock` matches `pyproject.toml`: Installs exact versions from the lockfile
- If lockfile is outdated or missing: Re-resolves dependencies, updates the lockfile (equivalent to `uv lock`), then installs dependencies

## Enforcing strict lockfile usage

To guarantee installation from an existing lockfile without updates:

```bash
uv sync --locked
```

> [!WARNING]
> If the lockfile doesn't match `pyproject.toml`, uv will error instead of updating dependencies. This is essential for CI/CD pipelines where you want reproducible builds.


## Verifying lockfile status

Check if your lockfile matches your project configuration:

```bash
uv lock --check
```

This validates that `uv.lock` is current with `pyproject.toml` without making changes.

## Manually updating the lockfile

Explicitly update the lockfile without syncing the environment:

```bash
uv lock
```

This resolves dependencies from `pyproject.toml` and updates `uv.lock` but doesn't install packages.

## Upgrading dependencies

Update all packages to their latest compatible versions:

```bash
uv lock --upgrade
```

Upgrade specific packages while preserving others:

```bash
uv lock --upgrade-package requests
uv lock --upgrade-package pandas==2.1.0
```

These flags also work with `uv sync` to update and install in one step:

```bash
uv sync --upgrade-package requests
```

## Best practices for reproducible environments

- Always commit `uv.lock` to version control
- Use `--locked` in CI/CD to prevent unexpected dependency changes
- Run `uv lock --check` before deployments to verify consistency
- Regularly upgrade with `uv lock --upgrade` for security updates
- Understand the difference between `uv sync` (may update lockfile) and `uv sync --locked` (strict lockfile usage)
