파이썬 프로젝트 하나를 새로 시작할 때 보통 이런 순서를 거칩니다. pyenv로 파이썬 버전을 맞추고, python -m venv .venv로 가상환경을 만들고, pip install로 패키지를 깔고, 의존성 버전을 고정하려면 pip freeze나 poetry를 따로 도입합니다. 도구 네 개가 각자 한 조각씩만 맡고 있어서, 신입 개발자에게 환경 설정을 설명하려면 이 네 가지를 순서대로 다 알려줘야 합니다. uv는 Astral(Ruff를 만든 팀)이 Rust로 작성한 패키지·프로젝트 매니저로, 이 네 도구가 나눠 맡던 역할을 하나의 바이너리로 합쳤습니다.

uv와 pip, Poetry, pip-tools 등 기존 파이썬 패키지 설치 도구의 설치 속도를 비교한 공식 벤치마크 막대그래프
uv 공식 저장소(astral-sh/uv)의 설치 속도 벤치마크 — 웜 캐시 기준으로 기존 도구 대비 수십 배 빠릅니다.

핵심 개념

  • 프로젝트 모드: uv init으로 프로젝트를 만들면 pyproject.toml에 의존성이 정리되고, 가상환경은 uv가 알아서 .venv에 만들어둡니다. pip처럼 가상환경을 켜고 끄는 걸 신경 쓸 필요가 거의 없습니다.
  • uv.lock: poetry.lock과 비슷하지만 플랫폼(OS·아키텍처·파이썬 버전)별 분기까지 하나의 파일에 다 담는 범용 락파일입니다. CI에서 리눅스로 빌드하고 로컬은 macOS를 쓰는 경우에도 락파일이 하나로 공유됩니다.
  • uv run: 가상환경을 직접 활성화하지 않고도 uv run python script.py처럼 바로 실행할 수 있습니다. 실행 전에 pyproject.toml과 uv.lock이 어긋나 있으면 먼저 동기화부터 하고 실행합니다.
  • 파이썬 버전 관리 내장: pyenv 없이도 uv python install 3.12로 원하는 파이썬 버전을 받아서 프로젝트별로 고정할 수 있습니다.
  • uvx: pipx run과 같은 역할로, 전역 설치 없이 CLI 도구를 그때그때 받아서 실행합니다(uvx ruff check .).

실전 예시

새 프로젝트를 만들면 pyproject.toml과 .venv, uv.lock이 한 번에 갖춰집니다.

uv init my-api
cd my-api
# pyproject.toml
[project]
name = "my-api"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = []

의존성을 추가하면 설치와 동시에 pyproject.toml·uv.lock이 같이 갱신됩니다.

uv add fastapi "uvicorn[standard]"
# pyproject.toml (갱신됨)
dependencies = [
    "fastapi>=0.115.0",
    "uvicorn[standard]>=0.32.0",
]

테스트나 린트처럼 배포에는 필요 없는 의존성은 그룹으로 분리합니다.

uv add --dev pytest ruff

가상환경을 직접 켜지 않고 바로 실행합니다.

uv run uvicorn main:app --reload

다른 머신에서 그대로 복원할 때는 락파일 기준으로만 설치합니다. 이 명령은 pyproject.toml을 다시 읽지 않고 uv.lock에 적힌 버전 그대로만 설치하므로, CI에서 "로컬에서는 되는데 CI에서는 버전이 다르게 깔린다" 문제를 막아줍니다.

uv sync --frozen

파이썬 버전 자체도 프로젝트에 고정할 수 있습니다.

uv python pin 3.12

이 명령은 프로젝트 루트에 .python-version 파일을 만들고, 이후 uv run·uv sync는 이 버전의 인터프리터를 자동으로 받아서 씁니다. 팀원 컴퓨터에 해당 버전이 없어도 uv가 알아서 내려받기 때문에 "내 파이썬 버전은 3.11인데요"로 시작하는 대화가 줄어듭니다.

비슷한 도구와 비교

항목 uv pip + venv Poetry Conda
설치 속도 빠름(Rust, 병렬 다운로드+캐시) 기준 uv보다 느림 가장 느린 편
파이썬 버전 관리 내장(uv python install) 없음(pyenv 별도 필요) 없음(pyenv 별도 필요) 내장
락파일 uv.lock(플랫폼 통합) 없음(freeze로 흉내) poetry.lock environment.yml + 별도 락 도구
표준 pyproject.toml 호환 호환 해당 없음 자체 섹션 의존 큼 해당 없음
CLI 일회성 실행(pipx 대체) uvx 내장 없음 없음 없음

Poetry는 오랫동안 사실상 표준이었고 플러그인 생태계도 넓어서, 이미 Poetry로 굳어진 팀이 당장 바꿀 이유는 크지 않습니다. 다만 새 프로젝트라면 설치 속도와 파이썬 버전 관리까지 한 바이너리로 끝난다는 점에서 uv 쪽이 설정할 도구 가짓수가 적습니다. Conda는 비-파이썬 바이너리 의존성(예: CUDA, 시스템 라이브러리)까지 다뤄야 하는 데이터 과학·ML 환경에서는 여전히 대체하기 어렵습니다.

넘어갈 때 걸리는 부분

기존 requirements.txt 기반 프로젝트에 붙일 때는 uv pip install -r requirements.txt처럼 pip 호환 명령으로 먼저 써볼 수 있습니다. 다만 이 모드에서는 uv.lock이 생기지 않으므로, 락파일의 이점을 보려면 결국 uv add로 의존성을 다시 선언하는 프로젝트 모드로 넘어가야 합니다. 사내 PyPI 미러처럼 커스텀 인덱스를 쓰는 환경에서는 pip.conf가 아니라 pyproject.toml의 [[tool.uv.index]]에 따로 설정을 옮겨야 하는 것도 처음 도입할 때 자주 놓치는 부분입니다.

버전은 아직 1.0 이전(0.x) 대역이라 마이너 버전 올릴 때 CLI 플래그가 바뀌는 경우가 종종 있어서, CI에서는 uv 버전을 고정해두는 편이 안전합니다.