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

# Projects

> Learn how uv manages Python projects with pyproject.toml, lockfiles, and virtual environments

Projects help manage Python code spanning multiple files. Working on projects is a core part of the uv experience.

<Info>
  Looking for an introduction to creating a project with uv? See the [projects guide](/guides/projects) first.
</Info>

## Project Structure

A uv project requires a `pyproject.toml` file that defines project metadata and dependencies.

### Minimal Project Definition

A minimal project definition includes a name and version:

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

### Complete Project Structure

A typical uv project includes:

* **pyproject.toml** - Project metadata, dependencies, and configuration
* **uv.lock** - Universal lockfile with exact package versions
* **.venv/** - Virtual environment (auto-managed by uv)
* **src/** or flat structure - Python source code

## The pyproject.toml File

Python project metadata is defined in a `pyproject.toml` file following the [PEP 621](https://packaging.python.org/en/latest/specifications/pyproject-toml/) standard. uv uses this file to identify the project root directory.

### Project Metadata

Additional project metadata includes:

```toml pyproject.toml theme={null}
[project]
name = "albatross"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
  "tqdm >=4.66.2,<5",
  "torch ==2.2.2",
  "transformers[torch] >=4.39.3,<5",
]
```

<Card title="Key Metadata Fields" icon="list">
  * **name** - Package name
  * **version** - Package version
  * **requires-python** - Python version requirement
  * **dependencies** - Runtime dependencies
  * **optional-dependencies** - Optional feature dependencies (extras)
</Card>

### Python Version Requirement

The `requires-python` field determines:

* Python syntax allowed in the project
* Compatible dependency versions (must support the same Python range)

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

## The Project Environment

When working on a project, uv automatically creates and manages a virtual environment.

### Default Environment Location

By default, uv creates a persistent environment in a `.venv` directory next to `pyproject.toml`. The `.venv` directory:

* Makes it easy for editors to find (for code completions and type hints)
* Is automatically excluded from git (via internal `.gitignore`)
* Should not be included in version control

### Running Commands

To run a command in the project environment:

```bash theme={null}
uv run python script.py
```

Alternatively, activate the environment manually:

```bash theme={null}
source .venv/bin/activate  # Unix
.venv\Scripts\activate     # Windows
```

<Warning>
  Do not modify the project environment manually with `uv pip install`. Use `uv add` for project dependencies or `uv run --with` for one-off requirements.
</Warning>

### Auto-Sync Behavior

When `uv run` is invoked:

1. Creates the project environment if it doesn't exist
2. Ensures the environment is up-to-date with lockfile
3. Runs the requested command

To disable auto-sync:

```bash theme={null}
uv run --no-sync <command>
```

### Custom Environment Path

The `UV_PROJECT_ENVIRONMENT` environment variable configures the virtual environment path:

```bash theme={null}
# Relative to workspace root
export UV_PROJECT_ENVIRONMENT=.venv

# Absolute path
export UV_PROJECT_ENVIRONMENT=/path/to/env
```

<Warning>
  If using an absolute path across multiple projects, the environment will be overwritten by each project. Only recommended for single projects in CI or Docker.
</Warning>

## The Lockfile

uv creates a `uv.lock` file next to `pyproject.toml` that captures exact package versions.

### Universal Lockfile

`uv.lock` is a **universal** or **cross-platform** lockfile that includes packages for all possible Python markers:

* Operating systems (Linux, macOS, Windows)
* Architectures (x86\_64, aarch64)
* Python versions (3.9, 3.10, 3.11, etc.)

### Lockfile vs pyproject.toml

<CardGroup cols={2}>
  <Card title="pyproject.toml" icon="file-code">
    * Broad requirements
    * Version constraints
    * Manually edited
  </Card>

  <Card title="uv.lock" icon="lock">
    * Exact versions
    * Resolved dependencies
    * Auto-managed by uv
  </Card>
</CardGroup>

### Version Control

The lockfile should be checked into version control because it:

* Ensures consistent package versions across developers
* Guarantees reproducible installations
* Locks exact versions for production deployments

### Auto-Update Behavior

The lockfile is automatically created and updated during:

* `uv sync` - Sync environment with lockfile
* `uv run` - Run command in project environment
* `uv lock` - Explicitly update lockfile

<Info>
  `uv.lock` is human-readable TOML but should not be edited manually. It uses a uv-specific format not compatible with other tools.
</Info>

## Virtual Environments

Virtual environments isolate project dependencies from the system Python.

### Creating Environments

The project environment is automatically created when needed:

```bash theme={null}
# Auto-creates .venv if needed
uv run python script.py

# Explicitly create/sync environment
uv sync
```

To manually create a virtual environment:

```bash theme={null}
uv venv
```

### Editable Installation

By default, when the environment is synced, uv installs the project as an **editable** package:

* Source code changes are immediately reflected
* No need to re-sync after editing files
* Uses `.pth` file to link source directory

To opt-out of editable installation:

```bash theme={null}
uv sync --no-editable
```

<Note>
  If the project doesn't define a build system in `[build-system]`, it won't be installed as a package.
</Note>

### Managed vs Unmanaged Projects

By default, uv manages the project environment automatically. To disable this:

```toml pyproject.toml theme={null}
[tool.uv]
managed = false
```

With `managed = false`, uv will not automatically lock or sync the project.

## Build Systems

A build system determines how the project should be packaged and installed.

### When to Use Build Systems

You probably need a build system if you want to:

* Add command-line interfaces
* Distribute the project to others
* Use a `src/` and `test/` layout
* Write a library

You probably don't need a build system if you're:

* Writing simple scripts
* Building a basic application
* Using a flat layout

### Defining a Build System

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

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
```

### Build Backend Options

Common build backends include:

* **hatchling** - Modern, fast build backend
* **setuptools** - Traditional, widely-used
* **flit** - Lightweight for simple packages
* **pdm-backend** - PDM's build backend

Create a packaged project with a specific backend:

```bash theme={null}
uv init --build-backend hatchling

# Or use default backend
uv init --package
```

### Package Setting Override

Override the automatic build system detection:

```toml pyproject.toml theme={null}
[tool.uv]
# Force building even without build-system
package = true

# Or prevent building despite build-system
package = false
```

## Entry Points

Entry points allow installed packages to advertise interfaces.

### Command-Line Interfaces

Define CLI commands in `[project.scripts]`:

```toml pyproject.toml theme={null}
[project.scripts]
hello = "example:main"
process = "example.cli:process_data"
```

Run commands with:

```bash theme={null}
uv run hello
uv run process --input data.csv
```

### GUI Scripts

Define GUI applications in `[project.gui-scripts]`:

```toml pyproject.toml theme={null}
[project.gui-scripts]
app = "example:launch_gui"
```

<Note>
  GUI scripts differ from CLI scripts only on Windows, where they're wrapped by a GUI executable to run without a console.
</Note>

### Plugin Entry Points

Register plugins for discovery:

```toml pyproject.toml theme={null}
[project.entry-points.'myapp.plugins']
foo = "example_plugin_foo"
bar = "example_plugin_bar"
```

Load plugins in your application:

```python theme={null}
from importlib.metadata import entry_points

for plugin in entry_points(group='myapp.plugins'):
    plugin.load()
```

## Related Documentation

<CardGroup cols={2}>
  <Card title="Managing Dependencies" icon="box" href="/concepts/dependencies">
    Learn how to add, remove, and manage project dependencies
  </Card>

  <Card title="Python Versions" icon="python" href="/concepts/python-versions">
    Understand Python version management and installation
  </Card>

  <Card title="Workspaces" icon="folder-tree" href="/concepts/workspaces">
    Work with multiple related projects in a single repository
  </Card>

  <Card title="Caching" icon="database" href="/concepts/cache">
    Learn about uv's caching mechanisms for faster installs
  </Card>
</CardGroup>
