Poetry: Python Packaging and Dependency Management
What Poetry is
Poetry is a tool for dependency management and packaging in Python. You declare the libraries your project depends on in pyproject.toml, and Poetry resolves compatible versions, installs them into an isolated virtual environment, records the exact result in a lockfile, and can build and publish your project as a wheel and sdist. The README's tagline is "Python packaging and dependency management made easy", and its central claim is that Poetry replaces setup.py, requirements.txt, setup.cfg, MANIFEST.in and Pipfile with a single pyproject.toml-based project format.
The problem it addresses is familiar to anyone who has maintained a Python project for a few years: dependencies listed loosely in one file and pinned in another, a virtual environment managed by hand, packaging metadata spread across setup.py and setup.cfg, and no guarantee that a teammate, the CI runner and production all end up with the same versions. Poetry pulls those concerns into one tool with one config file and one lockfile, poetry.lock.
Poetry is MIT-licensed and written in Python. It is maintained under the python-poetry GitHub organisation, which also hosts poetry-core (the PEP 517 build backend), the official installer script and plugins such as poetry-plugin-export. It is used by application developers who want reproducible environments, library authors who want a straightforward build-and-publish workflow, and teams standardising how Python projects are laid out.
How it works
pyproject.toml as the single source of truth
Modern Poetry (2.x) uses the standard PEP 621 [project] table for metadata and runtime dependencies, written with PEP 508 strings such as "aiohttp (>=3.8.1,<4.0.0)". Poetry-specific settings that the standard does not cover live under [tool.poetry], for example a Python upper bound used only for locking, per-dependency options like allow-prereleases, alternative package sources and the package layout. Dependency groups can be declared with the standard PEP 735 [dependency-groups] table or with Poetry's own [tool.poetry.group.<name>] syntax. The FAQ includes a guide for migrating an older project from the tool.poetry section to the project section.
The build side is handled by poetry-core, declared as the build backend in [build-system]. Because it is a standard PEP 517 backend, other tools can build a Poetry project without Poetry itself being installed.
Resolution and the lockfile
When you run poetry install for the first time without a lockfile, Poetry resolves every dependency in pyproject.toml, downloads the latest matching versions and writes the exact versions to poetry.lock. Later runs with a lockfile present install exactly what it records, even if newer releases exist, so everyone on the project gets the same versions. poetry update fetches the latest versions allowed by your constraints and rewrites the lockfile, and poetry lock locks without installing; by default it does not update packages that are already in the lockfile. Poetry warns when pyproject.toml and poetry.lock are out of sync.
Locking is universal: the docs describe it as guaranteeing that the project is installable on all the Python versions you declare support for, not just the one you happen to be running. That is why Poetry asks you to state the supported Python range explicitly, and why it complains when a dependency's own Python requirements do not cover that range.
Environments
Environment isolation is a core feature. Poetry first checks whether it is already running inside a virtual environment and, if so, uses it. Otherwise it reuses or creates a virtualenv for the project, by default under {cache-dir}/virtualenvs, or inside the project directory if you set virtualenvs.in-project. It tries the Python version Poetry itself was installed with, then looks for one compatible with your declared range. poetry env use points a project at a specific interpreter, poetry run executes a command inside the environment, and poetry env activate prints the activation command for your shell.
Declaring dependencies
Poetry's dependency specification goes well beyond a version number. In the standard [project] table you write PEP 508 strings; in [tool.poetry.dependencies] you can use Poetry's own constraint operators. Caret requirements such as ^1.2.3 allow updates that do not change the left-most non-zero digit, so ^1.2.3 means at least 1.2.3 and below 2.0.0, while ^0.2.3 means at least 0.2.3 and below 0.3.0. Tilde requirements are tighter: ~1.2.3 allows only patch-level changes. Compatible-release (~=), wildcard, inequality and exact requirements are also supported. Caret and tilde operators are not valid in project.dependencies, and poetry add converts them to equivalent ranges automatically.
Beyond index packages, dependencies can point at a git repository (optionally pinned to a branch, tag or revision, with credentials for private repositories), a local path, or a URL to an archive. A dependency can be restricted to certain Python versions or platforms with environment markers, for example installing tomli only when python_version < '3.11', and a single package can carry multiple constraints so different Python versions get different version ranges. Optional runtime features are expressed as extras, while development tooling belongs in groups. The README's example pyproject.toml shows most of these together: a ranged dependency, one with extras, a version-specific one with prereleases allowed, and a git dependency on a branch.
The docs also take a position on upper bounds. The FAQ discusses whether unbound constraints like * or >=3.4 are a bad idea, and the README's example deliberately leaves requires-python without an upper bound in package metadata while setting one in [tool.poetry.dependencies] purely for locking. Library authors in particular should read that discussion before copying constraints from an application.
Configuration
Poetry's own behaviour is configured with poetry config, and poetry config --list shows the current values. Settings can be made globally or per project, and every setting can also be supplied as an environment variable prefixed with POETRY_, with dots and dashes turned into underscores, which is the usual approach in CI. A common example is virtualenvs.in-project (POETRY_VIRTUALENVS_IN_PROJECT): when true, the environment is created in a .venv folder at the project root, which many editors pick up automatically. If it is not set, Poetry uses {cache-dir}/virtualenvs, or an existing .venv directory in the project if one is already there.
Key features
- Project scaffolding.
poetry newcreates a project with asrc/layout, tests directory andpyproject.toml;poetry initinteractively adds Poetry to an existing directory. - Adding and removing dependencies from the CLI.
poetry add pendulumpicks a suitable constraint, updatespyproject.toml, resolves and installs in one step;poetry removereverses it. - Rich version constraints. Caret, tilde, wildcard, inequality and multiple-constraint requirements, plus git, path and URL dependencies and environment markers.
- Dependency groups. Separate test, docs or lint dependencies into groups, mark groups optional, and choose what to install with
--with,--withoutand--only. - Environment synchronisation.
poetry syncmakes the environment match the lockfile exactly, removing anything not locked, and combines with the group options. - Package and non-package modes. Package mode (the default) builds distributable packages and installs the project itself in editable mode; setting
package-mode = falseuses Poetry purely for dependency management, with name and version optional. - Build and publish.
poetry buildproduces an sdist and a wheel, automatically including licence files;poetry publishuploads to PyPI by default or to a configured private repository. - Plugins. Extend Poetry with plugins installed via
poetry self add, or declare required plugins per project in[tool.poetry.requires-plugins]. - Python version management (experimental). Since 2.1.0,
poetry python install,listandremovemanage interpreters from the Python Standalone Builds project; the docs flag this as experimental. - pre-commit hooks. Hooks such as
poetry-check, which stops a broken Poetry configuration from being committed,poetry-lock, which keeps the lockfile current, andpoetry-install; an export hook comes with the export plugin.
Getting started
Poetry requires Python 3.11 or newer to run and aims to work equally well on Linux, macOS and Windows. The docs say it should always be installed in a dedicated virtual environment, isolated from the rest of the system, and recommend pipx:
pipx install poetry
Alternatively, the official installer creates its own environment for Poetry:
curl -sSL https://install.python-poetry.org | python3 -
The installer puts a poetry wrapper in $HOME/.local/bin on Unix or %APPDATA%\Python\Scripts on Windows, which you may need to add to PATH. Poetry installed this way can update itself:
poetry self update
Then create a project, add a dependency and install:
poetry new poetry-demo
poetry add pendulum
poetry install
Development-only dependencies go into groups, and optional groups are installed on request:
poetry add pytest --group test
poetry install --with docs
poetry install --only main
Run tools inside the project environment, or activate it in your current shell:
poetry run which python
eval "$(poetry env activate)"
When the project is ready to ship, build the distributions and publish them; note that publish does not build unless you pass --build:
poetry build
poetry publish
Use cases
- Reproducible application environments. Commit
poetry.lockso developers, CI and production machines install identical versions, which the docs recommend for application developers. - Publishing libraries to PyPI. Metadata, build and upload all come from
pyproject.tomland two commands, without asetup.py. - Separating runtime and tooling dependencies. Keep pytest, Sphinx and linters in groups so production images install only the main group.
- Container builds with good layer caching. The FAQ's Dockerfile pattern installs third-party dependencies with
--no-root --no-directorybefore copying source code, so code changes do not invalidate the dependency layer. - Dependency management for non-packaged projects. Scripts, notebooks or services that are never published can use non-package mode for locking and environments only.
- Private package indexes. Configure additional sources and credentials to install from, and publish to, an internal repository.
How it compares
The README positions Poetry against the files it replaces rather than against named tools: requirements.txt for pinning, setup.py and setup.cfg for packaging metadata, MANIFEST.in for sdist contents, and Pipfile from Pipenv. Compared with plain pip and requirements.txt, Poetry adds dependency resolution with a lockfile, automatic virtualenv handling and a build-and-publish workflow in one tool. Compared with Pipenv, it also covers packaging rather than only application environments.
Other tools in the same space, such as uv, PDM and Hatch, also manage pyproject.toml-based projects, and since Poetry 2 adopted the standard [project] table and PEP 735 dependency groups, much of the metadata is portable between them; lockfile formats and tool-specific settings are not. Poetry does not install Python interpreters by default; the basic-usage guide says you bring your own interpreter, with the newer poetry python commands still experimental. On testing tools, the FAQ documents how to use Poetry with tox and Nox.
Things to know before adopting
- Install Poetry in its own environment. The docs warn that installing it into the same environment as your project can lead it to upgrade or uninstall its own dependencies, causing hard-to-debug errors. Use pipx, the official installer or a manual venv.
- Pin the Poetry version in CI. The docs strongly recommend controlling the Poetry version in CI, preferring pipx or a manual install, and keeping your own copy of the installer script rather than piping it from the internet on every run. Setting
$POETRY_HOMEkeeps paths predictable in multi-stage container builds. - Not strict semantic versioning. Poetry uses major.minor.micro versions where minor releases may add deprecations and drop features deprecated earlier; the FAQ explains why it does not follow strict semver. Read release notes before minor upgrades.
- Poetry 2.0 moved things into plugins.
poetry shellnow lives inpoetry-plugin-shell, andpoetry export(for generating arequirements.txt) needspoetry-plugin-export, which is no longer installed by default. - Resolution can be slow. The FAQ explains that when packages lack proper metadata in the PyPI JSON API, Poetry has to download and inspect them, which costs bandwidth and time. Narrowing constraints on problem packages helps, and cached metadata speeds up later runs.
- All groups must be mutually compatible. Dependency groups are resolved together even when not installed, so an optional docs group can still block resolution if it conflicts with the main dependencies.
- PEP 440 versions only. Poetry requires PEP 440-compliant versions for projects; a version like
1.0.0-hotfix.1is rejected. - Windows self-update quirks. The docs note that
poetry self updatecan be problematic on Windows and that reinstalling with the installer is preferable there. - Keep using virtual environments in containers. You can disable environment creation with
virtualenvs.create false, but the docs strongly encourage a virtual environment even inside containers.
Project activity
As of November 2026 the python-poetry/poetry repository has about 34,400 stars and around 2,570 forks on GitHub. It was created in February 2018, is written in Python and is licensed under MIT. The latest release at the time of writing is 2.5.1, published on 20 September 2026, and the repository was last pushed to in early November 2026. Documentation for the current version, the development branch and recently unsupported versions is on the official website, and the project runs a Discord server for discussion.
The source is at github.com/python-poetry/poetry, and the documentation is at python-poetry.org.
Enjoying this project?
Discover more amazing open-source projects on TechLogHub. We curate the best developer tools and projects.
Repository:https://github.com/python-poetry/poetry
GitHub - python-poetry/poetry: Poetry: Python Packaging and Dependency Management
Poetry is an MIT-licensed tool for Python dependency management and packaging. It manages dependencies in pyproject.toml, resolves them into a poetry.lock lockf...
github - python-poetry/poetry
Related Projects
Maintain Poetry: Python Packaging and Dependency Management? Add the badge to your README
Show that the project is featured on TechLogHub and send readers to this write-up.
[](https://techloghub.com/open-source/poetry-python-packaging?utm_source=techloghub_badge&utm_medium=referral&utm_campaign=readme)

