<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Uv on KbWen Blog</title>
    <link>https://www.kbwen.com/tags/uv/</link>
    <description>KbWen 的個人技術部落格，分享 Python、機器學習、深度學習、資料工程與 AI 開發的學習筆記與實作心得。</description>
    <generator>Hugo</generator>
    <language>zh-tw</language>
    <image>
      <url>https://www.kbwen.com/images/og-default.png</url>
      <title>KbWen Blog</title>
      <link>https://www.kbwen.com/</link>
    </image>
    
    <lastBuildDate>Sun, 28 Jun 2026 10:00:00 +0800</lastBuildDate><atom:link href="https://www.kbwen.com/tags/uv/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>uv: the Python tool that replaces pip, venv, and pyenv</title>
      <link>https://www.kbwen.com/uv-replaces-pip-venv-pyenv/</link>
      <pubDate>Sun, 28 Jun 2026 10:00:00 +0800</pubDate><dc:creator>KbWen</dc:creator>
      <guid>https://www.kbwen.com/uv-replaces-pip-venv-pyenv/</guid>
      <description>uv is Astral&amp;#39;s Rust-written Python tool that folds pip, venv, pyenv, and pipx into one command — and installs packages several times faster. What it replaces, how fast it really is, and whether you should switch.</description>
      <content:encoded><![CDATA[<blockquote>
<p><strong>TL;DR:</strong> <code>uv</code> is Astral&rsquo;s Rust-written Python tool (same team as Ruff) that folds <code>pip</code>, <code>venv</code>, <code>pyenv</code>, and <code>pipx</code> into one command. <code>uv add</code> installs, <code>uv run</code> runs, <code>uv python install</code> manages versions, and it creates the <code>.venv</code> for you on first use. Installs land roughly 8–10x faster than pip on a cold cache, and near-instant on a warm one. It&rsquo;s command-compatible with your existing <code>requirements.txt</code>, so trying it on one project costs almost nothing.</p>
</blockquote>
<p>Spinning up a new Python project means keeping a small pile of tools in your head. <code>venv</code> for the environment, <code>pip</code> for packages, <code>requirements.txt</code> for dependencies, <code>pyenv</code> if you care about the interpreter version, <code>pipx</code> for installing a CLI globally, and <code>poetry</code> or <code>pip-tools</code> once you want real lockfiles. Each one is fine on its own. Together they&rsquo;re a mental lookup table you re-run every time you start: which job goes to which tool.</p>
<p><code>uv</code> is the thing that cleared that table for me. One command took over almost the whole row.</p>
<h2 id="what-it-actually-replaces">What it actually replaces</h2>
<p>Here&rsquo;s the rough translation, old habit on the left, the uv version on the right:</p>
<table>
  <thead>
      <tr>
          <th>Used to be</th>
          <th>With uv</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>python -m venv .venv</code> then source it</td>
          <td>nothing to do — uv creates <code>.venv</code> on first run</td>
      </tr>
      <tr>
          <td><code>pip install requests</code></td>
          <td><code>uv add requests</code></td>
      </tr>
      <tr>
          <td><code>pip install -r requirements.txt</code></td>
          <td><code>uv pip install -r requirements.txt</code> (compatible)</td>
      </tr>
      <tr>
          <td><code>python script.py</code></td>
          <td><code>uv run script.py</code> (runs in the right env automatically)</td>
      </tr>
      <tr>
          <td><code>pyenv install 3.12</code></td>
          <td><code>uv python install 3.12</code></td>
      </tr>
      <tr>
          <td><code>pipx run black</code></td>
          <td><code>uvx black</code></td>
      </tr>
      <tr>
          <td><code>poetry</code> lockfiles and publishing</td>
          <td><code>uv</code> (<code>pyproject.toml</code> + <code>uv.lock</code>)</td>
      </tr>
  </tbody>
</table>
<p>A few of these are worth slowing down on. The first time <code>uv add</code> runs in a folder, it builds the virtual environment and writes the dependency into <code>pyproject.toml</code> for you. There&rsquo;s no <code>activate</code> step to remember, because <code>uv run</code> finds the environment and runs inside it. <code>uvx</code> is shorthand for <code>uv tool run</code>: it spins up a throwaway environment, runs a CLI tool, and tears it down. That&rsquo;s exactly <code>pipx</code>&rsquo;s job. Version management is built in too. <code>uv python install 3.12</code> fetches an interpreter directly, so <code>pyenv</code> drops out of the picture.</p>
<p>One detail matters more than it sounds: uv is a single binary, and installing it doesn&rsquo;t need an existing Python. That kills the chicken-and-egg problem <code>pyenv</code> always had: you needed a Python to manage your Pythons.</p>
<h2 id="how-much-faster-really">How much faster, really</h2>
<p>Speed is uv&rsquo;s loudest selling point, and it&rsquo;s the Rust kind of fast. Downloads run in parallel; fetching metadata, resolving dependencies, and writing to disk overlap instead of queuing. <code>pip</code> downloads sequentially by default and leans on multiple processes to get around Python&rsquo;s GIL, which adds overhead. The gap shows up fast.</p>
<p>Some concrete numbers. Installing something like JupyterLab, <code>pip</code> clocks about 21 seconds and <code>uv</code> about 2.6 — call it 8x. On a warm cache, where the packages are already on your machine, uv rebuilds the environment with hardlinks and the speedup gets silly: rebuilding a couple dozen packages, pip takes several seconds, uv finishes in a fraction of one.</p>
<p>Astral&rsquo;s headline figure is &ldquo;10–100x faster.&rdquo; I read that as honest, as long as you read the range: the ~100x end is warm-cache environment rebuilds, and the everyday case (a fresh, uncached install) lands closer to 8–10x in independent tests. Even at the bottom of that range it adds up, especially in CI, where every run reinstalls from scratch. For what it&rsquo;s worth, by April 2026 uv was pulling around 75 million monthly downloads on PyPI, past Poetry, and turning into a default in CI setups.</p>
<h2 id="the-part-that-surprised-me">The part that surprised me</h2>
<p>After a while, speed stopped being the thing I noticed. What I noticed was that the mental table was gone.</p>
<p>I used to sort tasks by tool without thinking — environment goes to venv, installing goes to pip, versions to pyenv, global tools to pipx. Now it&rsquo;s mostly <code>uv</code> followed by whatever I&rsquo;m trying to do. What disappeared wasn&rsquo;t a few seconds; it was the small tax of laying out the toolchain in my head at the start of every project. It&rsquo;s the same thing I noticed about <a href="/coding-agents-back-to-the-terminal/">coding agents moving back to the terminal</a>: the best tools earn their keep by what they let you stop tracking.</p>
<h2 id="so-switch-or-not">So, switch or not</h2>
<p>I&rsquo;m not going to tell you to drop everything and convert — that reads like a sales pitch. The honest version: plain pip / venv projects move over almost painlessly, because uv mirrors <code>pip</code>&rsquo;s own command surface. <code>uv pip install -r requirements.txt</code> runs as you&rsquo;d expect, so you can test the water with commands you already know.</p>
<p>The one place to watch is the conda world. Scientific computing that pulls in a stack of non-Python binaries (the C and Fortran libraries conda packages up for you) isn&rsquo;t a painless port, and conda still earns its keep there. If you&rsquo;re a pip person, try it freely. If you live in conda, don&rsquo;t rush.</p>
<h2 id="trying-it-on-one-project">Trying it on one project</h2>
<p>The installer is a one-line script from the docs (<code>curl ... | sh</code> on macOS / Linux, a PowerShell line on Windows), and it&rsquo;s also on Homebrew, winget, and pipx if you&rsquo;d rather. Once it&rsquo;s in, don&rsquo;t renovate everything at once — pick one existing project:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># inside the project, install against the existing requirements.txt</span>
</span></span><span class="line"><span class="cl">uv venv
</span></span><span class="line"><span class="cl">uv pip install -r requirements.txt
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># or start using uv&#39;s own project management</span>
</span></span><span class="line"><span class="cl">uv init
</span></span><span class="line"><span class="cl">uv add requests
</span></span><span class="line"><span class="cl">uv run python main.py
</span></span></code></pre></div><p>Run it a few times and feel the difference: no <code>activate</code> step, and installs fast enough to be mildly disorienting. Like it, and you can roll it out to other projects slowly. It won&rsquo;t force an all-at-once migration.</p>
<p>uv didn&rsquo;t invent any new ideas. Virtual environments, lockfiles, version management: Python has done all of these for years. What it did was gather the scattered tools behind one entry point and put Rust under the speed. That&rsquo;s the whole thing. Day to day, that&rsquo;s plenty.</p>
<hr>
<p><em>Related reading:</em></p>
<ul>
<li><em><a href="/coding-agents-back-to-the-terminal/">Why coding agents are moving back to the terminal</a> — a good tool&rsquo;s value is often what it lets you stop tracking</em></li>
<li><em><a href="/python-list-comprehension-explained/">Python list comprehensions, explained as a for-loop</a> — another small thing that makes everyday Python smoother</em></li>
</ul>
<p><em>For the source: <a href="https://docs.astral.sh/uv/">uv official docs</a>, <a href="https://github.com/astral-sh/uv">astral-sh/uv on GitHub</a>.</em></p>
<p><em>Chinese version: <a href="/uv-python-package-manager/">uv 是什麼？把 pip、venv、pyenv 收進一個指令</a></em></p>
]]></content:encoded>
    </item>
    
    <item>
      <title>uv 是什麼？把 pip、venv、pyenv 收進一個指令</title>
      <link>https://www.kbwen.com/uv-python-package-manager/</link>
      <pubDate>Sun, 28 Jun 2026 09:30:00 +0800</pubDate><dc:creator>KbWen</dc:creator>
      <guid>https://www.kbwen.com/uv-python-package-manager/</guid>
      <description>uv 是 Astral 用 Rust 寫的 Python 套件工具，把 pip、venv、pyenv、pipx 收進同一個指令，安裝又快上好幾倍。聊一下它取代了哪些東西、快多少，還有要不要換。</description>
      <content:encoded><![CDATA[<blockquote>
<p><strong>TL;DR</strong>：<code>uv</code> 是 Astral（做 Ruff 那家）用 Rust 寫的 Python 套件工具，把 <code>pip</code>、<code>venv</code>、<code>pyenv</code>、<code>pipx</code> 那一整排東西收進同一個指令。<code>uv add</code> 裝套件、<code>uv run</code> 跑程式、<code>uv python install</code> 管版本，第一次跑會自己幫你建好 <code>.venv</code>。安裝速度大概比 pip 快 8 到 10 倍，warm cache 重建環境更誇張。它相容你現有的 <code>requirements.txt</code>，所以想試的話風險很低，挑一個專案換換看就知道。</p>
</blockquote>
<p>開一個新的 Python 專案，腦子裡要記的工具有點多。<code>venv</code> 開虛擬環境，<code>pip</code> 裝套件，<code>requirements.txt</code> 記依賴，想管 Python 版本要 <code>pyenv</code>，想把某個 CLI 工具裝成全域又得搬出 <code>pipx</code>，講究一點還會上 <code>poetry</code> 或 <code>pip-tools</code> 處理鎖檔。每個我都會用，但每開一個新專案，那串「先建環境、再 source、再 pip install」的開場白，還是得從頭再打一次。</p>
<p><code>uv</code> 就是來收拾這一攤的。一個指令，把上面那排東西的活幾乎都接走了。</p>
<h2 id="為什麼-python-會搞出這麼多工具">為什麼 Python 會搞出這麼多工具</h2>
<p>這事說來有段歷史。Python 一開始沒把「環境」跟「套件」當成同一個問題在解，所以它們是一塊一塊長出來的：先有 <code>pip</code> 管安裝，後來發現裝一裝會互相打架，才有 <code>virtualenv</code> / <code>venv</code> 把每個專案隔開；再後來大家想鎖死版本好重現，<code>pip-tools</code>、<code>poetry</code>、<code>pipenv</code> 各自上場；版本管理又是另一條線，交給 <code>pyenv</code>。</p>
<p>每個工具單看都合理，合起來就得自己分工：這件事歸誰、那件事又歸誰。<code>uv</code> 的想法很簡單，把這些當成同一個問題的不同切面，用一個工具一起解掉。</p>
<h2 id="它接走了哪些工具">它接走了哪些工具</h2>
<p>換算起來大概是這樣，左邊是以前的習慣，右邊是 uv 的講法：</p>
<table>
  <thead>
      <tr>
          <th>以前</th>
          <th>現在用 uv</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>python -m venv .venv</code> 然後 source</td>
          <td>不用手動開，<code>uv</code> 第一次跑會自己建 <code>.venv</code></td>
      </tr>
      <tr>
          <td><code>pip install requests</code></td>
          <td><code>uv add requests</code></td>
      </tr>
      <tr>
          <td><code>pip install -r requirements.txt</code></td>
          <td><code>uv pip install -r requirements.txt</code>（指令相容）</td>
      </tr>
      <tr>
          <td><code>python script.py</code></td>
          <td><code>uv run script.py</code>（自動在對的環境裡跑）</td>
      </tr>
      <tr>
          <td><code>pyenv install 3.12</code></td>
          <td><code>uv python install 3.12</code></td>
      </tr>
      <tr>
          <td><code>pipx run black</code></td>
          <td><code>uvx black</code></td>
      </tr>
      <tr>
          <td><code>poetry</code> 那套鎖檔、發佈</td>
          <td><code>uv</code>（<code>pyproject.toml</code> + <code>uv.lock</code>）</td>
      </tr>
  </tbody>
</table>
<p>幾個比較有感的點。<code>uv add</code> 第一次在一個資料夾裡跑，它會順手把虛擬環境建好、把依賴寫進 <code>pyproject.toml</code>，你不用記得先 <code>activate</code> 那一步——<code>uv run</code> 會自己找到那個環境再執行。<code>uvx</code> 是 <code>uv tool run</code> 的縮寫，拿來跑一次性的 CLI 工具，它會開一個臨時環境跑完就收，剛好補上 <code>pipx</code> 的位子。版本管理也是內建的，<code>uv python install 3.12</code> 直接幫你抓一份回來，連 <code>pyenv</code> 都省了。</p>
<p>還有個小地方我覺得很關鍵：uv 本身是一顆單一 binary，裝它不需要你先有 Python。這聽起來像廢話，但 <code>pyenv</code> 那種「要先有 Python 才能管 Python」的雞生蛋問題，它一開始就繞過去了。</p>
<h2 id="快這件事到底快多少">快這件事，到底快多少</h2>
<p>uv 最常被拿出來講的賣點就是快，而且是用 Rust 寫的那種快。它的下載是並行的、抓 metadata、解依賴、寫磁碟這些步驟會重疊著跑；<code>pip</code> 預設是一個一個照順序下載，又卡在 Python GIL，差距就出來了。</p>
<p>具體一點的數字：裝 JupyterLab 這種套件，<code>pip</code> 量到大概 21 秒，<code>uv</code> 大概 2.6 秒，8 倍。如果是 warm cache（這些套件你機器上抓過了），uv 會用 hardlink 直接把環境拼起來，那快法更不像話：重建一個一二十個套件的環境，pip 要等上好幾秒，uv 零點幾秒就好。</p>
<p>Astral 官方掛的數字是「快 10 到 100 倍」。這話我覺得誠實，但要會看區間：接近 100 倍那端是 warm cache 重建環境的情況，日常比較常遇到的是沒 cache 的全新安裝，獨立測試量出來大概落在 8 到 10 倍。就算砍到區間最低，省下的時間每天累積起來也很有感，尤其 CI 每跑一次都要重裝一輪的話。順帶一提，到今年四月，uv 在 PyPI 上的月下載量已經到七千五百萬，超過了 Poetry，也慢慢變成不少 CI 的預設選擇。</p>
<h2 id="換過去之後最有感的不是快">換過去之後，最有感的不是快</h2>
<p>用了一陣子，速度反而不是我最在意的部分。最有感的是腦子裡那張表不見了。</p>
<p>以前要在心裡分一下「環境的事問 venv、裝的事問 pip、版本的事問 pyenv、全域工具問 pipx」，現在就是 <code>uv</code> 開頭，接著想做什麼。少掉的不是那幾秒，是每開新專案都要先在腦中把工具鏈排一次的那點麻煩。這跟我之前寫 <a href="/coding-agents-back-to-the-terminal-zh/">AI 寫 code 為什麼又搬回終端機</a> 時的感覺有點像：工具真正的價值，常常不在它多了什麼功能，而在它幫你少記了什麼東西。</p>
<h2 id="那要不要現在就換">那要不要現在就換</h2>
<p>我不會說「所有人立刻全換」，那有點像在賣東西。比較持平的講法是：純 pip / venv 的專案，幾乎是無痛搬，因為 uv 連 <code>pip</code> 的指令介面都相容，你 <code>uv pip install -r requirements.txt</code> 一樣會動，等於先用熟悉的姿勢試水溫。</p>
<p>要留意的主要是 conda 那一圈。做科學運算、吃一堆非 Python 二進位依賴（那種 conda 幫你打包好的 C / Fortran 函式庫）的場景，搬過來不是無痛的，這塊 conda 還是有它的理由在。如果你平常就是 pip 派的，那大概可以放心試；如果重度靠 conda，就先別急。</p>
<h2 id="想試的話從一個專案開始">想試的話，從一個專案開始</h2>
<p>裝 uv 官網給的是一行指令的安裝 script（macOS / Linux 用 <code>curl ... | sh</code>，Windows 有對應的 PowerShell 版），或者你習慣 Homebrew、winget、pipx 也都裝得到。裝完別急著全面翻新，挑一個現有的小專案：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 進到專案資料夾，照現有的 requirements.txt 裝</span>
</span></span><span class="line"><span class="cl">uv venv
</span></span><span class="line"><span class="cl">uv pip install -r requirements.txt
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 或者開始用 uv 自己的管法</span>
</span></span><span class="line"><span class="cl">uv init
</span></span><span class="line"><span class="cl">uv add requests
</span></span><span class="line"><span class="cl">uv run python main.py
</span></span></code></pre></div><p>跑個幾次，感覺一下那個「不用先 activate」跟「裝套件快到有點不真實」的差別。喜歡再慢慢往其他專案推就好，反正它不會逼你一次到位。</p>
<p>說到底 uv 沒發明什麼新觀念，虛擬環境、鎖檔、版本管理這些事 Python 圈早就在做。它只是把散在各處的工具收進同一個入口，再用 Rust 把速度補上。就這樣而已，但每天用下來，這樣也就夠了。</p>
<hr>
<p><em>延伸閱讀：</em></p>
<ul>
<li><em><a href="/coding-agents-back-to-the-terminal-zh/">AI 寫 code 為什麼又搬回終端機了</a>：好工具的價值，常常在於幫你少記了什麼</em></li>
<li><em><a href="/python-list-comprehension/">Python 列表推導式：一行取代 for 迴圈</a>：另一個讓日常 Python 順手一點的小東西</em></li>
</ul>
<p><em>想看源頭的話：<a href="https://docs.astral.sh/uv/">uv 官方文件</a>、<a href="https://github.com/astral-sh/uv">astral-sh/uv on GitHub</a>。</em></p>
<p><em>English version: <a href="/uv-replaces-pip-venv-pyenv/">uv: the Python tool that replaces pip, venv, and pyenv</a></em></p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
