A CLAUDE.md Template for Python Projects Using uv

A ready-to-copy CLAUDE.md template for Python projects managed with uv, covering dependency commands, lockfile rules, virtual environment setup, and tests.

Updated 4 min read

A CLAUDE.md file in your Python project tells Claude Code that your team uses uv rather than pip or Poetry, which commands to run when adding a dependency, and what to do with the lockfile. Without that guidance, an assistant will often fall back to pip install, which bypasses the lockfile, the virtual environment that uv manages, and the version pinning your project depends on.

Tools like fenbs are a useful place for the tooling decisions that apply across your team: which package manager was chosen and why, which Python version is required, which linter configuration was agreed on. Your CLAUDE.md then covers the commands and constraints for the project at hand. This page gives you a template to copy and adapt.

What belongs in a CLAUDE.md for a uv project

The most important things to document are the commands Claude Code will need to run and the rules around the lockfile. uv keeps its own lockfile format (uv.lock) that is separate from pip's requirements files. If you do not explain this, an assistant may generate a requirements.txt manually or run pip freeze, which produces a different result.

  • The Python version the project targets and how to confirm the right interpreter is in use.
  • Commands for syncing the environment, adding a package, running the project, and running tests.
  • The lockfile rule: always commit uv.lock; never edit it by hand.
  • Whether the project uses a pyproject.toml with optional dependency groups (dev, test, docs).
  • Any linting, formatting, or type-checking tools and the command for each.

The template

Copy this into a CLAUDE.md at your project root and fill in the bracketed sections. The uv documentation (opens in a new tab) covers the full command reference if you need to describe a workflow not shown here.

CLAUDE.md for a Python project using uv
# [Project name] — Python project (uv)

## Package manager
This project uses uv for dependency management. Do not use pip, pip-compile,
or Poetry commands. Do not generate a requirements.txt manually.

## Python version
Target: Python [3.11 / 3.12 / other]. uv selects the interpreter from the
.python-version file or pyproject.toml. Run `uv python list` to see available
interpreters and `uv python install 3.x` to add one.

## Common commands
```
# Install all dependencies (including dev group)
uv sync --all-extras

# Add a production dependency
uv add [package-name]

# Add a dev dependency
uv add --dev [package-name]

# Run the project
uv run python src/[module].py
# or if the project has a script entry point:
uv run [script-name]

# Run tests
uv run pytest

# Run linter and formatter
uv run ruff check .
uv run ruff format .

# Type checking
uv run mypy .
```

## Lockfile
uv.lock is committed to the repository. Never edit it by hand.
After adding or removing a dependency, run `uv sync` to update it,
then commit both pyproject.toml and uv.lock together.

## Dependency groups
- `[project]` — production dependencies
- `[dev]` or `[tool.uv.dev-dependencies]` — development tools (linters, test runner)
- [Add any other groups your project uses]

## Environment
uv creates and manages the virtual environment at .venv/ automatically.
Do not activate the venv manually; use `uv run` for all commands.
.venv/ is in .gitignore and must not be committed.

## Tests
Tests live in tests/. Run the full suite with `uv run pytest` before committing.
Test coverage is checked with `uv run pytest --cov`. Target coverage: [your threshold].

## What Claude Code must not do
- Run pip install or pip uninstall.
- Edit uv.lock by hand.
- Commit the .venv/ directory.

The lockfile rule matters most

The single most important instruction is to use uv add or uv remove rather than pip. When Claude Code adds a dependency correctly, uv updates both pyproject.toml and uv.lock atomically. If it uses pip instead, the lockfile drifts from the actual environment and the next developer to run uv sync may get a different set of packages.

Add a matching rule to never edit uv.lock by hand. The file is generated; manual edits will be overwritten and may introduce inconsistencies that are hard to diagnose. Claude Code will respect this rule if you state it clearly.

Virtual environment management

uv manages the virtual environment at .venv/ automatically when you run uv sync or uv run. You do not need to activate it with source .venv/bin/activate or the Windows equivalent. Telling Claude Code to use uv run for every command — running tests, the linter, the application — prevents it from trying to activate the environment manually and picking up the wrong Python interpreter.

Another common issue is Python version selection. uv can install and manage multiple Python interpreters, but if your CLAUDE.md does not specify which version the project requires, Claude Code may run commands against a different interpreter than expected. Add the target Python version and tell Claude Code how to verify it: "Run uv python list to confirm the correct version is available before running tests."

If your project uses dependency groups for optional extras — a test group, a docs group, a dev tools group — describe them briefly. The command uv sync --all-extras installs everything; uv sync --extra test installs only a subset. Tell Claude Code which groups are needed for the work it will do so it does not end up with a partial environment.

Tooling decisions for the whole team

The choice to use uv, ruff, mypy, or pytest usually comes from a team conversation rather than a solo decision. So does the Python version and the minimum test coverage threshold. Those agreements are worth recording somewhere more visible than a comment in pyproject.toml.

When a new team member joins or a new assistant session starts, the rationale behind "we use ruff instead of flake8" or "we require Python 3.12 minimum" is just as useful as the fact itself. Keeping those decisions in fenbs means they are readable alongside the current tasks and where the project stands.

How fenbs helps

Keep tooling decisions where every assistant can read them

Record your package manager choice, Python version floor, linter setup, and coverage target as Decisions and rules in fenbs. When a connected assistant starts a new session, it reads those rules before suggesting changes that would contradict a decision your team has already made.

Create a free account

Free for one person · No credit card · Works with Claude, ChatGPT, Cursor and more

How to do this with fenbs

  1. Create a free account. Start a project for your Python application and add the current development tasks.
  2. Record tooling decisions — uv as the package manager, ruff as the linter, the Python version floor — as Decisions and rules in fenbs.
  3. Connect Claude Code to fenbs from Integrations. Ask it to read the project context at the start of each session so it has the rules before making any changes.
  4. Copy the CLAUDE.md template above into your project root and fill in your specific Python version, commands, and test threshold.
  5. When a tooling decision changes — a new linter adopted, a Python version bumped — update the fenbs decision and the CLAUDE.md together so both records stay in sync.

If you work across multiple Python services that share the same tooling choices, see Claude Code with multiple projects and CLAUDE.md for how to place shared instructions at the workspace level so each service does not repeat them. For troubleshooting when uv commands are ignored, see CLAUDE.md not working.

Questions people ask.

What is uv and how is it different from pip?

uv is a fast Python package manager that handles dependency resolution, lockfile generation, and virtual environment creation in one tool. Unlike pip, it produces a lockfile that pins all transitive dependencies, making environments reproducible across machines.

Can Claude Code run uv commands directly?

Yes, if uv is installed and available in the shell Claude Code uses. The CLAUDE.md tells it which commands to prefer so it does not fall back to pip by default.

Should I commit uv.lock to version control?

Yes. Committing uv.lock ensures every developer and every CI run installs exactly the same versions. The uv documentation recommends committing the lockfile for applications. For libraries, you may choose not to commit it, but include that decision in your CLAUDE.md.

How do I add a package only needed during development?

Run "uv add --dev [package-name]". This adds the package to the dev dependency group in pyproject.toml and updates uv.lock. The CLAUDE.md should say which groups you use so Claude Code adds packages to the right one.

Can I use uv in a project that also has a requirements.txt?

You can import an existing requirements.txt with "uv add -r requirements.txt", but once you adopt uv you should let it manage dependencies going forward. Your CLAUDE.md should state clearly whether requirements.txt is still authoritative or whether pyproject.toml and uv.lock are the source of truth.

Start with one thing.

Free for one person · No credit card · Works with Claude, ChatGPT, Cursor and more

There is nothing to set up first. Write one line and you’ve started.