uv는 2026년 파이썬 패키징의 사실상 표준이 됐습니다. pip·virtualenv·pyenv·pipx·pip-tools가 나눠 맡던 일을 바이너리 하나가 처리하고, 설치 속도는 10~100배 빠릅니다. 3월에는 OpenAI가 Astral 인수를 발표하며 기업 백업까지 붙었습니다.
요약 (Quick Answer) — uv 2026
| 항목 | 내용 |
|---|---|
| 정체 | Rust로 만든 파이썬 패키지·프로젝트 관리자 (Astral 제작) |
| 대체 대상 | pip · virtualenv · pyenv · pipx · pip-tools · (부분적으로) Poetry |
| 속도 | pip 대비 10~100배, Poetry 대비 약 10배 |
| 락파일 | uv.lock (플랫폼 무관 단일 파일) |
| 최초 릴리스 | 2024년 2월 |
| 소유 | Astral → OpenAI Codex 팀 (2026.03 인수 발표, 규제 승인 대기) |
| 2026년 권장 | 신규 프로젝트는 uv, 라이브러리 배포는 Poetry도 여전히 유효 |
5초 결론
- 새 프로젝트를 판다 →
uv init하고 시작하세요. - pip 프로젝트가 있다 →
uv pip install로 명령만 바꿔도 즉시 빨라집니다. - Poetry 프로젝트가 있다 → 급하지 않습니다. 잘 돌아가면 두세요.
- CI가 느리다 → 여기가 가장 확실한 이득 구간입니다.
검증 환경: macOS Sequoia 15.x / Apple Silicon M2 Pro / uv 0.11.x / Python 3.12
마지막 업데이트: 2026-07-27

uv란 무엇인가
uv는 Astral이 Rust로 만든 파이썬 패키지·프로젝트 관리자입니다. 2024년 2월에 처음 나왔습니다.
한 문장으로 줄이면 이렇습니다. 지금까지 대여섯 개 도구가 나눠 맡던 일을 바이너리 하나가 처리합니다.
무엇을 대체하나
| 하던 일 | 기존 도구 | uv 명령 |
|---|---|---|
| 패키지 설치 | pip | uv pip install / uv add |
| 의존성 고정 | pip-tools | uv lock (uv.lock) |
| 가상환경 생성 | venv, virtualenv | uv venv (자동 생성) |
| 파이썬 버전 관리 | pyenv | uv python install |
| CLI 도구 격리 실행 | pipx | uvx / uv tool |
| 프로젝트 관리 | Poetry, PDM | uv init / uv sync / uv run |
| 패키지 빌드·배포 | build, twine | uv build / uv publish |
Astral이 스스로 밝힌 목표가 "pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv 워크플로를 하나로 대체하는 단일 도구"입니다. 2026년 현재 마지막 줄인 라이브러리 배포 쪽을 빼면 대부분 실현됐습니다.
왜 빠른가
pip 대비 10~100배, Poetry 대비 대략 10배입니다. Sentry의 실제 의존성 세트로 측정한 콜드 설치는 uv 약 3초, Poetry 약 11초, pip-tools 약 33초입니다.
Rust로 만들었다는 것만으로 설명되지 않는 차이입니다. 실제 이유는 네 가지가 겹칩니다.
병렬 다운로드 — 패키지를 하나씩 순차로 받지 않습니다.
메타데이터 조회와 의존성 해결을 겹쳐서 실행 — pip은 메타데이터를 다 받은 뒤 해결을 시작하지만, uv는 두 작업과 디스크 쓰기를 동시에 굴립니다.
전역 중복 제거 캐시 — 같은 wheel을 두 번 저장하지 않습니다. 프로젝트 열 개가 같은 numpy를 쓰면 디스크에는 하나만 있습니다.
하드링크와 Copy-on-Write — 파일 시스템이 지원하면 복사 대신 링크를 겁니다. 가상환경 생성이 사실상 즉시 끝납니다.
캐시가 따뜻한 상태에서는 체감이 "조금 빠르다"가 아니라 다른 종류의 도구를 쓰는 느낌에 가까워집니다.
속도보다 중요한 것
uv를 속도로만 소개하면 절반을 놓칩니다. 실무에서 더 크게 와닿는 건 세 가지입니다.
파이썬이 없어도 설치됩니다. 단일 정적 바이너리라 파이썬 인터프리터도, 다른 패키지 매니저도 필요 없습니다. 오히려 uv가 파이썬을 설치합니다. CI 러너 이미지가 무슨 파이썬을 갖고 있든 신경 쓰지 않아도 되는 이유가 여기 있습니다.
락파일이 플랫폼을 안 가립니다. uv.lock 하나가 macOS·Linux·Windows에서 모두 동작합니다. pip-tools가 플랫폼별 파일을 따로 뽑아야 했던 문제가 사라집니다.
환경 활성화를 안 합니다. uv run이 실행 직전에 환경을 맞춰줍니다. source .venv/bin/activate를 잊어서 시스템 파이썬에 패키지를 깔아버리는 사고가 구조적으로 사라집니다.
표준을 따릅니다
uv는 자체 포맷을 만들지 않았습니다. pyproject.toml(PEP 517/518)을 그대로 쓰고, 스크립트 인라인 의존성은 PEP 723을 따릅니다. 표준 락파일 포맷인 PEP 751 pylock.toml과도 접점을 만들고 있습니다.
Poetry 프로젝트에서 uv sync가 그냥 돌아가는 것도 이 때문입니다. 서로 다른 도구가 같은 설정 파일을 읽습니다. 락파일 이동이 처음으로 현실적인 이야기가 됐습니다.
어디까지 안 되나
정직하게 짚어둡니다.
- 플러그인 생태계가 없습니다.
poetry-dynamic-versioning같은 도구에 의존한다면 대응물을 찾아야 합니다. - 라이브러리 배포 워크플로는 Poetry가 더 성숙합니다.
uv build·uv publish가 있지만 축적된 사례가 적습니다. - 의존성이 복잡하게 얽힌 경우 해결에 실패할 때가 있습니다. tensorflow·torch처럼 서브 의존성이 수십 개 걸리는 조합에서 Poetry가 더 관대하게 푸는 사례가 보고됩니다.
- Conda 전용 바이너리 패키지는 못 다룹니다. CUDA 빌드가 필요하면 Conda를 유지하세요.
2026년, 왜 uv를 봐야 하나
uv는 2024년 2월에 나온 비교적 새 도구입니다. 그런데 2년 만에 파이썬 생태계 한복판에 자리를 잡았습니다.
채택 규모
Simon Willison이 PyPI Stats를 인용해 밝힌 바로는 2026년 3월 한 달 다운로드가 1억 2,600만 회를 넘었습니다. Poetry는 같은 시기 6,600만 회 수준입니다. 다른 집계에서는 4월 기준 7,500만 회로 잡기도 하는데, 어느 쪽이든 Poetry를 앞선 상태입니다. 수치가 갈리는 이유는 미러·CI 트래픽을 어떻게 세느냐 차이로 보입니다.
소유권 변화 — OpenAI
2026년 3월 19일 OpenAI가 Astral 인수 합의를 발표했습니다. Astral은 uv 외에 린터 Ruff, 타입 체커 ty를 만든 회사입니다. Charlie Marsh를 포함한 팀 전체가 OpenAI Codex 팀에 합류할 예정이고, 인수 금액은 공개되지 않았습니다. 규제 승인이 남아 있어 아직 종결된 거래는 아닙니다.
양측 모두 오픈소스 도구를 계속 지원한다고 밝혔습니다. JetBrains는 PyCharm에 Ruff·uv 통합을 이어가겠다고 했고, 허용적 라이선스라 커뮤니티가 언제든 포크할 수 있다는 점도 언급했습니다.
실무자 입장에서 지금 할 일은 하나입니다. uv 버전을 lockfile에 고정해두고, 만약을 대비해 pip + venv라는 대안이 존재한다는 사실만 기억해두면 됩니다. 도구를 안 쓸 이유는 되지 않습니다.
설치
방법이 여러 개인데 대부분은 하나만 알면 됩니다.
권장 — standalone 설치 프로그램
파이썬이 없어도 됩니다. 자체 완결된 바이너리를 내려받는 방식이라 다른 사전 준비가 필요 없습니다.
macOS · Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
설치 확인:
uv --version
# uv 0.11.32
command not found가 뜨면 터미널을 새로 열어보세요. PATH 갱신이 반영되지 않은 경우입니다.
버전 고정 설치
CI나 팀 온보딩 스크립트라면 버전을 URL에 박아두는 편이 낫습니다.
curl -LsSf https://astral.sh/uv/0.11.32/install.sh | sh
설치 스크립트를 먼저 읽고 싶다면
파이프로 셸에 바로 넣는 게 꺼려진다면 내용을 먼저 확인할 수 있습니다.
curl -LsSf https://astral.sh/uv/install.sh | less
powershell -c "irm https://astral.sh/uv/install.ps1 | more"
설치 동작 조정
| 목적 | 방법 |
|---|---|
| 설치 경로 변경 | UV_INSTALL_DIR=/custom/path |
| 셸 프로파일 수정 안 함 | UV_NO_MODIFY_PATH=1 |
| 비대화식 실행 (CI) | 위 두 개 조합 |
UV_INSTALL_DIR="$HOME/.local/bin" UV_NO_MODIFY_PATH=1 \
curl -LsSf https://astral.sh/uv/install.sh | sh
패키지 매니저로 설치
시스템 패키지 매니저로 도구 버전을 통일해 관리하는 팀이라면 이쪽이 편합니다.
# macOS · Linux — Homebrew
brew install uv
# Windows — WinGet
winget install --id=astral-sh.uv -e
# Windows — Scoop
scoop install main/uv
pipx로 설치
파이썬 CLI 도구를 이미 pipx로 관리하고 있다면 결이 맞습니다.
pipx install uv
pip으로 설치 — 권장하지 않습니다
동작은 합니다. 다만 파이썬 인터프리터를 관리하는 도구를 설치하려고 파이썬 인터프리터가 필요한 순환 구조가 됩니다. 굳이 쓴다면 격리된 환경에 넣으세요.
pip install uv # 가능하지만 standalone 쪽이 낫습니다
Docker
공식 이미지를 씁니다. Dockerfile에서는 바이너리만 복사해오는 방식이 일반적입니다.
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
Cargo
크레이트 하나가 아직 crates.io에 없어서 Git에서 직접 빌드해야 합니다.
cargo install --git https://github.com/astral-sh/uv uv
GitHub Releases
프록시 뒤나 오프라인 환경이라면 릴리스 페이지에서 플랫폼별 바이너리를 직접 받아 PATH에 넣으면 됩니다.
설치 방법 선택 기준
| 상황 | 권장 |
|---|---|
| 그냥 빨리 쓰고 싶다 | standalone 설치 프로그램 |
| Homebrew·WinGet·Scoop로 도구를 통일 관리한다 | 해당 패키지 매니저 |
| 파이썬 CLI 도구를 pipx로 관리한다 | pipx |
| 컨테이너 안에서 쓴다 | ghcr.io/astral-sh/uv 이미지 |
| CI 워크플로 | astral-sh/setup-uv 액션 (아래 CI 섹션 참고) |
| 프록시 뒤·오프라인 | GitHub Releases 바이너리 |
| Rust 개발자이고 소스에서 빌드하고 싶다 | Cargo |
업그레이드
설치 방법에 따라 명령이 다릅니다. 여기서 자주 헷갈립니다.
uv self update # standalone 설치본만 동작
brew upgrade uv # Homebrew
winget upgrade astral-sh.uv # WinGet
scoop update uv # Scoop
pipx upgrade uv # pipx
cargo install --git https://github.com/astral-sh/uv uv --force # Cargo
uv self update가 "self-update is disabled" 같은 메시지를 뱉는다면 standalone이 아닌 방법으로 설치한 상태입니다. 설치할 때 쓴 도구로 올리세요.
uv self update는 설치 프로그램을 다시 실행하므로 셸 프로파일을 건드릴 수 있습니다. 그게 싫으면 INSTALLER_NO_MODIFY_PATH=1을 붙이세요.
uv를 올려도 uv가 관리하는 파이썬 버전들은 그대로 남습니다.
보안 패치가 포함된 릴리스가 나오는 도구입니다. 팀 프로젝트라면 CI에서 버전을 고정하되, 분기에 한 번 정도는 고정 버전을 올리는 주기를 잡아두는 편이 안전합니다.
삭제
바이너리만 지우면 캐시와 uv가 설치한 파이썬이 남습니다. 정리하려면 순서가 있습니다.
uv cache clean # 패키지 캐시
rm -r "$(uv python dir)" # uv가 설치한 파이썬 버전들
rm -r "$(uv tool dir)" # uv tool로 깐 CLI 도구들
그 다음 바이너리를 제거합니다.
rm ~/.local/bin/uv ~/.local/bin/uvx # standalone
brew uninstall uv # Homebrew
winget uninstall astral-sh.uv # WinGet
경로가 다를 수 있으니 which uv로 먼저 확인하세요.
두 가지 사용 방식 — 이걸 먼저 구분해야 합니다
uv를 처음 만나면 헷갈리는 지점이 있습니다. 명령이 두 계열로 나뉩니다.
| 계열 | 명령 | 성격 | 언제 |
|---|---|---|---|
| pip 호환 모드 | uv pip install, uv venv, uv pip sync |
pip 명령을 그대로 흉내, 락파일 없음 | 기존 프로젝트 속도만 올리고 싶을 때 |
| 프로젝트 모드 | uv init, uv add, uv sync, uv run |
pyproject.toml + uv.lock 관리 |
새 프로젝트, 재현성이 필요할 때 |
2025년 초 자료 대부분이 앞쪽만 다룹니다. 하지만 2026년 uv의 무게중심은 뒤쪽입니다. pip 호환 모드는 마이그레이션 다리이고, 프로젝트 모드가 본체입니다.
기존 requirements.txt 프로젝트라면 이 한 줄로 오늘 당장 이득을 봅니다.
uv pip install -r requirements.txt
여기서 멈춰도 됩니다. 다만 락파일과 재현성이 필요해지는 순간 프로젝트 모드로 넘어가게 됩니다.
프로젝트 워크플로 — 다섯 명령이면 끝납니다
uv 프로젝트 모드에서 실제로 매일 쓰는 명령은 다섯 개입니다.
프로젝트 생성
uv init my-app
cd my-app
pyproject.toml, .python-version, main.py, README.md가 생깁니다. 가상환경은 아직 없습니다. 첫 uv run이나 uv sync 때 자동으로 만들어집니다.
의존성 추가
uv add fastapi
uv add "pandas>=2.2"
uv add --dev pytest ruff
uv add는 세 가지를 한 번에 합니다. pyproject.toml에 항목을 쓰고, 의존성을 해결하고, uv.lock을 갱신합니다. 별도로 pip install + pip freeze를 돌릴 일이 없습니다.
환경 동기화
uv sync # 락파일대로 환경 맞추기
uv sync --locked # 락파일이 낡았으면 실패 (CI에서 필수)
uv sync --frozen # 락파일 검증 건너뛰기 (Docker 초기 레이어)
--locked와 --frozen의 차이가 실무에서 자주 문제를 일으킵니다. CI에서는 --locked를 써야 합니다. 누군가 pyproject.toml만 고치고 락파일을 커밋하지 않았을 때 빌드가 실패해야 하기 때문입니다.
실행
uv run python main.py
uv run pytest
uv run ruff check .
uv run은 실행 직전에 환경이 락파일과 맞는지 확인합니다. source .venv/bin/activate를 할 일이 없어집니다. 이 하나만으로도 팀 온보딩 문서가 절반으로 줄어듭니다.
의존성 갱신
uv lock --upgrade # 전체 갱신
uv lock --upgrade-package fastapi # 특정 패키지만
uv.lock — 왜 커밋해야 하나
uv.lock은 전이 의존성까지 정확한 버전으로 못박은 파일입니다. Poetry의 poetry.lock, npm의 package-lock.json과 같은 역할입니다.
특징 세 가지를 짚어둡니다.
플랫폼 무관 — 하나의 uv.lock이 macOS·Linux·Windows에서 모두 동작합니다. pip-tools가 플랫폼별 파일을 따로 뽑아야 했던 문제가 사라집니다.
사람이 읽을 수 있음 — TOML 형식이라 diff가 읽힙니다. PR 리뷰에서 "이 패키지가 왜 올라갔지"를 추적할 수 있습니다.
직접 편집 금지 — 손으로 고치지 마세요. uv lock, uv add, uv sync가 관리합니다.
PEP 751 pylock.toml은 어떻게 되나
파이썬 진영에 pylock.toml이라는 표준 락파일 포맷이 생겼습니다. pip은 실험적으로 읽고, Poetry는 내보내기를 지원하며, uv는 자체 uv.lock을 유지하면서 이 포맷과도 접점을 만들고 있습니다. 도구 간 락파일 이동이 처음으로 현실성을 갖게 된 셈입니다.
지금 당장 할 일은 없습니다. 어느 도구를 쓰든 락파일을 버전 관리에 넣어두면 됩니다.
# .gitignore
.venv/
__pycache__/
# uv.lock 은 커밋합니다 — 여기 넣지 마세요
pyenv·pipx도 필요 없어집니다
uv를 소개할 때 패키지 설치만 얘기하면 절반을 빠뜨리는 겁니다.
파이썬 버전 관리 (pyenv 대체)
uv는 파이썬 자체를 내려받아 관리합니다. pyenv도, deadsnakes PPA도, 소스 컴파일도 필요 없습니다.
uv python install 3.12 3.13 # 여러 버전 한 번에
uv python list # 설치된 버전 확인
uv python pin 3.12 # .python-version 생성
uv run --python 3.11 script.py # 일회성으로 다른 버전 사용
CI에서 특히 유용합니다. 러너 이미지가 어떤 파이썬을 갖고 있든 상관없이 프로젝트가 지정한 버전이 확정적으로 깔립니다.
CLI 도구 실행 (pipx 대체)
uvx ruff check . # 설치 없이 일회성 실행
uv tool install ruff # 전역 설치
uv tool list
uv tool upgrade --all
uvx는 uv tool run의 축약입니다. 캐시된 환경에서 바로 돌기 때문에 pipx보다 훨씬 빠릅니다.
스크립트 단독 실행 (PEP 723)
파일 하나짜리 스크립트에 의존성을 직접 적을 수 있습니다.
# /// script
# requires-python = ">=3.12"
# dependencies = ["httpx", "rich"]
# ///
import httpx
from rich import print
print(httpx.get("https://api.github.com").json())
uv run script.py
가상환경을 만들 필요도, requirements.txt를 쓸 필요도 없습니다. uv가 헤더를 읽고 임시 환경을 만들어 실행합니다. 운영 스크립트나 일회성 도구에 잘 맞습니다.
마이그레이션 — pip과 Poetry에서
requirements.txt에서
가장 간단합니다. 두 갈래로 갈립니다.
A. 명령만 바꾸기 (5초, 무위험)
uv pip install -r requirements.txt
pyproject.toml도 락파일도 안 만듭니다. 속도만 가져갑니다.
B. 프로젝트 모드로 이전 (10분)
uv init --bare # pyproject.toml만 생성
uv add -r requirements.txt # 의존성 이관
uv add --dev -r requirements-dev.txt # 개발 의존성
uv sync
이관이 끝나면 requirements.txt를 지우기 전에 uv run pytest로 한 번 검증하세요. 버전 범위가 없던 항목이 예상보다 높은 버전으로 잡히는 경우가 있습니다.
Poetry에서
전용 도구가 있습니다.
uvx migrate-to-uv
pyproject.toml의 [tool.poetry] 섹션을 표준 [project] 형식으로 바꾸고, 의존성 그룹을 옮기고, poetry.lock을 참고해 uv.lock을 만듭니다.
수동으로 하고 싶다면 이 순서입니다.
poetry export -f requirements.txt --output requirements.txt --without-hashesuv init --bareuv add -r requirements.txtuv sync && uv run pytest- 검증 끝나면
poetry.lock삭제
마이그레이션 전에 확인할 것
| 항목 | 확인 |
|---|---|
| Poetry 플러그인 의존 | poetry-dynamic-versioning 등은 uv에 대응물이 없습니다 |
| 라이브러리 배포 | uv도 uv build/uv publish를 지원하지만 Poetry 워크플로가 더 성숙합니다 |
| Dockerfile | poetry install 줄을 전부 바꿔야 합니다 |
| CI 워크플로 | 캐시 경로와 설치 액션이 달라집니다 |
| Makefile·배포 스크립트 | poetry run 호출을 찾아 바꾸세요 |
새 명령이 검증될 때까지 옛 명령을 주석으로 남겨두는 편이 안전합니다.
Docker 적용
uv 공식 문서가 권장하는 패턴은 2단계 sync입니다. 의존성 레이어와 프로젝트 레이어를 분리해 캐시 적중률을 높입니다.
FROM python:3.12-slim
# uv 바이너리 복사 (distroless 이미지에서)
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /app
# 1단계: 의존성만 설치 (소스가 바뀌어도 이 레이어는 재사용)
COPY pyproject.toml uv.lock ./
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-install-project --no-dev
# 2단계: 프로젝트 설치
COPY . /app
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev
ENV PATH="/app/.venv/bin:$PATH"
CMD ["uv", "run", "python", "-m", "myapp"]
핵심 세 가지를 짚습니다.
--frozen과 --locked의 사용처가 다릅니다. 첫 sync에서는 프로젝트 파일이 아직 없어 락파일 검증이 불가능하므로 --frozen을 씁니다. 두 번째 sync에서는 --locked로 검증할 수 있습니다. 워크스페이스를 쓴다면 멤버 pyproject.toml이 다 복사되기 전까지는 --frozen을 유지하세요.
.dockerignore에 .venv를 넣으세요. 로컬 가상환경은 플랫폼에 종속돼 있어 이미지에 들어가면 안 됩니다. 수백 MB를 그냥 버리는 셈이기도 합니다.
.venv
.git
pycache
*.pyc
.ruff_cache
.mypy_cache개발 의존성은 UV_NO_DEV=1 또는 --no-dev로 제외합니다. 프로덕션 이미지에 pytest가 들어갈 이유가 없습니다.
파이썬 베이스 이미지 없이 가는 방법도 있습니다.
FROM debian:bookworm-slim
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
ENV UV_PYTHON_INSTALL_DIR="/usr/local"
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-install-project
uv가 파이썬 자체를 설치하므로 베이스 이미지 선택이 자유로워집니다.
GitHub Actions 적용
공식 액션 astral-sh/setup-uv를 씁니다.
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@v8.1.0
with:
version: "0.11.32" # 버전 고정 권장
enable-cache: true # uv 캐시 지속
- name: Install dependencies
run: uv sync --locked --all-extras --dev
- run: uv run ruff check .
- run: uv run ruff format --check .
- run: uv run pytest
몇 가지 실무 포인트가 있습니다.
버전을 고정하세요. setup-uv는 v8부터 @v8 같은 이동 태그를 더 이상 발행하지 않습니다. 전체 버전 태그나 커밋 SHA를 쓰세요. uv 자체 버전도 version: 옵션으로 고정하는 편이 재현성에 좋습니다.
--locked를 빼지 마세요. 락파일이 낡았으면 CI가 실패해야 합니다. 이 플래그가 없으면 uv가 조용히 락파일을 갱신하고 지나가서, 로컬과 CI가 다른 버전으로 도는 상황이 생깁니다.
캐시는 enable-cache: true 한 줄이면 됩니다. actions/cache로 직접 관리할 수도 있지만 대부분은 필요 없습니다.
가상환경 없이 시스템에 설치하려면 UV_PROJECT_ENVIRONMENT 환경변수를 쓰면 됩니다. 컨테이너 기반 CI에서 몇 초를 더 줄일 수 있습니다.
파이썬 버전은 두 방법 중 하나로 잡습니다.
# 방법 1: uv가 설치 (.python-version 존중)
- run: uv python install
# 방법 2: GitHub 캐시 활용 (더 빠름)
- uses: actions/setup-python@v5
with:
python-version-file: ".python-version"
uv vs Poetry vs pip — 2026년 기준
속도 (Sentry 실제 의존성 세트 벤치마크)
| 작업 | uv | Poetry | pip-tools |
|---|---|---|---|
| 콜드 설치 (락파일에서) | 약 3초 | 약 11초 | 약 33초 |
| 락파일 생성 | 약 8초 | 약 22초 | 약 35초 |
pip 대비로는 10~100배, Poetry 대비로는 대략 10배 차이가 납니다. 작은 프로젝트에서는 체감이 없습니다. 의존성이 많은 프로젝트, 특히 CI에서는 실제 비용으로 돌아옵니다.
기능 비교
| 항목 | uv | Poetry | pip |
|---|---|---|---|
| 패키지 설치 | ✅ | ✅ | ✅ |
| 가상환경 관리 | ✅ | ✅ | ❌ (venv 별도) |
| 파이썬 버전 관리 | ✅ | ❌ | ❌ |
| 락파일 | ✅ uv.lock |
✅ poetry.lock |
❌ |
| CLI 도구 실행 | ✅ uvx |
❌ | ❌ |
| 워크스페이스(모노레포) | ✅ | ❌ | ❌ |
| 스크립트 인라인 의존성 | ✅ PEP 723 | ❌ | ❌ |
| 플러그인 생태계 | ❌ | ✅ | ✅ |
| 라이브러리 배포 성숙도 | 보통 | 높음 | 낮음 |
| 파이썬 없이 설치 | ✅ 단일 바이너리 | ❌ | 내장 |
선택 기준
uv를 쓰세요
- 새 프로젝트를 시작한다
- CI 시간이 아깝다
- 모노레포에서 여러 패키지가 락파일을 공유해야 한다
- pyenv + virtualenv + pip-tools 세 개를 관리하는 게 지겹다
Poetry를 유지하세요
- 팀이 이미 잘 쓰고 있고 병목이 아니다
poetry-dynamic-versioning같은 플러그인에 의존한다- 라이브러리를 PyPI에 배포하는 게 주 업무다
- Poetry의 의존성 그룹 모델이 팀 관행에 맞다
pip은 계속 남습니다
CPython에 내장돼 있어 어디서든 확실히 존재합니다. 도커 베이스 이미지 한 줄, 남의 서버 긴급 디버깅 같은 상황에서 결국 쓰게 됩니다. 완전히 벗어날 수 있는 도구가 아니고, 그래도 괜찮습니다.
자주 발생하는 문제
uv sync가 락파일을 자꾸 고쳐 쓴다
CI라면 --locked를 붙이세요. 락파일이 최신이 아니면 실패시키는 게 맞습니다.
Poetry 프로젝트에서 uv sync가 그냥 동작하던데?
uv가 Poetry 형식 pyproject.toml을 읽어 uv.lock을 만들어줍니다. 다만 의존성 그룹 매핑이나 플러그인 설정은 넘어오지 않습니다. 정식 이전은 uvx migrate-to-uv를 쓰세요.
Docker 빌드가 매번 전체 재설치를 한다COPY . /app을 uv sync보다 먼저 하고 있을 가능성이 큽니다. pyproject.toml과 uv.lock만 먼저 복사하고 sync를 돌린 뒤에 소스를 복사하세요.
.venv가 Docker 이미지에 들어가 이미지가 거대해졌다.dockerignore에 .venv를 추가하세요. 로컬 가상환경은 플랫폼에 종속돼 컨테이너에서 동작하지도 않습니다.
tensorflow·torch 같은 무거운 패키지에서 해결이 실패한다
서브 의존성이 50개 넘게 얽히는 조합에서 Poetry가 더 관대하게 푸는 경우가 있습니다. 이럴 때는 버전을 명시적으로 고정하거나 --resolution lowest-direct 옵션을 시도해보세요.
Conda 환경에서 쓸 수 있나
uv는 어떤 파이썬 환경에도 패키지를 설치할 수 있어 Conda 환경 안에서도 동작합니다. 다만 CUDA 같은 Conda 전용 바이너리 패키지가 필요하면 Conda를 유지하는 편이 낫습니다.
팀원마다 uv 버전이 달라 결과가 다르다
CI에서 version:으로 고정하고, 로컬은 uv self update로 주기적으로 맞추세요. 프로젝트 README에 권장 버전을 적어두는 것도 방법입니다.
자주 묻는 질문 (FAQ)
Q. OpenAI가 인수했는데 uv를 계속 써도 되나요?
쓰셔도 됩니다. 2026년 3월 발표된 거래는 규제 승인을 조건으로 하고 있고, OpenAI와 Astral 모두 오픈소스 도구를 계속 지원한다고 밝혔습니다. JetBrains도 PyCharm의 Ruff·uv 통합을 이어가겠다고 했습니다. 라이선스가 허용적이라 커뮤니티 포크도 언제든 가능합니다. 실무에서 할 일은 버전을 고정해두고 pip + venv라는 대안이 존재한다는 걸 기억하는 정도입니다.
Q. pip에서 uv로 옮기면 위험한가요?uv pip install은 pip의 드롭인 대체라 동작이 같습니다. 명령 앞에 uv만 붙이면 되고 되돌리기도 쉽습니다. 프로젝트 모드(uv init + uv add)로 완전히 옮기는 건 별개 작업이고, 이쪽은 검증 시간을 좀 잡으세요.
Q. Poetry를 지금 버려야 하나요?
아닙니다. Poetry 2.x는 성숙하고 안정적이며 6,600만 다운로드 규모로 활발히 유지되고 있습니다. 잘 돌아가는 프로젝트를 옮길 이유는 없습니다. 구체적인 통증이 있을 때 — CI가 느리다, 파이썬 버전 관리가 번거롭다 — 그때 검토하세요.
Q. uv.lock을 git에 커밋해야 하나요?
네. 애플리케이션이라면 반드시 커밋하세요. 재현 가능한 빌드의 핵심입니다. 라이브러리를 배포하는 경우에도 개발 환경 재현을 위해 커밋하는 편이 낫습니다.
Q. uv sync --locked와 --frozen은 뭐가 다른가요?--locked는 락파일이 pyproject.toml과 맞는지 검증하고 안 맞으면 실패합니다. --frozen은 검증을 건너뛰고 락파일 그대로 설치합니다. CI에서는 --locked, Docker 초기 레이어에서는 --frozen이 맞습니다.
Q. uv가 pyenv를 완전히 대체하나요?
파이썬 버전 설치와 프로젝트별 고정이라는 핵심 기능은 대체합니다. uv python install, uv python pin으로 처리됩니다. 다만 시스템 전역 파이썬을 바꾸는 pyenv의 shim 방식과는 동작이 다릅니다. 프로젝트 단위로 쓴다면 uv만으로 충분합니다.
Q. 모노레포에서 쓸 수 있나요?
uv 워크스페이스가 이 용도입니다. 여러 패키지가 하나의 uv.lock을 공유하고, 패키지 간 로컬 참조도 됩니다. Poetry에는 없는 기능입니다.
Q. uvx와 uv tool run은 다른 건가요?
같습니다. uvx가 uv tool run의 축약입니다. 일회성 실행이라면 uvx ruff check .처럼 쓰고, 자주 쓴다면 uv tool install ruff로 전역 설치하세요.
Q. Windows에서도 동일한가요?
설치 방법만 다르고 명령은 같습니다. PowerShell에서 irm https://astral.sh/uv/install.ps1 | iex로 설치하거나 winget install astral-sh.uv를 쓰세요.
Q. requirements.txt를 다시 뽑을 수 있나요?
uv export --format requirements-txt --no-hashes > requirements.txt
레거시 배포 파이프라인과 공존해야 할 때 유용합니다.
이 글의 핵심 메트릭
- uv 최초 릴리스: 2024년 2월
- 월 PyPI 다운로드: 1억 2,600만+ (2026.03, PyPI Stats) / 집계에 따라 7,500만 (2026.04)
- Poetry 월 다운로드: 약 6,600만 (2026.02)
- 콜드 설치 벤치마크: uv 3초 / Poetry 11초 / pip-tools 33초
- 소유권: Astral → OpenAI (2026.03.19 인수 발표, 규제 승인 대기)
- 검증 버전: uv 0.11.x / Python 3.12 / macOS Sequoia 15.x
함께 읽으면 좋은 글
📚 파이썬 & 개발 환경 시리즈
공식 문서는 docs.astral.sh/uv에 있습니다.
'Programming > Python' 카테고리의 다른 글
| 파이썬 이미지 배경 제거(누끼) 완벽 가이드 (2026) — rembg 모델 5종 비교와 상업용 라이선스 주의사항 (0) | 2026.07.30 |
|---|---|
| decorator - 데커레이터 (0) | 2024.10.30 |
| python 으로 asdict, from_dict 직접 구현 (0) | 2023.12.18 |
| docker compose - python default 컨테이너 만들기 (0) | 2023.04.05 |
| try except를 깔끔하게 사용하기 - suppress (0) | 2023.01.31 |
댓글