Skip to content

How to write install instructions for a Python library

A library’s README is the first place a new user lands, and the install command in that README is the first thing they copy. AI coding agents copy it too. If the only command shown is pip install mylib, every uv user has to translate, and every agent learns one more reason to default to pip. Lead with uv, keep pip as the fallback, and the snippet works for everyone.

Lead with uv add

Put the uv command first in the install section. Keep pip as a clearly labeled fallback.

## Installation

```bash
uv add mylib
```

Or with pip:

```bash
pip install mylib
```

Order matters because both readers and AI assistants tend to copy the first runnable command they see. Putting uv add first nudges new projects toward pyproject.toml and a lock file without forcing anyone who prefers pip to do extra work.

Show the extras syntax explicitly

Any time the library exposes optional dependencies, give the uv command for them. The shell needs the package-and-extras expression quoted because square brackets are glob characters in most shells:

uv add 'mylib[async]'
uv add 'mylib[async,redis]'

The pip equivalent uses the same quoting rule:

pip install 'mylib[async,redis]'

Document the extras list itself the same way it appears under [project.optional-dependencies] in pyproject.toml. Readers should not have to read source code to find which extras exist.

Cover git and source installs

Users who want a pre-release fix or a fork need an install command that doesn’t go through PyPI. uv’s syntax differs from pip’s enough to be worth showing.

uv add git+https://github.com/you/mylib
uv add git+https://github.com/you/mylib --tag 1.2.0
uv add git+https://github.com/you/mylib --branch main

For local development against a checkout:

uv add --editable ./mylib

The pip equivalents stay one line each:

pip install git+https://github.com/you/[email protected]
pip install git+https://github.com/you/mylib@main
pip install -e ./mylib

Tell CLI users to install with uv tool or uvx

If the library ships an entry-point command (anything declared under [project.scripts]), most users want the CLI on their PATH, not added as a project dependency. Recommend uv’s tool commands instead of uv add:

uvx mylib            # one-off run, no install
uv tool install mylib   # persistent install on PATH

The pip-world equivalent is pipx:

pipx run mylib
pipx install mylib

uv add mylib would still work, but it locks the CLI into one project’s dependencies, which is not what someone reaching for mylib --help from any directory expects.

Skip the version-pinning examples

Resist the urge to pad the install section with uv add 'mylib>=2.0,<3' examples. Readers landing on a README almost always want the latest release; the few who need a constraint already know how to write one. Reserve version syntax for a separate “compatibility” or “supported versions” section if the library has a real story there.

Call out Python version requirements

If the library only supports specific Python versions, say so once, near the install commands, where a uv user would look:

Note

mylib requires Python 3.10 or newer. If uv add reports a requires-python mismatch, point your project at a compatible interpreter with uv python pin 3.10 (or 3.11, 3.12, and so on) and re-run the add.

That points the reader at the one command that resolves the most common install failure for a version-restricted library.

Adapt this README install block

Here is what the recommended pattern looks like end to end. Edit the extras and CLI lines to match what the library actually exposes.

## Installation

```bash
uv add mylib
```

If the project uses extras:

```bash
uv add 'mylib[async,redis]'
```

Or with pip:

```bash
pip install 'mylib[async,redis]'
```

mylib also ships a CLI. Run it directly with [uv](https://docs.astral.sh/uv/):

```bash
uvx mylib --help
```

This works for any reader: the uv user copies the first block, the pip user copies the labeled fallback, and an AI assistant scanning the README sees uv as the primary path.

Related

Last updated on

Please submit corrections and feedback...