AICosmus

Where tech meets the everyday — AI, fintech, swimming, and cars.
Python 도구를 하나로 통합하는 uv 일러스트

uv 사용법 총정리 — pip 대체 Python 초고속 패키지 매니저

Python으로 프로젝트를 시작하려고 앉으면, 코드를 작성하기도 전에 넘어야 할 산이 있습니다. pip로 패키지를 설치하고, virtualenv나 venv로 가상환경을 만들고, 여러 Python 버전이 필요하면 pyenv까지 따로 깔아야 합니다. poetry를 쓸지 pipenv를 쓸지 고민하다 보면 정작 코드는 한 줄도 못 쓴 채 저녁이 됩니다. 이 도구의 파편화는 Python 생태계의 오래된 아픈 손가락이었습니다.

2024년 초, Ruff(초고속 Python 린터)를 만든 Astral이라는 팀이 이 문제에 정면으로 도전장을 내밀었습니다. 그 결과물이 바로 uv입니다. Rust로 작성된 uv는 pip, pip-tools, virtualenv, pyenv, pipx, poetry를 단 하나의 바이너리로 대체하며, 기존 도구 대비 10~100배 빠른 속도를 보여줍니다. 2026년 현재 GitHub 스타 6만 개를 돌파하며 Python 생태계의 사실상 표준 패키지 매니저로 자리잡아 가고 있습니다.

이 글에서는 uv가 무엇인지, 어떻게 설치하고, 실전에서 어떻게 활용하는지를 처음부터 끝까지 다룹니다. 기존에 pip만 써왔던 분도, poetry나 pipenv에 익숙한 분도, 이 글을 따라 하면 30분 안에 uv로 전환할 수 있습니다.

uv란 무엇인가 — 하나로 끝내는 Python 도구 체인

uv를 한 문장으로 정의하면 “Python 개발에 필요한 거의 모든 도구를 하나로 통합한 초고속 패키지 매니저”입니다. Astral이라는 회사가 Rust 언어로 처음부터 새로 만들었으며, 기존 Python 도구들이 각각 독립적으로 해결하던 문제를 하나의 CLI에서 전부 처리합니다.

uv가 대체하는 기존 도구들

uv 하나면 아래 도구들을 더 이상 따로 설치할 필요가 없습니다.

  • pip + pip-toolsuv pip install, uv pip compile로 호환 인터페이스 제공
  • virtualenv / venvuv venv로 가상환경 생성 (수백 밀리초 내 완료)
  • pyenvuv python install 3.12로 Python 버전 자체를 설치·관리
  • pipxuvx ruff처럼 CLI 도구를 격리된 환경에서 즉시 실행
  • poetry / pipenvuv init, uv add, uv lock으로 프로젝트 의존성 관리

특히 기존에 “pip로 설치하고 → virtualenv로 격리하고 → pyenv로 버전 바꾸고 → pip-tools로 잠그고”라는 4단계를 거치던 작업이, uv에서는 uv inituv adduv run 세 명령어로 끝납니다.

왜 이렇게 빠른가

uv의 가장 눈에 띄는 특징은 압도적인 속도입니다. pip이 30초 걸리는 의존성 해석을 uv는 1초 안에 끝냅니다. 비결은 세 가지입니다.

  • Rust 네이티브 구현: Python이 아닌 Rust로 작성되어 패키지 메타데이터 파싱, 의존성 해석, 파일 I/O 전 과정이 컴파일된 네이티브 코드로 동작합니다.
  • 전역 캐시: 한 번 다운로드한 패키지는 전역 캐시에 저장되어 다른 프로젝트에서 재사용합니다. 같은 버전의 numpy를 열 개 프로젝트에서 쓰더라도 디스크에는 한 벌만 존재합니다.
  • 병렬 다운로드: 여러 패키지를 동시에 다운로드하고 설치합니다. pip의 순차 처리와 대비됩니다.
pip과 uv 설치 속도 비교 차트

실제 벤치마크에서 uv는 pip 대비 8~25배, 워밍 캐시(이미 다운로드된 상태) 기준으로는 80~115배 빠른 결과를 보여줍니다. 대규모 프로젝트의 requirements.txt에 패키지가 수십 개 들어 있는 경우, pip으로 2~3분 걸리던 설치가 uv로는 수 초 만에 끝나는 체감 차이가 큽니다.

설치 — 3분이면 끝나는 초간단 세팅

uv는 단일 바이너리로 배포되어 설치가 극도로 간단합니다. Python이 아직 설치되지 않은 깨끗한 시스템에서도 uv 먼저 설치한 뒤, uv를 통해 Python까지 설치할 수 있습니다.

Windows (PowerShell)

PowerShell을 열고 아래 명령어를 입력합니다.

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

설치가 끝나면 터미널을 재시작한 뒤 uv --version으로 확인합니다. Windows 패키지 매니저를 선호한다면 winget install astral-sh.uv 또는 scoop install uv로도 설치할 수 있습니다.

macOS / Linux

curl -LsSf https://astral.sh/uv/install.sh | sh

Homebrew 사용자라면 brew install uv도 가능합니다.

pip으로 설치 (기존 Python 환경이 있는 경우)

pip install uv

다만 이 방법은 uv의 장점(Python 없이도 동작)을 활용하지 못하므로, 가능하면 공식 설치 스크립트를 권장합니다.

설치 확인

uv --version
# uv 0.7.x

버전 번호가 출력되면 준비 완료입니다. uv는 자동 업데이트 명령어도 내장하고 있어, uv self update 한 줄로 최신 버전으로 올릴 수 있습니다.

프로젝트 시작부터 실행까지 — 핵심 워크플로우

uv의 진가는 프로젝트 관리 워크플로우에서 드러납니다. 새 프로젝트를 시작하고, 패키지를 추가하고, 코드를 실행하는 전 과정을 살펴보겠습니다.

uv init에서 run까지 프로젝트 워크플로우

1단계: 프로젝트 초기화

mkdir my-project
cd my-project
uv init

이 명령 하나로 다음 파일들이 자동 생성됩니다.

  • pyproject.toml — 프로젝트 메타데이터와 의존성 정의 (PEP 621 표준)
  • .python-version — 프로젝트가 사용하는 Python 버전
  • hello.py — 샘플 스크립트
  • README.md — 기본 문서

생성된 pyproject.toml을 열어보면 이런 형태입니다.

[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = []

poetry의 pyproject.toml과 비슷하지만, uv는 PEP 621 표준을 따르므로 특정 도구에 종속되지 않습니다.

2단계: 패키지 추가

uv add requests
uv add pandas numpy

이 명령은 세 가지 일을 동시에 처리합니다.

  • pyproject.tomldependencies에 패키지를 추가합니다.
  • 의존성 트리를 해석하고 uv.lock 잠금 파일을 생성합니다.
  • 가상환경(.venv)을 자동 생성하고 패키지를 설치합니다.

개발용 의존성(테스트, 린터 등)은 --dev 플래그로 분리합니다.

uv add --dev pytest ruff mypy

이렇게 추가된 개발 의존성은 pyproject.toml[tool.uv.dev-dependencies] 섹션에 기록되어, 배포 시에는 포함되지 않습니다.

3단계: 코드 실행

uv run python hello.py

uv run가상환경을 자동으로 활성화한 상태에서 명령어를 실행합니다. 더 이상 source .venv/bin/activate(Linux/Mac)나 .venv\Scripts\activate(Windows)를 손으로 칠 필요가 없습니다.

# pytest 실행도 uv run으로
uv run pytest

# 특정 모듈 실행
uv run python -m my_project.main

이 세 단계가 uv의 기본 워크플로우입니다. init → add → run. 가상환경 생성, Python 버전 확인, 의존성 잠금까지 모두 uv가 뒤에서 알아서 처리합니다.

패키지 제거와 동기화

# 패키지 제거
uv remove pandas

# 잠금 파일 기준으로 환경 동기화 (CI/CD에서 유용)
uv sync

uv syncuv.lock 파일을 기준으로 현재 환경을 정확하게 맞춥니다. 팀원이 git pulluv sync 한 번이면 동일한 환경이 재현됩니다.

Python 버전 관리 — pyenv 없이도 되는 이유

기존에는 여러 Python 버전을 관리하려면 pyenv(Linux/Mac)나 py 런처(Windows)가 필요했습니다. uv는 이 기능까지 내장하고 있어, 별도 도구 없이 Python 자체를 설치하고 전환할 수 있습니다.

Python 설치

# 특정 버전 설치
uv python install 3.12
uv python install 3.11

# 설치된 버전 확인
uv python list

uv는 python-build-standalone 프로젝트의 사전 빌드된 바이너리를 다운로드합니다. 소스 컴파일이 아니라 이미 빌드된 바이너리를 받는 것이므로 Windows에서도 수 초 안에 설치가 끝납니다.

프로젝트별 Python 버전 고정

# 현재 프로젝트의 Python 버전을 3.12로 고정
uv python pin 3.12

이 명령은 .python-version 파일에 버전을 기록합니다. 이후 uv run을 실행하면 자동으로 해당 버전의 Python을 사용합니다. 해당 버전이 아직 설치되지 않았다면 uv가 자동으로 다운로드까지 해줍니다.

프로젝트 A는 Python 3.11, 프로젝트 B는 3.12를 쓴다면 각 디렉토리의 .python-version만 다르게 설정하면 됩니다. pyenv의 .python-version 파일과 형식이 호환되므로, 기존 pyenv 사용자는 그대로 전환할 수 있습니다.

시스템에 Python이 전혀 없는 경우

이것이 uv의 가장 매력적인 시나리오 중 하나입니다. 새 컴퓨터에 Python이 설치되어 있지 않아도, uv만 설치하면 됩니다.

# uv 설치 (Python 불필요)
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

# uv를 통해 Python 설치
uv python install 3.12

# 바로 프로젝트 시작
uv init my-app
cd my-app
uv add fastapi
uv run python -m my_app

이전이라면 python.org에서 설치 파일을 내려받고, PATH를 설정하고, pip를 업그레이드하고, virtualenv를 설치하는 번거로운 과정을 거쳐야 했습니다. uv는 이 모든 과정을 없앱니다.

스크립트 실행과 도구 관리 — uvx의 위력

uv에는 프로젝트 관리 외에도 두 가지 강력한 기능이 있습니다. 단일 스크립트의 인라인 의존성 관리와, CLI 도구의 격리 실행입니다.

인라인 의존성이 있는 스크립트 실행

Python 파일 하나짜리 간단한 스크립트를 공유할 때, “이 스크립트를 실행하려면 requests와 beautifulsoup4를 먼저 설치하세요”라고 안내하는 것은 번거롭습니다. uv는 PEP 723(인라인 스크립트 메타데이터)을 지원하여, 스크립트 파일 안에 의존성을 직접 명시할 수 있습니다.

# /// script
# requires-python = ">=3.12"
# dependencies = [
#     "requests",
#     "beautifulsoup4",
# ]
# ///

import requests
from bs4 import BeautifulSoup

response = requests.get("https://example.com")
soup = BeautifulSoup(response.text, "html.parser")
print(soup.title.string)

이 스크립트를 uv run scrape.py로 실행하면, uv가 자동으로 임시 환경을 만들고 의존성을 설치한 뒤 스크립트를 돌립니다. 한 번 캐시된 의존성은 다음 실행부터 즉시 사용됩니다. 스크립트를 받은 사람도 uv run scrape.py 한 줄이면 모든 준비가 끝납니다.

uvx — CLI 도구를 설치 없이 즉시 실행

uvx는 pipx의 uv 버전입니다. Python으로 만들어진 CLI 도구를 격리된 임시 환경에서 즉시 실행합니다. 글로벌 환경을 오염시키지 않으면서 필요한 도구를 바로 사용할 수 있습니다.

# Ruff로 코드 검사 (설치 불필요)
uvx ruff check .

# Black으로 코드 포맷팅
uvx black my_script.py

# Jupyter 노트북 실행
uvx jupyter lab

# HTTP 서버 띄우기
uvx http-server

# 특정 버전 실행
uvx [email protected] check .

pipx와의 차이는 속도입니다. pipx는 도구를 처음 실행할 때 가상환경을 만들고 설치하는 데 수 초에서 수십 초가 걸리지만, uvx는 캐시가 있으면 거의 즉시, 없어도 1~2초 안에 실행됩니다.

uv 핵심 명령어 카테고리별 정리

자주 쓰는 도구는 uv tool install로 영구 설치할 수도 있습니다.

# 영구 설치 (PATH에 자동 등록)
uv tool install ruff
uv tool install mypy

# 설치된 도구 목록
uv tool list

# 업그레이드
uv tool upgrade ruff

pip 호환 인터페이스 — 기존 습관 그대로

uv가 아무리 좋아도, 기존 프로젝트가 requirements.txt로 관리되고 있다면 당장 전환이 부담스러울 수 있습니다. uv는 이를 위해 pip 호환 인터페이스를 제공합니다. 기존 pip 명령어 앞에 uv만 붙이면 됩니다.

# pip install과 동일
uv pip install requests
uv pip install -r requirements.txt

# pip freeze와 동일
uv pip freeze

# pip uninstall과 동일
uv pip uninstall requests

# pip-tools의 pip-compile과 동일
uv pip compile requirements.in -o requirements.txt

이 방식은 기존 프로젝트의 requirements.txt를 그대로 유지하면서도 uv의 속도 이점을 누릴 수 있어, 점진적 전환에 적합합니다. CI/CD 파이프라인에서 pip install -r requirements.txtuv pip install -r requirements.txt로 바꾸는 것만으로도 설치 시간이 10분의 1로 줄어드는 경우가 많습니다.

기존 프로젝트를 uv로 이전하기

이미 운영 중인 프로젝트를 uv로 옮기는 것은 생각보다 간단합니다. 상황별 이전 방법을 정리했습니다.

pip + requirements.txt에서 이전

가장 흔한 경우입니다. 단계별로 진행합니다.

# 1. 프로젝트 루트에서 uv 초기화
uv init --no-readme

# 2. 기존 requirements.txt의 패키지를 uv에 추가
uv add $(cat requirements.txt | grep -v '^#' | grep -v '^$' | tr '\n' ' ')

# 또는 Windows PowerShell에서
uv add (Get-Content requirements.txt | Where-Object { $_ -and $_ -notmatch '^#' })

# 3. 정상 동작 확인
uv run python -c "import requests; print('OK')"

이후 requirements.txtpyproject.tomluv.lock으로 대체됩니다. 팀원들에게 uv sync를 사용하도록 안내하면 됩니다.

pip·poetry·pipenv에서 uv로 이전 경로

poetry에서 이전

poetry의 pyproject.toml[tool.poetry.dependencies] 섹션을 사용하지만, uv는 PEP 621 표준인 [project].dependencies를 사용합니다. 다행히 uv는 poetry 형식의 pyproject.toml을 자동으로 인식합니다.

# poetry 프로젝트 디렉토리에서
uv sync

이 한 줄로 uv가 기존 pyproject.toml의 의존성을 읽고, uv.lock을 생성하고, 가상환경을 세팅합니다. 이후 [tool.poetry.*] 섹션을 [project] 표준 형식으로 수동 변환하면 poetry에 대한 의존이 완전히 사라집니다.

pipenv에서 이전

# Pipfile.lock에서 requirements.txt 추출
pipenv requirements > requirements.txt

# uv로 이전
uv init --no-readme
uv add -r requirements.txt

# Pipfile과 Pipfile.lock 제거
rm Pipfile Pipfile.lock

이전 시 체크리스트

  • Python 버전 확인: uv python pin으로 프로젝트의 Python 버전을 명시합니다.
  • .gitignore 업데이트: .venv/가 이미 있으면 OK. uv 관련 추가 항목은 불필요합니다.
  • CI/CD 파이프라인 수정: pip installuv sync 또는 uv pip install로 교체합니다.
  • uv.lock을 버전 관리에 포함: uv.lock은 커밋합니다. 팀 전원이 동일한 의존성 버전을 사용하게 됩니다.
  • 기존 도구 제거: 전환이 안정되면 pyenv, virtualenv, pipx 등 불필요해진 도구를 정리합니다.

실전 팁 — 더 똑똑하게 uv 사용하기

Docker에서 uv 활용

컨테이너 빌드에서 uv의 속도 이점은 더 극적입니다. 매번 docker build를 돌릴 때마다 의존성 설치 단계가 수십 초에서 수 초로 줄어듭니다.

FROM python:3.12-slim

# uv 설치
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

# 의존성 파일만 먼저 복사 (Docker 레이어 캐시 활용)
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev

# 소스 코드 복사
COPY . .

CMD ["uv", "run", "python", "-m", "my_app"]

--frozen 플래그는 잠금 파일을 재생성하지 않고 그대로 사용하라는 의미입니다. CI/CD 환경에서는 uv.lock이 최신인지 검증하는 --locked 플래그도 유용합니다.

GitHub Actions에서 uv 캐시 활용

- name: Install uv
  uses: astral-sh/setup-uv@v5
  with:
    enable-cache: true

- name: Install dependencies
  run: uv sync --frozen

- name: Run tests
  run: uv run pytest

Astral이 공식 제공하는 setup-uv 액션을 사용하면 uv 설치와 캐시 설정이 한 번에 됩니다. 캐시 히트 시 의존성 설치가 거의 0초에 가까워지므로, CI 전체 실행 시간이 대폭 단축됩니다.

캐시 관리

uv는 글로벌 캐시를 사용하여 같은 패키지를 여러 프로젝트에서 공유합니다. 캐시 위치와 관리 명령어는 다음과 같습니다.

# 캐시 위치 확인
uv cache dir

# 캐시 사용량 확인
uv cache info

# 캐시 전체 삭제 (디스크 공간 확보)
uv cache clean

# 특정 패키지 캐시만 삭제
uv cache clean numpy

캐시 디렉토리는 Windows에서 %LOCALAPPDATA%\uv\cache, macOS에서 ~/Library/Caches/uv, Linux에서 ~/.cache/uv에 위치합니다. 프로젝트가 많다면 수 기가바이트까지 커질 수 있으므로, 디스크가 부족할 때 uv cache clean으로 정리하면 됩니다.

환경변수로 동작 커스터마이징

uv의 동작을 세밀하게 제어하는 주요 환경변수입니다.

  • UV_CACHE_DIR: 캐시 디렉토리 변경 (예: 외장 SSD로 이동)
  • UV_PYTHON_PREFERENCE: Python 탐색 순서 제어 (system, managed-only 등)
  • UV_LINK_MODE: 패키지 설치 방식 (hardlink, copy, symlink). 기본값은 하드링크로 디스크를 절약합니다.
  • UV_NO_PROGRESS: 진행률 표시 비활성화 (CI 로그 정리에 유용)

알아두면 좋은 주의사항

  • 시스템 패키지와의 관계: uv pip install은 기본적으로 가상환경에만 패키지를 설치합니다. 시스템 Python에 설치하려면 --system 플래그가 필요합니다.
  • 잠금 파일 형식: uv.lock은 uv 전용 형식입니다. pip이나 poetry가 직접 읽지는 못하지만, uv export --format requirements-txt로 변환할 수 있습니다.
  • C 확장 패키지: numpy, pandas 같은 C 확장 패키지도 정상적으로 설치됩니다. uv는 pip과 동일한 패키지 소스(PyPI)를 사용하므로 호환성 문제는 거의 없습니다.
  • 사설 레지스트리: 사내 PyPI 미러나 사설 패키지 서버를 사용하는 경우 uv pip install --index-url 또는 pyproject.toml[[tool.uv.index]]로 설정할 수 있습니다.

자주 쓰는 uv 명령어 치트시트

일상적으로 가장 많이 쓰는 명령어를 한눈에 정리했습니다.

프로젝트 관리

  • uv init — 새 프로젝트 초기화
  • uv add <패키지> — 의존성 추가
  • uv add --dev <패키지> — 개발 의존성 추가
  • uv remove <패키지> — 의존성 제거
  • uv sync — 잠금 파일 기준 환경 동기화
  • uv lock — 잠금 파일만 갱신 (설치 없이)
  • uv run <명령어> — 가상환경 내에서 명령어 실행
  • uv tree — 의존성 트리 시각화

Python 버전 관리

  • uv python install <버전> — Python 설치
  • uv python list — 설치된 버전 목록
  • uv python pin <버전> — 프로젝트 Python 버전 고정
  • uv python uninstall <버전> — Python 삭제

도구 관리

  • uvx <도구> — 도구를 임시 환경에서 실행
  • uv tool install <도구> — 도구 영구 설치
  • uv tool list — 설치된 도구 목록
  • uv tool upgrade <도구> — 도구 업그레이드

pip 호환

  • uv pip install <패키지> — pip install 대체
  • uv pip install -r requirements.txt — 파일 기반 설치
  • uv pip freeze — 설치된 패키지 목록
  • uv pip compile requirements.in — 의존성 잠금

유틸리티

  • uv self update — uv 자체 업데이트
  • uv cache info — 캐시 정보 확인
  • uv cache clean — 캐시 삭제
  • uv export --format requirements-txt — requirements.txt 형식으로 내보내기

마무리 — 2026년, Python 개발 환경의 새로운 기본값

Python은 배우기 쉬운 언어로 유명하지만, 정작 개발 환경을 세팅하는 과정은 초보자에게 가장 큰 진입 장벽이었습니다. pip, virtualenv, pyenv, poetry, pipenv… 어떤 도구를 어떤 조합으로 써야 하는지 결정하는 것만으로 에너지를 다 쓰곤 했습니다.

uv는 이 파편화를 끝냅니다. 하나의 도구로 Python 설치부터 패키지 관리, 가상환경, 스크립트 실행까지 전부 해결합니다. 속도는 기존 도구와 비교가 안 될 만큼 빠르고, pip 호환 인터페이스 덕분에 기존 프로젝트도 점진적으로 이전할 수 있습니다.

시작은 간단합니다. 오늘 당장 uv를 설치하고, 다음 프로젝트부터 uv init으로 시작해 보세요. 설치에 3분, 첫 프로젝트 세팅에 1분이면 충분합니다. 한 번 써보면 pip으로 돌아가기 어려울 겁니다.

이미지는 Leonardo AI 로 생성되었습니다.

이미지는 Claude AI 로 생성되었습니다.

답글 남기기

Your email address will not be published. Required fields are marked *.

Warning: Undefined array key "cookies" in /var/www/html/wp-content/themes/personal-cv-resume/class/class-post-related.php on line 212
*
*

최신 댓글