Virtual Envs, pip, uv, and Poetry
npm/package.json → pip/venv/pyproject.toml
Section titled “npm/package.json → pip/venv/pyproject.toml”Package management is where Python’s tooling history is most visible. Node has one model: npm installs into node_modules, package.json declares dependencies, and package-lock.json locks exact versions. Python has three layers you need to understand: the interpreter itself, the isolation layer (venv), and then the package manager on top.
Layer 1: Virtual Environments (venv)
Section titled “Layer 1: Virtual Environments (venv)”Run this in your terminal:
# Create a virtual environment in the .venv folderpython3 -m venv .venv
# Activate it — you must do this every new terminal sessionsource .venv/bin/activate # macOS / Linux# .venv\Scripts\activate.bat # Windows CMD# .venv\Scripts\Activate.ps1 # Windows PowerShell
# Confirm which python is activewhich python # should point to .venv/bin/python
# DeactivatedeactivateOnce activated, pip install X installs only into .venv. Add .venv/ to your .gitignore.
Layer 2: pip + requirements.txt (classic)
Section titled “Layer 2: pip + requirements.txt (classic)”# npm classic workflownpm install express # adds to package.json + node_modulesnpm install -D jest # dev dependencynpm install # install from package.jsonnpm ci # clean install from lock file (CI)
# package.json excerpt:# {# "dependencies": { "express": "^4.18.2" },# "devDependencies": { "jest": "^29.0.0" }# }# pip classic workflowpip install requests # installs to active venvpip install pytest --upgrade # install/upgrade dev deppip freeze > requirements.txt # snapshot all installed versionspip install -r requirements.txt # reproduce from snapshot
# requirements.txt excerpt:# requests==2.31.0# certifi==2024.2.2# charset-normalizer==3.3.2requirements.txt is the oldest approach. It works, but it has no distinction between direct and transitive dependencies. The modern replacement is pyproject.toml.
Layer 3: uv — the fast modern tool
Section titled “Layer 3: uv — the fast modern tool”uv (by Astral, the ruff team) is a Rust-powered replacement for pip and venv combined. It is 10–100× faster than pip and handles virtual environments automatically.
# Install uv (once, globally)curl -LsSf https://astral.sh/uv/install.sh | sh
# Create a new project (generates pyproject.toml + .venv)uv init my-projectcd my-project
# Add a dependency (updates pyproject.toml + uv.lock)uv add fastapi
# Add a dev dependencyuv add --dev pytest ruff mypy
# Sync environment from pyproject.toml (like npm ci)uv sync
# Run a command inside the venv without activatinguv run python main.pyuv run pytestLayer 4: Poetry — the npm-like experience
Section titled “Layer 4: Poetry — the npm-like experience”Poetry was the first tool to unify project metadata, dependency resolution, and virtual environment management into one ergonomic CLI. Many existing projects use it.
# npm-like workflownpm init # scaffold package.jsonnpm install express # add runtime depnpm install -D jest # add dev depnpm run start # run scriptnpm run test # run testscat package-lock.json # exact lock file# Poetry — npm-like workflow for Pythonpoetry new my-project # scaffold pyproject.toml + src/poetry add fastapi # add runtime deppoetry add --group dev pytest # add dev deppoetry run python main.py # run scriptpoetry run pytest # run testscat poetry.lock # exact lock fileComparing the options
Section titled “Comparing the options”| pip + venv | poetry | uv | |
|---|---|---|---|
| Speed | slow | medium | very fast |
| Lock file | requirements.txt (manual) | poetry.lock | uv.lock |
| pyproject.toml | partial | full | full |
| Venv auto-management | manual | yes | yes |
| Maturity | very stable | stable | newer (2024+) |
| Recommendation | legacy projects | existing poetry projects | new projects |
Playground note: Package managers modify the filesystem and network — they require a terminal. Run the commands above in your project directory.