/flags/poetry/poetry-install-extras
poetry install -E (--extras): install optional dependencies
- tool
- Poetry
- command
- poetry install
- flag
- -E, --extras NAMES, --all-extras
- default
- no extras are installed
Extras are optional dependency sets that a package offers, like requests[socks]. poetry install -E fast (long form --extras fast) installs the project's own extra named fast in addition to the normal dependencies; --all-extras installs every extra. In Poetry 2 extras are declared in the standard [project.optional-dependencies] table, so pip users get the same sets with pip install demo[fast].
Installing an extra
cat > pyproject.toml <<'EOF'
[project]
name = "demo"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = ["six (==1.16.0)"]
[project.optional-dependencies]
fast = ["humanize (==4.11.0)"]
[tool.poetry]
package-mode = false
EOF
P="uvx -q poetry@2.5.1"
$P config virtualenvs.in-project true --local
$P lock -q
echo "--- poetry install"
$P install 2>&1 | grep "Installing"
echo "--- poetry install -E fast"
$P install -E fast 2>&1 | grep "Installing"
echo "--- poetry install again, without -E"
$P install 2>&1 | grep -E "Installing|Removing|No dependencies"
echo "--- unknown extra"
$P install -E slow 2>&1 | grep -i "extra"Output
--- poetry install Installing dependencies from lock file - Installing six (1.16.0) --- poetry install -E fast Installing dependencies from lock file - Installing humanize (4.11.0) --- poetry install again, without -E Installing dependencies from lock file No dependencies to install or update --- unknown extra Extra [slow] is not specified.
The extra's package is only installed when it is requested, and a later plain poetry install leaves it in place. An extra name that the project does not define is rejected with Extra [slow] is not specified., so typos in CI scripts are visible.
Options
| Option | Effect |
|---|---|
| -E fast / --extras fast | Install the extra named fast |
| -E fast -E cli or --extras "fast cli" | Several extras |
| --all-extras | Every extra defined by the project |
| --only main -E fast | Main dependencies plus the extra, no groups |
| poetry sync -E fast | Install the extra and remove packages that are not selected |
Declaring extras
[project.optional-dependencies]
fast = ["orjson (>=3.10)"]
cli = ["typer (>=0.12)", "rich (>=13)"]Poetry 1.x used [tool.poetry.extras] together with optional = true on each dependency. Poetry 2 still reads that layout, but new projects should use the standard table, which every packaging tool understands. After editing extras by hand, run poetry lock, otherwise commands fail with pyproject.toml changed significantly.
Extras versus groups
- Extras describe optional features of the package and travel with it to PyPI.
- Groups (
[tool.poetry.group.dev]) hold development tools and are never published; select them with--with,--withoutand --only.
Pitfalls
- Shells expand square brackets: quote package specs with extras (
pip install "demo[fast]"), especially in zsh. - Extras of a dependency are requested differently, in its dependency entry:
"requests[socks] (>=2.32)". - Code that imports an optional package should handle
ImportErrorand print a hint like "install demo[fast]", because users of the base install do not have it.
FAQ
What is the difference between extras and dependency groups?
Extras are part of the published package: users install them with pip install demo[fast]. Groups are a Poetry-only development feature and are never published. Use extras for optional features of your library, groups for dev tools.
Does poetry install without -E remove extras I installed before?
No. As the example shows, poetry install only adds and updates packages, so an extra installed earlier stays. poetry sync makes the environment match the request exactly and removes extras that are not passed again.
How do I add a package as an extra?
poetry add humanize --optional fast adds it to the fast extra in Poetry 2 (in Poetry 1.x, --optional marks it and the extras table names it). Then run poetry lock if pyproject.toml was edited by hand.