
Every Python project has to answer the same two questions: how do I install the packages I need, and how do I make sure the next machine gets exactly the same ones? pip answers the first well and the second badly. Poetry answers both, at the cost of learning a new tool. This cheat sheet puts the everyday commands side by side so you can switch between them without looking anything up.
The examples install Iotcore, an MQTT broker package I maintain, but any package name works.
When to use which
Use pip directly when you are inside an existing virtual environment, writing a quick script or working in a project that already has a requirements.txt. Use Poetry when you are starting a project that other people will install, publishing a package or when “it works on my machine” has bitten you once too often. Poetry’s lock file records the exact version of every dependency and sub-dependency, which pip alone does not do.
Both tools can coexist. Poetry uses pip under the hood to install wheels, and you can always pip install inside a Poetry environment in a pinch.
pip: the everyday commands
Prefer python3 -m pip over a bare pip. It guarantees the package lands in the interpreter you think it does, which matters on machines with more than one Python.
Install a package:
python3 -m pip install iotcore
Show where a package is installed, its version and what it depends on:
python3 -m pip show iotcore
Remove it:
python3 -m pip uninstall iotcore
List everything in the current environment:
python3 -m pip list
Upgrade one package to the latest release (-U is the short form):
python3 -m pip install --upgrade iotcore
# or
python3 -m pip install -U iotcore
Snapshot the environment so another machine can reproduce it, then install from that snapshot:
python3 -m pip freeze > requirements.txt
python3 -m pip install -r requirements.txt
pip freeze pins versions, but it records only what is installed right now, with no record of which packages you asked for and which came along as dependencies. That is the gap Poetry fills.
Poetry: the everyday commands
Create a new project. Poetry scaffolds a package directory, a tests/ folder and a pyproject.toml:
poetry new poetry_demo
Add a dependency. This writes it to pyproject.toml, resolves the full dependency tree, pins it in poetry.lock and installs it:
poetry add arrow
Add a development-only dependency, such as a test runner, so it is not installed in production:
poetry add --group dev pytest
Show what is installed, as a tree so you can see which top-level package pulled in what:
poetry show --tree
Remove a package:
poetry remove arrow
Install everything from the lock file on a fresh machine or in CI. The --sync flag also removes anything in the environment that the lock file does not list:
poetry install --sync
Update dependencies within the ranges allowed by pyproject.toml and rewrite the lock file:
poetry update
Commit poetry.lock. It is the whole point.
Virtual environments in Poetry
Poetry creates and manages a virtual environment per project. You rarely need to think about it, but three commands cover the cases where you do.
Open a shell inside the environment:
poetry shell
Leave it the same way you leave any shell:
exit
Run a single command inside the environment without opening a shell, which is the right form for scripts and CI:
poetry run python project/script.py
If you prefer the environment to live inside the project folder, set it once and Poetry will create .venv/ there instead of in its cache directory:
poetry config virtualenvs.in-project true
Define your own commands
Poetry can register Python functions as command-line entry points, which replaces a pile of Makefile targets or shell scripts. Create a script, for example scripts/timer.py:
import time
def main():
time.sleep(3)
print("Timer expired")
if __name__ == "__main__":
main()
Register it in pyproject.toml:
[tool.poetry.scripts]
timer = "scripts.timer:main"
Run it:
poetry run timer
When the package is installed with pip, the same entry becomes a real timer executable on the user’s path, which is how command-line tools distributed on PyPI are built.
Quick reference
| Task | pip | Poetry |
|---|---|---|
| Install a package | python3 -m pip install X |
poetry add X |
| Remove a package | python3 -m pip uninstall X |
poetry remove X |
| List installed | python3 -m pip list |
poetry show --tree |
| Upgrade | python3 -m pip install -U X |
poetry update X |
| Reproduce an environment | pip install -r requirements.txt |
poetry install --sync |
| Run inside the environment | activate venv, then run | poetry run ... |
Summary
pip is the right tool for installing things into an environment you already have. Poetry is the right tool for owning a project: it keeps a lock file, separates development dependencies from runtime ones and turns functions into commands. Learn the handful of commands above and the choice stops being a debate.


