🔎

uv の細かい使い方 (pip互換, sync と run, --group など)

に公開

はじめに

こちらの記事の続きです->uv 実際に使ってみる (インストール手順・コマンド・実行例)
uv の基本的な使い方やコマンド実行例などを、上記の前記事で紹介しています。

本記事は、前記事では紹介するには少し細かいと思った内容を紹介しています。
uv の基本的な使い方からは少し外れていますが、知っていれば役立つ内容かと思います。

よろしければ、前記事の方にも目を通していただければと思います。

記事内容について

今回は以下のトピックをまとめています。

基本的には、公式ドキュメントを調べたり実際にコマンドを実行したりなどして、
得られた知見を紹介させていただきます。

  • pip, requirements.txt との互換
  • uv sync と pyproject.toml と uv.lock の関係
  • 依存関係のグループ化 (dev と group)
  • キャッシュ

動作環境

前記事と同様です。

項目 詳細
ホストOS Windows 11 Pro
WSL2 ゲストOS Ubuntu 24.04.1 LTS
Docker ゲストOS Ubuntu 24.04.1 LTS
uv バージョン 0.9.14

pip, requirements.txt との互換

uv には pip 互換のインターフェースが用意されています。
公式ドキュメント

しかし、公式としては uv の標準インターフェースと、この pip 互換のインターフェースを併用することは非推奨とされています。

uv と pip 互換インターフェースの併用について

非推奨の理由はいくつかあるみたいですが、大きいのは pip 互換のインターフェースを使って変化したパッケージ等の依存関係は、uv の標準インターフェースの管理下から外れることでしょう。
具体例としては、pip 互換のインターフェースである uv pip install でインストールしたパッケージは、pyproject.toml や uv.lock には記載されず、依存関係として管理されません。

# pip インターフェースで numpy インストール
$ uv pip install numpy
Resolved 1 package in 105ms
Prepared 1 package in 274ms
Installed 1 package in 59ms
 + numpy==2.4.0

# 仮想環境内で numpy が使える
$ uv run python
Python 3.14.2 (main, Dec  9 2025, 19:03:28) [Clang 21.1.4 ] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy

# uv 標準インターフェースからは numpy は見えない
$ uv tree
Resolved 1 package in 0.48ms
tips-project v0.1.0

# 一度仮想環境を削除
$ rm -r .venv/

# numpy は uv の依存関係になかったため、再生成した仮想環境内に存在しない
$ uv run python 
Using CPython 3.14.2
Creating virtual environment at: .venv
Python 3.14.2 (main, Dec  9 2025, 19:03:28) [Clang 21.1.4 ] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    import numpy
ModuleNotFoundError: No module named 'numpy'

このように、 仮想環境と pyproject.toml や uv.lock の実体がズレる可能性があるため、
両者の併用は避けた方がよいです。

pip 互換のインターフェース (コマンド)

いくつか、pip 互換のインターフェースを紹介していきます。

公式ドキュメントにも記載があります。

パッケージインストール/アンインストール uv pip install, uv pip uninstall

uv pip install [package name] でパッケージをインストールできます。

$ uv pip install numpy
Resolved 1 package in 2ms
Installed 1 package in 54ms
 + numpy==2.4.0

パッケージのアンインストールは uv pip uninstall [package name] です。

$ uv pip uninstall numpy
Uninstalled 1 package in 18ms
 - numpy==2.4.0

パッケージ一覧 uv pip list, uv pip tree uv pip freeze

pip互換インターフェースでインストールしたパッケージの一覧は、
uv pip list, uv pip tree, uv pip freeze 等で確認できます。

先述の通り pip 互換のインターフェースは uv による依存関係管理に影響しないので、以下のように、uv tree の結果と異なる場合があります。

$ uv pip list
Package         Version
--------------- -----------
numpy           2.4.0
pandas          2.3.3
python-dateutil 2.9.0.post0
pytz            2025.2
six             1.17.0
tzdata          2025.3

$ uv pip tree
pandas v2.3.3
├── numpy v2.4.0
├── python-dateutil v2.9.0.post0
│   └── six v1.17.0
├── pytz v2025.2
└── tzdata v2025.3

$ uv pip freeze
numpy==2.4.0
pandas==2.3.3
python-dateutil==2.9.0.post0
pytz==2025.2
six==1.17.0
tzdata==2025.3

# uv tree の結果と必ずしも一致しない
$ uv tree 
Resolved 1 package in 1ms
tips-project v0.1.0

requirements.txt からのインストール uv pip install -r

uv pip install -r requirements.txt で、同じように requirements.txt を使ってパッケージをインストールできます。

$ cat requirements.txt 
numpy
pandas

$ uv pip install -r requirements.txt 
Resolved 6 packages in 137ms
Prepared 6 packages in 448ms
Installed 6 packages in 80ms
 + numpy==2.4.0
 + pandas==2.3.3
 + python-dateutil==2.9.0.post0
 + pytz==2025.2
 + six==1.17.0
 + tzdata==2025.3

$ uv pip list
Package         Version
--------------- -----------
numpy           2.4.0
pandas          2.3.3
python-dateutil 2.9.0.post0
pytz            2025.2
six             1.17.0
tzdata          2025.3

現在のインストールパッケージを requirements.txt を出力したい場合は、
uv pip freeze > requirements.txt とします。

$ uv pip tree
pandas v2.3.3
├── numpy v2.4.0
├── python-dateutil v2.9.0.post0
│   └── six v1.17.0
├── pytz v2025.2
└── tzdata v2025.3
$ uv pip freeze > requirements.txt

$ cat requirements.txt 
numpy==2.4.0
pandas==2.3.3
python-dateutil==2.9.0.post0
pytz==2025.2
six==1.17.0
tzdata==2025.3

パッケージの詳細表示 uv pip show [package name]

uv pip show で、インストールしたパッケージの詳細を表示できます。

$ uv pip show numpy
Name: numpy
Version: 2.4.0
Location: /home/ubuntu/ws/tips-project/.venv/lib/python3.14/site-packages
Requires:
Required-by:

uv 標準インターフェースで requirements.txt のインポート/エクスポート

uv 標準インターフェースを使って、requirements.txt からパッケージをインストールしたり、逆に uv が管理するパッケージ依存関係をファイル出力することができます。

例えばまず、requirements.txt へのエクスポートは uv export -o requirements.txt --no-hashes コマンドで実施できます。
公式ドキュメントはこちら
他の形式のファイルへの出力についても上記で確認できます。
オプションなどはこちらから確認

$ uv export -o requirements.txt --no-hashes
Resolved 7 packages in 0.52ms
# This file was autogenerated by uv via the following command:
#    uv export -o requirements.txt --no-hashes
numpy==2.3.5
    # via pandas
pandas==2.3.3
    # via test-project
python-dateutil==2.9.0.post0
    # via pandas
pytz==2025.2
    # via pandas
six==1.17.0
    # via python-dateutil
tzdata==2025.2
    # via pandas

$ cat requirements.txt 
# This file was autogenerated by uv via the following command:
#    uv export -o requirements.txt --no-hashes
numpy==2.3.5
    # via pandas
pandas==2.3.3
    # via test-project
python-dateutil==2.9.0.post0
    # via pandas
pytz==2025.2
    # via pandas
six==1.17.0
    # via python-dateutil
tzdata==2025.2
    # via pandas

requirements.txt からのインストール (インポート) は、uv add -r requirements.txt で実施できます。
この方法でインストールした場合は、uv pip install -r requirements.txt の場合と違い、uv による依存関係の管理下となります。

$ uv add -r requirements.txt 
Resolved 7 packages in 78ms
Prepared 2 packages in 314ms
Installed 6 packages in 70ms
 + numpy==2.3.5
 + pandas==2.3.3
 + python-dateutil==2.9.0.post0
 + pytz==2025.2
 + six==1.17.0
 + tzdata==2025.2

$ uv tree
Resolved 7 packages in 0.48ms
tips-project v0.1.0
├── numpy v2.3.5
├── pandas v2.3.3
│   ├── numpy v2.3.5
│   ├── python-dateutil v2.9.0.post0
│   │   └── six v1.17.0
│   ├── pytz v2025.2
│   └── tzdata v2025.2
├── python-dateutil v2.9.0.post0 (*)
├── pytz v2025.2
├── six v1.17.0
└── tzdata v2025.2
(*) Package tree already displayed

uv sync と pyproject.toml と uv.lock の関係

前記事 で、uv sync について少し話題に出しました。こちらは明示的に仮想環境と uv.lock を更新するコマンドです。
また uv run コマンドを実行した場合も、自動で仮想環境 と uv.lock が更新されるという話もしました。

ここでは、uv run を実行した場合と uv sync を実行した場合の違い、さらにこれらのコマンドと、pyproject.toml, uv.lock のファイルの関係について見ていきます。

uv sync について

uv sync は、pyproject.toml の内容をもとに仮想環境と uv.lock ファイルを更新するコマンドです。

pyproject.toml 内では、そのプロジェクトにおけるパッケージの依存関係を定義できます。

pyproject.toml
[project]
name = "tips-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.14"
dependencies = [
    "matplotlib>=3.10.8",
    "pandas>=2.3.3",
]

[dependency-groups]
dev = [
    "ruff>=0.14.11",
]

pyproject.toml 内の依存関係の定義は、uv add でパッケージをインストールしたときなどに自動で更新されます。
また、記法を間違えなければ手動で書き換えてもokです。公式ドキュメントはこちら

uv sync コマンドを実行すると、pyproject.toml で定義した依存関係の通りに、仮想環境にパッケージをインストール (同期) します。
そして uv.lock には、その依存関係に加えインストールしたパッケージのバージョンの情報も書き出します。

uv.lock の情報だけを使って、仮想環境を更新することもできます。それが、--frozen オプションです。
uv sync --frozen とすると、pyproject.toml の内容ではなく、uv.lock の情報に従い指定バージョンのパッケージを仮想環境にインストールします。

uv sync, uv sync --frozen の実行例

以下のように、pyproject.toml には numpy だけ、uv.lock には numpy と ruff が定義してある状態で、--frozen オプション有無のそれぞれの挙動を見てみます。

pyproject.toml
[project]
name = "tips-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.14"
dependencies = [
    "numpy>=2.3.3",
]
# pyproject.toml は numpy のみ
uv.lock

...

[[package]]
name = "tips-project"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
    { name = "numpy" },
    { name = "ruff" },
]

[package.metadata]
requires-dist = [
    { name = "numpy", specifier = ">=2.3.3" },
    { name = "ruff", specifier = ">=0.14.11" },
]
# uv.lock は numpy と ruff がある

uv sync (オプションなし) を実行すると、以下のように uv.lock と仮想環境が pyproject.toml の定義に合わせるように更新されます

# 一回仮想環境削除
$ rm -r .venv/

$ uv sync
Using CPython 3.14.2
Creating virtual environment at: .venv
Resolved 2 packages in 48ms
Installed 1 package in 280ms
 + numpy==2.4.0
 
$ ls .venv/lib/python3.14/site-packages/
_virtualenv.pth  _virtualenv.py  numpy  numpy-2.4.0.dist-info  numpy.libs
# 仮想環境は numpy のみ

$ cat uv.lock 

...

[[package]]
name = "tips-project"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
    { name = "numpy" },
]

[package.metadata]
requires-dist = [{ name = "numpy", specifier = ">=2.3.3" }]
# uv.lock は numpy のみ (更新された)

uv sync --frozen 実行すると、以下のようにその時点の uv.lock の定義に合わせて仮想環境が更新されます。uv.lock は更新されず、pyproject.toml の内容は影響しません。

# 一回仮想環境削除
$ rm -r .venv/

$ uv sync --frozen
Using CPython 3.14.2
Creating virtual environment at: .venv
Installed 2 packages in 73ms
 + numpy==2.4.0
 + ruff==0.14.11

$ ls .venv/lib/python3.14/site-packages/
_virtualenv.pth  _virtualenv.py  numpy  numpy-2.4.0.dist-info  numpy.libs  ruff  ruff-0.14.11.dist-info
# 仮想環境には numpy と ruff があり、uv.lock の内容と一致

$ cat uv.lock

...

[[package]]
name = "tips-project"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
    { name = "numpy" },
    { name = "ruff" },
]

[package.metadata]
requires-dist = [
    { name = "numpy", specifier = ">=2.3.3" },
    { name = "ruff", specifier = ">=0.14.11" },
]
# uv.lock は numpy と ruff がありそのまま (更新されていない)

uv run との違い

uv run も実行時に、pyproject.toml の内容をもとに仮想環境と uv.lock ファイルを更新します。
しかしその挙動は、uv sync と若干異なる部分があります。

例として、requests のみをインストールした状態から pyproject.toml の中身を書き換え、requests を削除し numpy を追加します。
以下のように、pyproject.toml には numpy のみがありますが、仮想環境には requests とその依存パッケージのみがある状態です。

$ uv add requests
Resolved 6 packages in 103ms
Prepared 5 packages in 77ms
Installed 5 packages in 8ms
 + certifi==2025.11.12
 + charset-normalizer==3.4.4
 + idna==3.11
 + requests==2.32.5
 + urllib3==2.6.2

$ ls .venv/lib/python3.14/site-packages/
__pycache__      _virtualenv.py  certifi-2025.11.12.dist-info  charset_normalizer-3.4.4.dist-info  idna-3.11.dist-info  requests-2.32.5.dist-info  urllib3-2.6.2.dist-info
_virtualenv.pth  certifi         charset_normalizer            idna                                requests             urllib3

$ cat pyproject.toml 
[project]
name = "tips-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.14"
dependencies = [
    "numpy",
]

この状態で、uv run python を実行すると、

$ uv run python
Python 3.14.2 (main, Dec  9 2025, 19:03:28) [Clang 21.1.4 ] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>>

$ cat uv.lock        
(略)
[[package]]
name = "tips-project"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
    { name = "numpy" },
]
(略)
...

$ ls .venv/lib/python3.14/site-packages/
__pycache__      _virtualenv.py  certifi-2025.11.12.dist-info  charset_normalizer-3.4.4.dist-info  idna-3.11.dist-info  numpy-2.4.0.dist-info  requests                   urllib3
_virtualenv.pth  certifi         charset_normalizer            idna                                numpy                numpy.libs             requests-2.32.5.dist-info  urllib3-2.6.2.dist-info

上記のように、uv.lock からは requests が削除され numpy のみの状態になっていますが、仮想環境には requests が残っています。 仮想環境からの余分パッケージの削除はしないようです。

このように、uv run 時にも仮想環境と uv.lock ファイルを更新するといっても、こちらは実行優先の考え方であり、pyproject.toml の内容に同期することとは少し違う挙動であることに注意が必要です。。

比較用に uv sync を実行してみると、仮想環境から requests が削除されました。

$ uv sync
Resolved 2 packages in 0.56ms
Uninstalled 5 packages in 4ms
 - certifi==2025.11.12
 - charset-normalizer==3.4.4
 - idna==3.11
 - requests==2.32.5
 - urllib3==2.6.2
$ ls .venv/lib/python3.14/site-packages/
__pycache__  _virtualenv.pth  _virtualenv.py  numpy  numpy-2.4.0.dist-info  numpy.libs

依存関係のグループ化 (dev と group)

他のパッケージ管理ツールと同様に、uv でも依存関係のグループ化が可能です。
用途ごとに別々の依存関係を定義し、それをグループとして扱い切り替えることで、多岐にわたる用途でも簡易に依存関係の管理ができます。

グループには任意の名前をつけることができます。
また、dev は開発用依存関係を定義する際に使用しますが、uv においては dev はグループのうち特別な扱い方をされるものです。

pyproject.toml の中身をみると、以下のように、別々の依存関係として管理されています。

pyproject.toml
[project]
name = "tips-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.14"
dependencies = [
    "numpy>=2.4.0",
]

[dependency-groups]
dev = [
    "ruff>=0.14.10",
]
web = [
    "requests>=2.32.5",
]

dev グループの利用

インストールとアンインストール

dev グループにパッケージをインストールする際は、uv add --dev [package_name] とします。

$ uv add --dev pandas
Resolved 7 packages in 94ms
Installed 5 packages in 162ms
 + pandas==2.3.3
 + python-dateutil==2.9.0.post0
 + pytz==2025.2
 + six==1.17.0
 + tzdata==2025.3

$ cat pyproject.toml 
[project]
name = "tips-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.14"
dependencies = [
    "numpy>=2.4.0",
]

[dependency-groups]
dev = [
    "pandas>=2.3.3",
]

アンインストールの場合は、uv remove --dev [package_name] とします。

仮想環境の更新

続いて仮想環境を更新する場合ですが、こちらは少し注意が必要です。
uv sync や uv run コマンド実行時、オプションを付けないデフォルトではベースの依存関係に加えて dev の依存関係も含めて仮想環境を更新します。
--no-dev オプションを付与した場合に、dev を除外して更新します。

$ cat pyproject.toml 
[project]
name = "tips-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.14"
dependencies = [
    "numpy>=2.4.0",
]

[dependency-groups]
dev = [
    "ruff>=0.14.10",
]

$ uv sync
Resolved 3 packages in 0.52ms
Audited 2 packages in 0.03ms

$ ls .venv/lib/python3.14/site-packages/
_virtualenv.pth  _virtualenv.py  numpy  numpy-2.4.0.dist-info  numpy.libs  ruff  ruff-0.14.10.dist-info

$ uv sync --no-dev
Resolved 3 packages in 0.52ms
Uninstalled 1 package in 2ms
 - ruff==0.14.10

$ ls .venv/lib/python3.14/site-packages/
_virtualenv.pth  _virtualenv.py  numpy  numpy-2.4.0.dist-info  numpy.libs

--frozen と --no-dev オプションは併用できます。
この場合は、uv.lock の記載のうち dev グループの依存関係を除外して仮想環境を更新します。

任意グループの利用 (--group)

ユーザが任意のグループを指定し、そのグループの依存関係を定義できます。
基本、各コマンドのオプションに --group [group_name] をつけることでグループの依存関係を操作できます。

インストールとアンインストール

uv add --group [group_name] [package_name] で、指定のグループにパッケージを追加できます。
このとき、グループを事前に作成するような準備は不要です。グループの定義と同時にパッケージが追加されます。

$ uv add --group mygroup requests
Using CPython 3.14.2
Creating virtual environment at: .venv
Resolved 7 packages in 0.40ms
Installed 6 packages in 61ms
 + certifi==2025.11.12
 + charset-normalizer==3.4.4
 + idna==3.11
 + numpy==2.4.0
 + requests==2.32.5
 + urllib3==2.6.2

$ cat pyproject.toml 
[project]
name = "tips-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.14"
dependencies = [
    "numpy>=2.4.0",
]

[dependency-groups]
mygroup = [
    "requests>=2.32.5",
]

アンインストールは、uv remove --group [group_name] [package_name] です。

仮想環境の更新

uv sync --group [group_name] または uv run --group [group_name] で、ベースの依存関係に加えて、グループの依存関係を追加して仮想環境を更新します。
こちらは dev の場合と逆に、オプションを付けないデフォルトではグループの依存関係は参照されません。

$ cat pyproject.toml 
[project]
name = "tips-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.14"
dependencies = [
    "numpy>=2.4.0",
]

[dependency-groups]
dev = []
mygroup = [
    "requests>=2.32.5",
]

$ uv sync
Using CPython 3.14.2
Creating virtual environment at: .venv
Resolved 7 packages in 0.51ms
Installed 1 package in 54ms
 + numpy==2.4.0
 
$ ls .venv/lib/python3.14/site-packages/
_virtualenv.pth  _virtualenv.py  numpy  numpy-2.4.0.dist-info  numpy.libs

$ uv sync --group mygroup   
Resolved 7 packages in 0.58ms
Installed 5 packages in 4ms
 + certifi==2025.11.12
 + charset-normalizer==3.4.4
 + idna==3.11
 + requests==2.32.5
 + urllib3==2.6.2

$ ls .venv/lib/python3.14/site-packages/
_virtualenv.pth  certifi                       charset_normalizer                  idna                 numpy                  numpy.libs  requests-2.32.5.dist-info  urllib3-2.6.2.dist-info
_virtualenv.py   certifi-2025.11.12.dist-info  charset_normalizer-3.4.4.dist-info  idna-3.11.dist-info  numpy-2.4.0.dist-info  requests    urllib3

uv sync や uv run において、複数グループを指定することもできます。その場合は、指定したグループの依存をまとめて参照し更新できます。
$ uv sync --group mygroup --group testgroup

また、--no-dev オプションとの併用が可能です。同時指定した場合は、ベースの依存関係と指定したグループの依存関係のみ考慮し仮想環境を更新します。
$ uv sync --no-dev --group testgroup

まとめ

仮想環境の更新周りはややこしかったので、以下にまとめました。
各コマンドで仮想環境を更新する際、各列のグループの依存関係が考慮されるかどうかの表です。
※base はベースの依存関係です。(uv add オプションなしで追加されるデフォルトの依存関係)

コマンド base dev group (mygroup)
uv sync ✅(考慮される) ✅ ❌(考慮されない)
uv sync --no-dev ✅ ❌ ❌
uv sync --group mygroup ✅ ✅ ✅
uv sync --no-dev --group mygroup ✅ ❌ ✅

uv run の場合も上記と同様ですが、uv sync と違い余分パッケージの削除は行われないことに注意してください。

キャッシュ

uv のキャッシュについての公式ドキュメントはこちら

uv はキャッシュを利用して再ダウンロードを回避し、処理速度の向上を実現しています。

キャッシュが保存されているディレクトリパスは、 uv cache dir コマンドで確認できます。
キャッシュデータを削除する場合は、 uv cache clean コマンドを実行します。特定パッケージのキャッシュを削除する場合は、uv cache clean [package] です。

キャッシュ関係で問題が出た場合には、上記でキャッシュを削除したり、
コマンドに --refresh --reinstall のオプションを付けるなど公式で言及されています。
--refresh は現依存関係のキャッシュ検証(更新処理)、
--reinstall はキャッシュ削除後に実行することで、プロジェクトとキャッシュにパッケージの再インストールを行います。

キャッシュ復旧については、以下により詳しい解説記事がありました。

Discussion