> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/astral-sh/uv/llms.txt
> Use this file to discover all available pages before exploring further.

# Dependency Management

> Learn how to add, remove, and manage dependencies in uv projects

Dependencies of a project are defined in several fields in `pyproject.toml`. uv supports modifying dependencies with `uv add` and `uv remove`, or by editing the `pyproject.toml` directly.

## Dependency Fields

Dependencies are organized into different tables:

<CardGroup cols={2}>
  <Card title="project.dependencies" icon="box">
    Published runtime dependencies
  </Card>

  <Card title="project.optional-dependencies" icon="puzzle-piece">
    Published optional dependencies (extras)
  </Card>

  <Card title="dependency-groups" icon="layer-group">
    Local development dependencies (PEP 735)
  </Card>

  <Card title="tool.uv.sources" icon="code-branch">
    Alternative dependency sources
  </Card>
</CardGroup>

<Note>
  The `project.dependencies` and `project.optional-dependencies` fields can be used even if the project isn't going to be published. `dependency-groups` is a recently standardized feature that may not be supported by all tools yet.
</Note>

## Adding Dependencies

Add a dependency to your project:

```bash theme={null}
uv add httpx
```

This updates `pyproject.toml`:

```toml pyproject.toml theme={null}
[project]
name = "example"
version = "0.1.0"
dependencies = ["httpx>=0.27.2"]
```

### Version Constraints

By default, uv adds a constraint for the most recent compatible version. Customize the bound type:

```bash theme={null}
# Add with specific constraint
uv add "httpx>=0.20"

# Add exact version
uv add "httpx==0.27.2"

# Add with different bound type
uv add httpx --bounds ">=,<"
```

### Importing from requirements.txt

Import dependencies from a `requirements.txt` file:

```bash theme={null}
uv add -r requirements.txt
```

## Removing Dependencies

Remove a dependency:

```bash theme={null}
uv remove httpx
```

Remove from specific tables with flags:

```bash theme={null}
uv remove httpx --dev
uv remove httpx --optional network
uv remove httpx --group test
```

## Changing Dependencies

Update an existing dependency's constraints:

```bash theme={null}
uv add "httpx>0.1.0"
```

<Info>
  This changes constraints in `pyproject.toml`. The locked version only changes if necessary to satisfy new constraints. To force an upgrade, use `--upgrade-package`:

  ```bash theme={null}
  uv add "httpx>0.1.0" --upgrade-package httpx
  ```
</Info>

Change dependency source (e.g., to local development version):

```bash theme={null}
uv add "httpx @ ../httpx"
```

## Platform-Specific Dependencies

Use [environment markers](https://peps.python.org/pep-0508/#environment-markers) for platform-specific dependencies:

```bash theme={null}
# Linux only
uv add "jax; sys_platform == 'linux'"

# Python 3.11+
uv add "numpy; python_version >= '3.11'"
```

Resulting `pyproject.toml`:

```toml pyproject.toml theme={null}
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
  "jax; sys_platform == 'linux'",
  "numpy; python_version >= '3.11'",
]
```

### Available Markers

Common environment markers:

* `sys_platform` - OS platform ("linux", "darwin", "win32")
* `platform_machine` - Architecture ("x86\_64", "aarch64")
* `python_version` - Python version ("3.11", "3.12")
* `implementation_name` - Python implementation ("cpython", "pypy")

## Project Dependencies

The `project.dependencies` table represents dependencies used when:

* Publishing to PyPI
* Building wheels
* Installing the package

### Dependency Specifier Syntax

Dependency specifiers follow [PEP 508](https://peps.python.org/pep-0508/) syntax:

```toml pyproject.toml theme={null}
[project]
name = "albatross"
version = "0.1.0"
dependencies = [
  # Version range
  "tqdm >=4.66.2,<5",
  # Exact version
  "torch ==2.2.2",
  # With extras
  "transformers[torch] >=4.39.3,<5",
  # Platform-specific
  "importlib_metadata >=7.1.0,<8; python_version < '3.10'",
]
```

### Version Specifier Operators

<Tabs>
  <Tab title="Common">
    * `>=1.2.3` - Greater than or equal
    * `<2.0` - Less than
    * `==1.2.3` - Exact version
    * `!=1.4.0` - Not equal
  </Tab>

  <Tab title="Advanced">
    * `~=1.2` - Compatible release (`>=1.2, <2.0`)
    * `~=1.2.3` - Compatible release (`>=1.2.3, <1.3`)
    * `==2.1.*` - Wildcard (any `2.1.x` version)
  </Tab>
</Tabs>

Specifiers can be combined:

```toml theme={null}
dependencies = ["foo >=1.2.3,<2,!=1.4.0"]
```

## Dependency Sources

The `tool.uv.sources` table extends standard dependencies with alternative sources during development.

### Why Use Sources?

Sources enable patterns not supported by `project.dependencies`:

* Editable installations
* Relative paths
* Git repositories
* Local development versions

<Warning>
  Sources are uv-specific and ignored by other tools. If another tool is used, source metadata must be re-specified in that tool's format.
</Warning>

### Index Sources

Install from a specific package index:

```bash theme={null}
uv add torch --index pytorch=https://download.pytorch.org/whl/cpu
```

Resulting configuration:

```toml pyproject.toml theme={null}
[project]
dependencies = ["torch"]

[tool.uv.sources]
torch = { index = "pytorch" }

[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"
```

Using `index` source pins the package to that index exclusively.

#### Explicit Indexes

Mark an index as explicit to use it only for pinned packages:

```toml pyproject.toml theme={null}
[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"
explicit = true
```

### Git Sources

Install from Git repositories:

```bash theme={null}
# HTTPS
uv add git+https://github.com/encode/httpx

# SSH
uv add git+ssh://git@github.com/encode/httpx
```

With specific references:

<Tabs>
  <Tab title="Tag">
    ```bash theme={null}
    uv add git+https://github.com/encode/httpx --tag 0.27.0
    ```

    ```toml pyproject.toml theme={null}
    [tool.uv.sources]
    httpx = { git = "https://github.com/encode/httpx", tag = "0.27.0" }
    ```
  </Tab>

  <Tab title="Branch">
    ```bash theme={null}
    uv add git+https://github.com/encode/httpx --branch main
    ```

    ```toml pyproject.toml theme={null}
    [tool.uv.sources]
    httpx = { git = "https://github.com/encode/httpx", branch = "main" }
    ```
  </Tab>

  <Tab title="Commit">
    ```bash theme={null}
    uv add git+https://github.com/encode/httpx --rev 326b943
    ```

    ```toml pyproject.toml theme={null}
    [tool.uv.sources]
    httpx = { git = "https://github.com/encode/httpx", rev = "326b943" }
    ```
  </Tab>
</Tabs>

#### Git Subdirectories

For packages not in the repository root:

```bash theme={null}
uv add git+https://github.com/langchain-ai/langchain#subdirectory=libs/langchain
```

#### Git LFS Support

Configure Git LFS per source:

```bash theme={null}
uv add --lfs git+https://github.com/astral-sh/lfs-cowsay
```

```toml pyproject.toml theme={null}
[tool.uv.sources]
lfs-cowsay = { git = "https://github.com/astral-sh/lfs-cowsay", lfs = true }
```

* `lfs = true` - Always fetch LFS objects
* `lfs = false` - Never fetch LFS objects
* Omitted - Use `UV_GIT_LFS` environment variable

### URL Sources

Install from direct URLs (wheels or source distributions):

```bash theme={null}
uv add "https://files.pythonhosted.org/packages/.../httpx-0.27.0.tar.gz"
```

```toml pyproject.toml theme={null}
[tool.uv.sources]
httpx = { url = "https://files.pythonhosted.org/packages/.../httpx-0.27.0.tar.gz" }
```

### Path Sources

Install from local paths:

<Tabs>
  <Tab title="Wheel">
    ```bash theme={null}
    uv add ./foo-0.1.0-py3-none-any.whl
    ```
  </Tab>

  <Tab title="Source Distribution">
    ```bash theme={null}
    uv add ./foo-0.1.0.tar.gz
    ```
  </Tab>

  <Tab title="Directory">
    ```bash theme={null}
    uv add ./packages/foo
    ```
  </Tab>
</Tabs>

Path sources support absolute and relative paths:

```toml pyproject.toml theme={null}
[tool.uv.sources]
foo = { path = "./packages/foo" }
bar = { path = "/absolute/path/to/bar" }
```

#### Editable Path Dependencies

Request editable installation for directories:

```bash theme={null}
uv add --editable ./packages/foo
```

```toml pyproject.toml theme={null}
[tool.uv.sources]
foo = { path = "./packages/foo", editable = true }
```

<Tip>
  For multiple related packages, consider using [workspaces](/concepts/workspaces) instead.
</Tip>

### Workspace Sources

Declare dependencies on workspace members:

```toml pyproject.toml theme={null}
[project]
dependencies = ["foo==0.1.0"]

[tool.uv.sources]
foo = { workspace = true }

[tool.uv.workspace]
members = ["packages/foo"]
```

Workspace members are always [editable](#editable-dependencies).

### Platform-Specific Sources

Limit sources to specific platforms using markers:

```toml pyproject.toml theme={null}
[tool.uv.sources]
httpx = {
  git = "https://github.com/encode/httpx",
  tag = "0.27.2",
  marker = "sys_platform == 'darwin'"
}
```

On macOS, `httpx` installs from GitHub. On other platforms, it falls back to PyPI.

### Multiple Sources

Provide multiple sources disambiguated by environment markers:

```toml pyproject.toml theme={null}
[project]
dependencies = ["httpx"]

[tool.uv.sources]
httpx = [
  { git = "https://github.com/encode/httpx", tag = "0.27.2", marker = "sys_platform == 'darwin'" },
  { git = "https://github.com/encode/httpx", tag = "0.24.1", marker = "sys_platform == 'linux'" },
]
```

Platform-specific indexes:

```toml pyproject.toml theme={null}
[tool.uv.sources]
torch = [
  { index = "torch-cpu", marker = "platform_system == 'Darwin'"},
  { index = "torch-gpu", marker = "platform_system == 'Linux'"},
]

[[tool.uv.index]]
name = "torch-cpu"
url = "https://download.pytorch.org/whl/cpu"
explicit = true

[[tool.uv.index]]
name = "torch-gpu"
url = "https://download.pytorch.org/whl/cu124"
explicit = true
```

### Disabling Sources

Ignore `tool.uv.sources` (e.g., to test published metadata):

```bash theme={null}
uv lock --no-sources
```

## Optional Dependencies

Optional dependencies (extras) reduce the default dependency tree for libraries.

### Defining Optional Dependencies

```toml pyproject.toml theme={null}
[project]
name = "pandas"
version = "1.0.0"

[project.optional-dependencies]
plot = ["matplotlib>=3.6.3"]
excel = [
  "odfpy>=1.4.1",
  "openpyxl>=3.1.0",
  "xlrd>=2.0.1",
]
```

### Adding Optional Dependencies

```bash theme={null}
uv add httpx --optional network
```

### Installing with Extras

Users install extras with bracket syntax:

```bash theme={null}
uv pip install "pandas[plot,excel]"
```

### Extra-Specific Sources

Use different sources for different extras:

```toml pyproject.toml theme={null}
[project.optional-dependencies]
cpu = ["torch"]
gpu = ["torch"]

[tool.uv.sources]
torch = [
  { index = "torch-cpu", extra = "cpu" },
  { index = "torch-gpu", extra = "gpu" },
]
```

## Development Dependencies

Development dependencies are local-only and not published to PyPI.

### Adding Development Dependencies

```bash theme={null}
uv add --dev pytest
```

This creates a `dev` group in `[dependency-groups]` (PEP 735):

```toml pyproject.toml theme={null}
[dependency-groups]
dev = ["pytest >=8.1.1,<9"]
```

### The dev Group

The `dev` group is special:

* Has dedicated flags: `--dev`, `--only-dev`, `--no-dev`
* Synced by default with `uv sync` and `uv run`

## Dependency Groups

Organize development dependencies into multiple groups:

```bash theme={null}
uv add --group lint ruff
uv add --group test pytest
uv add --group docs mkdocs
```

Resulting configuration:

```toml pyproject.toml theme={null}
[dependency-groups]
dev = ["pytest"]
lint = ["ruff"]
test = ["pytest", "coverage"]
docs = ["mkdocs", "mkdocs-material"]
```

### Using Groups

```bash theme={null}
# Install all groups
uv sync --all-groups

# Install specific groups
uv sync --group lint --group test

# Install only one group
uv sync --only-group docs

# Exclude specific groups
uv sync --no-group lint
```

<Info>
  The `--dev`, `--only-dev`, and `--no-dev` flags are equivalent to `--group dev`, `--only-group dev`, and `--no-group dev`.
</Info>

### Nesting Groups

Groups can include other groups:

```toml pyproject.toml theme={null}
[dependency-groups]
dev = [
  {include-group = "lint"},
  {include-group = "test"}
]
lint = ["ruff"]
test = ["pytest"]
```

### Default Groups

Configure which groups are installed by default:

```toml pyproject.toml theme={null}
[tool.uv]
default-groups = ["dev", "lint"]

# Or enable all groups
default-groups = "all"
```

Disable defaults during commands:

```bash theme={null}
uv sync --no-default-groups
uv sync --no-group lint
```

### Group requires-python

Groups can have different Python version requirements:

```toml pyproject.toml theme={null}
[project]
name = "example"
version = "0.0.0"
requires-python = ">=3.10"

[dependency-groups]
dev = ["pytest"]

[tool.uv.dependency-groups]
dev = {requires-python = ">=3.12"}
```

## Build Dependencies

Build dependencies are required to build the project, but not to run it.

### Defining Build Dependencies

```toml pyproject.toml theme={null}
[project]
name = "example"
version = "0.1.0"

[build-system]
requires = ["setuptools>=42"]
build-backend = "setuptools.build_meta"
```

### Build Dependencies with Sources

By default, `tool.uv.sources` applies to build dependencies:

```toml pyproject.toml theme={null}
[build-system]
requires = ["setuptools>=42"]
build-backend = "setuptools.build_meta"

[tool.uv.sources]
setuptools = { path = "./packages/setuptools" }
```

<Tip>
  When publishing, run `uv build --no-sources` to verify the package builds without custom sources.
</Tip>

## Editable Dependencies

Editable installations link source directories directly into the virtual environment.

### How Editable Works

<Steps>
  <Step title="Regular Installation">
    Builds wheel, copies files to venv
  </Step>

  <Step title="Editable Installation">
    Adds `.pth` file linking to source directory
  </Step>

  <Step title="Result">
    Source changes immediately reflected without reinstall
  </Step>
</Steps>

### Limitations

* Build backend must support editable installs
* Native modules aren't recompiled before import
* Some packaging features may not work

### Using Editable Dependencies

uv uses editable installation for workspace packages by default.

For path dependencies:

```bash theme={null}
uv add --editable ./path/foo
```

Opt-out for workspace members:

```bash theme={null}
uv add --no-editable ./path/foo
```

## Virtual Dependencies

Virtual dependencies don't install the package itself, only its dependencies.

### When to Use

Useful for:

* Dependency-only projects without installable code
* Aggregating multiple packages' dependencies
* Build-only dependency sets

### Marking Dependencies as Virtual

```toml pyproject.toml theme={null}
[project]
dependencies = ["bar"]

[tool.uv.sources]
bar = { path = "../projects/bar", package = false }
```

With `package = false`, only `bar`'s dependencies are installed, not `bar` itself.

## Related Documentation

<CardGroup cols={2}>
  <Card title="Projects" icon="folder" href="/concepts/projects">
    Learn about project structure and pyproject.toml
  </Card>

  <Card title="Workspaces" icon="folder-tree" href="/concepts/workspaces">
    Manage dependencies across multiple related packages
  </Card>

  <Card title="Python Versions" icon="python" href="/concepts/python-versions">
    Understand how Python versions affect dependency resolution
  </Card>

  <Card title="Cache" icon="database" href="/concepts/cache">
    Learn how uv caches dependencies
  </Card>
</CardGroup>
