4P by GN⁺ | ★ favorite | 댓글 1개
  • uv는 Rust로 작성된 Python 패키지 및 프로젝트 관리자로, pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv 등을 대체하는 단일 도구를 지향함
  • pip보다 10~100배 빠른 성능을 내며, 기존 워크플로를 크게 바꾸지 않고 uv pip 인터페이스로 속도 향상을 얻을 수 있음
  • 프로젝트 의존성·환경 관리, 범용 lockfile, Cargo 스타일 워크스페이스, 전역 캐시 기반 의존성 중복 제거를 지원함
  • 단일 파일 스크립트의 인라인 의존성 메타데이터, Python 버전 설치·전환, Python 패키지로 배포된 CLI 도구 실행·설치를 제공함
  • macOS, Linux, Windows에서 동작하고, Rust나 Python 없이 curl 또는 pip로 설치 가능하며, standalone 설치 시 uv self update로 자체 업데이트할 수 있음

uv가 해결하려는 범위

  • uv는 Rust로 작성된 Python 패키지 및 프로젝트 관리자
  • 하나의 도구로 여러 Python 생태계 도구를 대체하는 것을 목표로 함
    • pip
    • pip-tools
    • pipx
    • poetry
    • pyenv
    • twine
    • virtualenv
  • BENCHMARKS.md에 따르면 pip보다 10~100배 빠름
  • uv는 Astral이 지원하며, Astral은 Ruffty의 제작자임

주요 기능

  • 프로젝트 관리

    • 의존성과 환경을 관리하고, lockfile과 워크스페이스를 지원함
    • ryepoetry와 비슷한 방식으로 프로젝트를 초기화하고 의존성을 추가하며 실행할 수 있음
    • 범용 lockfile을 제공함
    • Cargo 스타일 워크스페이스를 지원해 확장 가능한 프로젝트 구성을 다룸
  • 스크립트 실행

    • 단일 파일 스크립트의 의존성과 환경을 관리함
    • 인라인 의존성 메타데이터를 지원함
    • uv run example.py처럼 스크립트를 격리된 가상 환경에서 실행할 수 있음
  • 도구 실행 및 설치

    • Python 패키지로 제공되는 CLI 도구를 실행하거나 설치함
    • uvxuv tool run의 별칭이며, 임시 환경에서 도구를 실행함
    • uv tool install ruff처럼 도구를 설치할 수 있음
  • Python 버전 관리

    • Python 버전을 설치하고 빠르게 전환할 수 있음
    • uv python install 3.12 3.13 3.14로 여러 버전을 설치할 수 있음
    • uv python pin 3.11로 현재 디렉터리에 사용할 Python 버전을 고정할 수 있음

pip 호환 인터페이스

  • uv는 pip, pip-tools, virtualenv의 일반적인 명령을 대체하는 호환 인터페이스를 제공함
  • uv pip 인터페이스를 사용하면 기존 워크플로를 바꾸지 않고 pip 대비 10~100배 속도 향상을 경험할 수 있음
  • 확장 기능도 포함함
    • 의존성 버전 override
    • 플랫폼 독립적 해석
    • 재현 가능한 해석
    • 대체 해석 전략
  • 예시 워크플로
    • uv pip compile requirements.in --universal --output-file requirements.txt로 플랫폼 독립적인 requirements 파일을 생성함
    • uv venv로 가상 환경을 생성함
    • uv pip sync requirements.txt로 고정된 requirements를 설치함

설치와 문서

  • standalone installer로 설치 가능함
  • PyPI에서도 설치할 수 있음
    • pip install uv
    • pipx install uv
  • standalone installer로 설치한 경우 uv self update로 최신 버전으로 자체 업데이트할 수 있음
  • 문서는 docs.astral.sh/uv에 있으며, 명령줄 참조는 uv help로 볼 수 있음

구현 기반과 라이선스

  • uv의 의존성 resolver는 내부적으로 PubGrub을 사용함
  • Git 구현은 Cargo를 기반으로 함
  • 일부 최적화는 pnpm, Orogene, Bun의 작업에서 영감을 받음
  • Windows 지원을 위해 Nathaniel J. Smith의 Posy에서 배운 내용과 trampoline을 활용함
  • 라이선스는 Apache License 2.0 또는 MIT license 중 선택할 수 있는 듀얼 라이선스

댓글과 토론

Hacker News 의견들
  • 몇 달 전만 해도 uv는 절대 안 쓸 거라고 했고, 이미 venvpip에 익숙해서 새 도구가 필요 없다고 생각했음
    지금은 Python 작업 전부에 uv를 씀. 전환 계기는 루트 권한이 없는 공유 서버였고, 깨진 패키지와 드라이버가 많았으며 pytorch가 필요했는데 아무것도 제대로 안 됐음. pip는 너무 오래 걸렸고, 사용자별 저장공간 10GB에서 pip 캐시가 너무 많이 차지했으며 위치 변경도 잘 안 됐음. uv로 바꾸자 그냥 다 동작함
    아직 버티는 중이라면 정말 5분만 써보면 후회하지 않을 것 같음

    • 내게 핵심은 uv가 설명하기도, 쓰기도 훨씬 쉽다는 점이었음. 특히 매일 Python을 다루지는 않고 가끔 스크립트만 짜는 사람들에게 좋음
      pip + 설정 파일 + venv 조합은 올바른 가상환경을 쓰려면 대략 두 단계를 기억해야 함. 만들고, 그 안에 설치해야 하며, 테스트 실행이나 스크립트 실행 때마다 이상한 해시뱅 형식을 기억하거나 가상환경을 활성화해야 함. 오류 메시지도 별 도움이 안 되는데, 이 구성이 표준화되거나 공식적으로 축복받은 방식이 아니라서 그럴 수밖에 없다고 봄. 결국 ImportErrorvenv의 연결을 머릿속에 억지로 새겨야 함
      쓸 수는 있지만, 익숙하지 않은 사람들에게 가르쳐 보니 전체 도구 체인이 얼마나 뒤엉켜 있는지 다시 느꼈음
      이제 팀원들은 uv run, uv add, uv sync만 기억하면 되고, 훨씬 쉽고 덜 위압적으로 느껴짐
    • 내게 uv의 결정적 기능은 기존 venv 기반 작업 흐름과 여전히 호환된다는 점임. 그냥 uv venv를 실행하면 됨
    • 한동안 ASDF를 쓰다가 mise로 옮겼는데, 더 범용적인 최신 도구인 mise와는 어떻게 비교되는지 궁금함
    • uv로 못 넘어가게 만든 건 Ruff 경험임. Ruff는 “Flake8, isort, Black과 완전 대체 가능”하다고 하지만 사실이 아니었음
      적어도 isort의 경우 Ruff는 원하는 부분만 다시 구현했고, 빠진 기능이나 설정이 있으면 예전 isort 도구를 Ruff에서 호출하라고 함. 그럴 거면 의미가 뭔지 모르겠음. Ruff는 여러 기존 도구를 부분적으로 다시 구현하고 새 기능을 더한 셈이라, 실제로는 써야 하는 도구 수가 또 늘어나며 Pylint가 하는 일도 전부 하지는 못함
      uv로 옮기는 데 대해서도 “빠르다” 말고 Poetry 대비 장점을 설득력 있게 듣지 못했음. 지금 아는 고유한 장점은 uv가 Python 자체를 설치할 수 있어서 Pyenv 같은 도구를 없앨 수 있다는 정도임. 그 점은 흥미롭지만, “빠르다”만으로는 충분한 이유가 아님
    • pip 캐시가 저장공간을 많이 먹고 위치도 제대로 못 바꿨는데 uv로 해결됐다는 부분이 궁금함. 저장공간 사용량이 더 나은가? 그렇다면 공유 가능한 것을 잘 공유해서 그런 건가?
  • uv를 처음 썼을 때는 뭔가 실수했거나 잘못 입력했다고 확신했음. pip로 겪어본 어떤 작업보다 훨씬 빨리 끝났기 때문임

    • 가끔 uv가 패키지 설치에 최대 200ms나 걸려서, 엔터를 누른 뒤 다음 셸 프롬프트가 뜨기까지 약간의 지연이 느껴질 때가 있음
      Poetry에는 그런 문제가 없음. 커피 한 잔 만들러 몇 분 다녀오면 보통 끝나 있음
    • 나도 같았음. 너무 매끄러워서 Python 같지 않음
    • 지난주에 똑같이 겪었고, 제대로 동작하지 않는다고 확신했음. 이제는 전향했음
  • uvruff는 “바퀴를 재발명하지 말라”는 사람들에게 좋은 반례임. 단지 새로 만들기 위해서 하면 안 되지만, 명확한 목표가 있으면 가끔 한 자릿수 차이로 더 나은 제품을 만들 수 있음

    • 그 표현은 대개 현재 시스템이 어떻게 동작하는지, 단점이 무엇인지, 어떻게 개선할지 모르는 미숙한 장인에게 하는 말이라고 봄. 골드바흐 추측을 풀려는 학부생 같은 경우임
      보통은 바퀴 재발명에 실패하거나, 가치가 없는 똑같은 바퀴를 다시 만드는 데서 끝남. 이 표현은 전문가에게는 확실히 맞지 않음
    • 바퀴를 재발명했다기보다는, 나무를 더 튼튼한 재료로 바꿔 10배 속도 회전을 견디게 만든 것에 가까움
    • Python 패키지 관리 역사를 보면, 모두가 현상보다 자신이 더 잘할 수 있다고 생각한다는 점이 분명함
    • “바퀴를 재발명하지 말라”는 말은 솔직히 전혀 말이 안 됨. 우리는 아직도 나무 원반을 바퀴로 쓰지 않고, 신석기 이후 훨씬 나은 바퀴를 발명해 왔음. 소프트웨어라고 그렇게 하지 말 이유가 없음
    • Ruff는 사실 재작성의 위험을 보여주는 좋은 예임. 도구를 다시 만들었지만 그 도구들의 모든 부분을 다시 만든 건 아님
  • 다른 사람들도 만날 수 있어 경고하자면, 매우 빈약한 시스템에서는 uv가 동시에 너무 많은 다운로드를 열어 과부하를 일으키고 시간 초과가 날 수 있음. 예를 들면 Windows에서 돌아가는 AWS T2.micro 같은 경우임
    UV_CONCURRENT_DOWNLOADS 환경 변수로 제한할 수 있음. 내 경우에는 1이나 2로 둬야 했고, 그 이상은 시간 초과가 났음
    극단적인 경우인 건 알지만, uv가 여기서는 너무 공격적이라고 봄. 모듈마다 다운로드 스레드를 여는 대신, 각 원본 서버의 총 전송 속도를 보고 서버별 스레드 수를 자동 조정해야 함

    • 전혀 극단적이지 않음. 취미 작업에는 가장 싸고 작은 VPS를 쓰는 사람이 많고, 나도 AWS는 아니지만 그렇게 씀. 공유해줘서 고맙고, 자동 감지가 개선되면 좋겠음
    • uv는 큰 프로젝트에서 꽤 성능 좋은 Linux 데스크톱도 파일 디스크립터를 다 써버리게 만들 수 있음. 결정적이고 재현 가능한 설치도 아직 안 됨. 더 성숙해질 필요가 있음
  • uv add --script mycoolscript.py가 정말 마음에 듦
    그리고 위에 #!/usr/bin/env -S uv run을 붙이면 Python 스크립트를 쉽게 실행할 수 있어서 좋음

    • 이 방법만 가르치는 특별 지침을 넣은 Claude Project를 만들었고, 그러면 한 번의 프롬프트로 인라인 의존성이 포함된 완전한 스크립트를 출력해 줌: https://simonwillison.net/2024/Dec/19/one-shot-python-tools/
      다만 Claude 4의 학습 기준일은 2025년 3월이고, 방금 확인해 보니 Claude Sonnet 4는 추가 지침 없이도 이걸 할 수 있었음
      uv와 인라인 스크립트 의존성을 쓰는 Python 스크립트를 만들고, URL을 주면 httpxbeautifulsoup으로 긁어서 페이지의 모든 링크 URL과 링크 텍스트를 CSV로 반환하게 했음
      출력은 여기 있고, 의존성 처리도 제대로 했음: https://claude.ai/share/57d5c886-d5d3-4a9b-901f-27a3667a8581
    • 이 트릭을 Marimo.io 노트북의 앱 모드에서 쓰고 있음
      최소 전제조건으로 uv만 설치하면 다른 사람에게 보낼 수 있는, 즉시 반응형이고 재현 가능한 앱이 됨. 정말 강력한 조합임
    • 정말 멋짐. 이제 작은 스크립트를 습관처럼 바이브 코딩해서 바로 실행함. 환경과 의존성을 관리해야 하는 것보다 훨씬 낫다
      https://everything.intellectronica.net/p/the-little-scripter
      https://www.youtube.com/watch?v=8LB7e2tKWoI
      https://github.com/intellectronica/ez-mcp
    • 예시를 잘못 읽었음. 아래는 프로젝트 문맥의 uv adduv add --script를 잘못 패턴 매칭한 관련 없는 내용이라 무시해도 됨
      ~~그건 현재 작업 디렉터리의 프로젝트/환경을 변경함. 문서에 많이 나와 있지만, run --withuv의 PEP723 지원이 더 마음에 들 것 같음~~
      https://docs.astral.sh/uv/guides/scripts/
    • mydependencies가 뭐임? 설정 파일인가?
  • 최근 개인용으로 노트북에서 쓰기 시작했음. pip에 익숙하다면 혼란스러울 정도로 빠름. 너무 빨리 돌아와서 제대로 안 된 줄 생각한 적이 여러 번 있음

  • 예전에 uv를 써봤는데, 얼마나 빠르고 쓰기 쉬운지 충격받았음. 이제 사실상 pip를 쓸 이유가 없고, Python만 쓴다면 conda를 쓸 이유도 거의 없음

    • pyenvpoetry도 버릴 수 있게 해주는 것 같음
  • UV가 정말 좋음
    Astral 팀의 Ruff도 좋음. 우리는 린트와 포맷팅을 pylint + Black에서 Ruff로 막 전환했음
    린트 시간이 90초에서 1.5초 미만으로 줄었고, 미친 수준임

    • Ruff가 pylint 검사의 일부만 수행한다는 걸 깨닫는 순간이 올 것임. 명백한 오류 때문에 실행조차 안 되는 코드 같은 아주 뻔한 실수도 쉽게 통과할 수 있음
  • uv를 Docker와 함께 쓰는 예시를 찾는다면 Flask와 Django 예제 앱을 만들어 두었음: https://github.com/nickjj/docker-flask-examplehttps://github.com/nickjj/docker-django-example
    uv가 가상환경을 만들지 못하게 하고, 의존성 설치 시 바이트코드를 한 번 컴파일하는 식의 최적화도 함
    전환할 가치가 충분했음. pip 대비 설치 속도가 약 10배 개선됐고, 전체 의존성 설치가 30초에서 3초로 줄었음. 제대로 된 잠금 파일 지원도 좋음. 우연히도 약 일주일 전에 Docker화된 Flask/Django 앱을 uv로 바꾸는 글과 영상을 만들었음: https://nickjanetakis.com/blog/switching-pip-to-uv-in-a-dock...

  • 작은 실행 스크립트를 돌릴 때 이게 요즘 최애 방식임
    #!/usr/bin/env -S uv --quiet run --script
    # /// script
    # requires-python = ">=3.13"
    # dependencies = [
    # "python-dateutil",
    # ]
    # ///
    #
    # [dateutil이 필요한 Python 스크립트]

    • 해시뱅 줄이 #!/usr/bin/env uvx처럼 훨씬, 훨씬 더 외우기 쉬웠으면 좋겠음. 이걸 쓸 때마다 매번 찾아봐야 함