TechFeedTechFeed
Programming Languages

Python uv 완전 가이드 | pip·Poetry 대비 설치 속도 10~100배, 한국 개발자 실전

uv는 Rust 기반 Python 패키지 매니저로 pip 대비 설치 속도가 10~100배 빠르다. pip·Poetry·pyenv·pipx를 단일 도구로 대체하며, 가상환경 관리·lock 파일·Python 버전 관리까지 담당한다. 기본 사용법부터 GitHub Actions CI 연동, Poetry 마이그레이션, 사내 PyPI 미러 설정까지 한국 개발자 환경에 맞게 정리한다.

by

pip install 명령 하나가 30초 걸리는 환경에 익숙해진 뒤, uv로 같은 패키지를 설치했을 때 0.8초가 나왔다. 처음엔 캐시가 있는 줄 알았다. 클린 환경에서 다시 해도 비슷했다.


uv는 Astral이 만든 Rust 기반 Python 패키지 매니저다. pip 대체재로 시작했지만 지금은 가상환경 관리, 프로젝트 도구, 파이썬 버전 관리까지 담당한다. 오픈AI가 Astral을 인수한 뒤 더 주목받고 있지만, 실제로 쓸 만한지는 직접 써봐야 안다. 이 글은 pip·Poetry를 쓰던 개발자가 uv로 전환할 때 마주치는 패턴과 판단 기준을 정리한다.


uv란 무엇인가 | pip·Poetry·pyenv를 대체하는 단일 도구

uv는 Rust로 작성된 Python 패키지·프로젝트 관리 도구다. 2024년 2월 처음 나왔을 때는 "pip 대신 쓰는 빠른 설치기" 수준이었지만, 1.0 릴리스 이후 역할이 크게 넓어졌다.


  • 패키지 설치 — pip 대체. uv pip install 또는 uv add.
  • 가상환경uv venv로 생성, 내부적으로 자동 관리.
  • 프로젝트 관리 — Poetry처럼 pyproject.toml·lock 파일 기반 재현 환경.
  • 파이썬 버전 — pyenv 없이 uv python install 3.13으로 설치·전환.
  • 툴 실행uv run·uv tool run으로 격리된 툴 실행 (pipx 대체).

하나의 바이너리가 이 범위를 커버한다. pip·venv·Poetry·pyenv·pipx 조합을 각기 배울 필요 없이, uv 하나로 워크플로가 끝난다는 점이 1인 개발자나 작은 팀에서 환영받는 이유다.


오픈AI의 Astral 인수(2026년 초) 이후 기업 환경에서도 도입 검토가 늘었다. Ruff(Python 린터)도 같은 회사 제품이라 툴체인 통합이 자연스럽다.


uv 패키지 매니저 설치 속도 비교 — pip·Poetry·uv 벤치마크
uv는 Rust 기반 병렬 다운로드로 pip 대비 10~100배 빠른 설치를 제공한다

pip·Poetry 대비 속도 비교 | 왜 이렇게 빠른가

아래 수치는 동일 MacBook M3 Pro, 클린 캐시 기준으로 django + rest_framework + celery + redis + psycopg2-binary 5개 패키지를 설치하는 데 걸린 시간이다. 환경마다 다르지만 상대적 비율은 비슷하게 나온다.


도구클린 캐시캐시 있음특이사항
pip28~35초12~18초직렬 의존성 해결
Poetry42~55초20~28초해결 알고리즘 무거움
uv (cold)2~4초0.5~1.5초병렬 다운로드·Rust 해결기

uv가 빠른 이유는 세 가지다. 첫째, 의존성 해결기가 Rust로 구현돼 있고 병렬로 실행된다. 둘째, 전역 캐시가 있어 같은 패키지를 두 번째 프로젝트부터는 네트워크 없이 가져온다. 셋째, 파이썬 인터프리터를 거치지 않고 바이너리 자체가 설치를 처리한다.


속도 차이가 가장 실감 나는 구간은 CI 파이프라인이다. GitHub Actions에서 의존성 설치 단계가 40초에서 3초로 줄면 전체 파이프라인 비용이 눈에 띄게 바뀐다.


설치와 기본 사용법 | curl 한 줄로 시작

uv 설치는 공식 스크립트로 하는 것이 가장 안전하다. Homebrew·pip·cargo로도 설치 가능하지만, 공식 스크립트는 OS별 최적 경로를 자동으로 잡아준다.


uv 설치 (macOS·Linux·Windows)
# 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.5.x (또는 최신) # Homebrew로도 가능 brew install uv

설치 후 기본 워크플로는 크게 두 가지다. 기존 pip처럼 쓰는 방식Poetry처럼 프로젝트를 init해서 쓰는 방식이다.


pip 대체 모드 — 기존 개발자에게 가장 빠른 진입
# 가상환경 생성 uv venv # 패키지 설치 (pip install 대체) uv pip install django djangorestframework # requirements.txt 설치 uv pip install -r requirements.txt # 패키지 목록 uv pip list # 언인스톨 uv pip uninstall django
프로젝트 모드 — pyproject.toml 기반 (Poetry 대체)
# 새 프로젝트 초기화 uv init my-project cd my-project # 패키지 추가 (pyproject.toml + uv.lock 자동 관리) uv add django uv add --dev pytest ruff # 환경 동기화 (lock 파일 기준) uv sync # 스크립트 실행 (자동으로 .venv 활성화) uv run python manage.py runserver # lock 파일 갱신 uv lock
핵심 차이: uv pip install은 현재 활성 환경에 설치(pip처럼). uv add는 pyproject.toml에 등록하고 lock 파일까지 갱신한다. 팀 프로젝트라면 uv add를, 빠른 실험이나 개인 도구는 uv pip install을 쓰면 된다.

Python 버전 관리 | pyenv 없이 3.13까지 설치

uv는 Python 바이너리도 직접 관리한다. pyenv를 완전히 대체할 수 있다.


Python 버전 설치·전환
# 설치 가능한 버전 목록 uv python list # 특정 버전 설치 uv python install 3.12 uv python install 3.13 # 현재 프로젝트에 Python 버전 고정 uv python pin 3.12 # 특정 버전으로 가상환경 생성 uv venv --python 3.12 # .python-version 파일 자동 생성됨 cat .python-version # 3.12

팀마다 Python 버전이 다를 때 .python-version 파일을 커밋하면 된다. uv sync를 실행하면 해당 버전이 없을 때 자동으로 다운로드한다.


macOS 시스템 Python을 건드리지 않고 독립적으로 관리하기 때문에 시스템 라이브러리 충돌 걱정이 없다. Apple Silicon Mac에서 Rosetta 없이 arm64 바이너리를 받아 주는 점도 실용적이다.


uv venv 가상환경 생성 및 Python 버전 관리 CLI 화면
uv venv와 uv python install로 pyenv 없이 Python 버전을 관리한다

기존 프로젝트 마이그레이션 | pip·Poetry에서 전환하는 법

기존 프로젝트를 uv로 전환할 때 주요 경로 세 가지다.


기존 도구마이그레이션 방법주의점
pip + requirements.txtuv pip install -r requirements.txt 그대로 사용 가능점진 전환 가능. lock 파일 없음
Poetryuv init → poetry.lock 기반 uv add 반복 또는 uv import poetry.lockdev 그룹 설정 확인 필수
pipenvPipfile을 requirements.txt로 export 후 uv로 재설치pipenv는 빌드 도구가 달라 직접 변환 없음
conda과학 패키지는 병행 유지 권장. 순수 Python 부분만 uv로CUDA·MKL 의존성은 conda가 더 안전

Poetry에서 마이그레이션할 때 가장 많이 걸리는 부분은 dev dependency 그룹이다. Poetry의 [tool.poetry.group.dev.dependencies]는 uv의 [dependency-groups]로 옮긴다. pyproject.toml 형식이 약간 다르지만 의미는 동일하다.


Poetry → uv 전환 pyproject.toml 비교
# Poetry 형식 (기존) [tool.poetry.dependencies] python = "^3.12" django = "^5.0" [tool.poetry.group.dev.dependencies] pytest = "^8.0" ruff = "^0.3" # ↓ uv 형식 (전환 후) [project] name = "my-project" requires-python = ">=3.12" dependencies = [ "django>=5.0", ] [dependency-groups] dev = [ "pytest>=8.0", "ruff>=0.3", ]

CI/CD 연동 | GitHub Actions에서 uv 쓰는 법

CI 파이프라인에서 uv의 속도 차이가 가장 두드러진다. 공식 astral-sh/setup-uv 액션을 쓰면 캐시 설정까지 한 줄로 해결된다.


GitHub Actions — uv 캐시 적용 예시
name: CI on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up uv uses: astral-sh/setup-uv@v3 with: enable-cache: true # 패키지 캐시 자동 적용 - name: Install Python run: uv python install 3.12 - name: Install dependencies run: uv sync --frozen # lock 파일 기준 설치 (갱신 안 함) - name: Run tests run: uv run pytest - name: Lint run: uv run ruff check .

--frozen 플래그는 lock 파일과 pyproject.toml이 일치하지 않으면 에러를 내게 한다. CI에서 의도치 않은 버전 갱신을 막는 안전장치다. 로컬에서 uv sync만 하면 lock 파일이 자동 갱신되니, CI와 로컬 사이 동작 차이가 생기지 않도록 주의한다.


GitHub Actions 캐시 키는 OS + uv.lock 해시 기반으로 자동 생성된다. lock 파일이 바뀌면 캐시 미스가 나서 재설치한다. 변경이 없으면 캐시 히트로 대부분의 패키지를 건너뛴다.


GitHub Actions에서 uv 캐시 적용으로 CI 빌드 시간 단축 화면
astral-sh/setup-uv 액션 적용 후 GitHub Actions 의존성 설치 단계가 40초에서 3초로 줄었다

한국 개발 환경에서 주의할 것

실제 전환 시 걸리는 몇 가지 사항이다.


1. 기업 사내 PyPI 미러 — 많은 한국 기업이 사내 보안 정책상 PyPI 미러를 사용한다. uv는 ~/.config/uv/uv.toml이나 프로젝트 .uv/uv.toml에서 인덱스를 지정한다.


사내 PyPI 미러 설정 (uv.toml)
# ~/.config/uv/uv.toml 또는 프로젝트 루트 .uv/uv.toml [[index]] url = "https://pypi-mirror.company.internal/simple" default = true # 추가 인덱스 (기본값 PyPI + 사내) [[index]] url = "https://pypi.org/simple" name = "pypi" default = false

2. SSL 인증서 문제 — 사내 CA 인증서를 사용하는 환경에서 uv가 SSL 오류를 낼 수 있다. 환경변수 UV_NATIVE_TLS=1을 설정하면 시스템 신뢰 저장소를 사용한다.


3. conda 병행 환경 — 데이터 분석·ML 팀은 conda 환경과 uv를 동시에 쓰는 경우가 많다. conda 기반 가상환경 안에서 uv pip install을 쓰면 conda 패키지와 충돌이 날 수 있다. conda 환경은 conda로, 순수 Python 웹 서비스는 uv로 분리하는 것이 안전하다.


4. M1/M2/M3 Mac + Rosetta — uv는 arm64 바이너리를 네이티브로 지원한다. Python 설치도 arm64 빌드를 받아 준다. x86_64 전용 패키지가 있으면 UV_PYTHON_DOWNLOADS=manual로 수동 지정해야 한다.


5. VS Code Python 인터프리터 경로 — uv가 만든 가상환경은 기본적으로 .venv 폴더에 생긴다. VS Code에서 Python: Select Interpreter.venv/bin/python을 선택하면 된다. Pylance·Ruff 확장도 자동으로 이 경로를 잡아준다.


언제 pip·Poetry를 유지해야 하나

uv가 만능이 아닌 상황도 있다. 전환 전에 확인할 항목이다.


  • C 확장 패키지 빌드 — uv는 설치를 빠르게 하지 이진 빌드를 대신하지는 않는다. wheel이 없어 소스 컴파일이 필요한 패키지(일부 ML 라이브러리 등)는 빌드 툴체인이 별도로 필요하다.
  • conda 필수 패키지 — scipy, numpy, 일부 CUDA 패키지는 conda 빌드가 훨씬 안정적이다. 이 경우 conda를 유지한다.
  • 배포 파이프라인이 Poetry에 깊이 엮인 경우 — Dockerfile·CI 스크립트가 poetry export에 의존한다면 점진적 전환 계획이 필요하다. 한 번에 바꾸는 것보다 새 프로젝트부터 uv를 쓰고 기존 것은 유지하는 접근이 현실적이다.
  • 팀 모두가 윈도우 — uv의 Windows 지원은 개선됐지만, 일부 엣지 케이스가 Linux/macOS보다 늦게 해결된다. Windows 전용 팀은 한 명이 먼저 충분히 테스트한 뒤 적용하는 것이 낫다.

자주 묻는 질문

uv.lock을 git에 커밋해야 하나요?

팀 프로젝트라면 커밋하는 것이 권장된다. lock 파일은 의존성 버전을 고정해 "내 컴퓨터에서는 되는데" 문제를 줄인다. 라이브러리(배포하는 패키지)는 lock 파일 없이 constraints만 지정하는 것이 일반적이다.


uv와 pip의 requirements.txt 형식이 다른가요?

아니다. uv pip install -r requirements.txt는 pip 형식 그대로 읽는다. 기존 파일을 수정 없이 쓸 수 있다. uv의 lock 파일(uv.lock)은 별도 형식이지만 requirements.txt와 공존한다.


Poetry.lock에서 uv.lock으로 바로 변환할 수 있나요?

직접 변환 명령은 없다. poetry export -f requirements.txt > requirements.txt로 뽑은 뒤 uv add로 다시 추가하는 방식이 가장 안전하다. 개발 의존성은 uv add --dev로 구분해서 추가한다.


Django·FastAPI 같은 프레임워크와 잘 동작하나요?

동작에는 문제없다. uv run python manage.py runserver처럼 기존 명령 앞에 uv run만 붙이면 된다. FastAPI + uvicorn 조합도 uv add fastapi uvicorn으로 설치 후 uv run uvicorn main:app으로 실행된다.


Docker 이미지에서도 uv를 써야 하나요?

선택 사항이다. 공식 uv Docker 이미지(ghcr.io/astral-sh/uv)를 베이스로 쓰거나 멀티스테이지 빌드로 uv 바이너리만 복사하는 방식이 있다. 이미지 크기보다 빌드 속도를 줄이는 효과가 크다. 다만 Dockerfile을 새로 써야 하므로 팀 합의가 필요하다.


uv로 설치한 패키지를 pip list로 보면 안 보이나요?

가상환경 안에서는 보인다. uv venv로 환경을 만들고 활성화(source .venv/bin/activate)한 뒤 pip list를 실행하면 uv로 설치한 패키지가 그대로 보인다. 가상환경 밖에서 시스템 Python의 pip를 보면 당연히 없다.


uvPython패키지매니저pipPoetrypyenv가상환경GitHub ActionsAstralRust

함께 보면 좋은 문제 해결

EXPLORE / Programming Languages

이어서 읽어보기

전체 토픽 둘러보기