/flags/poetry/poetry-install-only-main
poetry install --only main: skip dev dependencies (replaces --no-dev)
- tool
- Poetry
- command
- poetry install
- flag
- --only GROUPS, --without GROUPS, --with GROUPS
- default
- main plus every non-optional group
poetry install --only main installs only the project's main dependencies ([project] dependencies or [tool.poetry.dependencies]) and none of the dependency groups such as dev or test. It is the Poetry 1.2+ replacement for the removed --no-dev flag and the usual choice for production installs and Docker images. --without dev excludes one group instead, and --with docs adds an optional group.
Groups in action
six is a main dependency, humanize belongs to the dev group:
cat > pyproject.toml <<'EOF'
[project]
name = "demo"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = ["six (==1.16.0)"]
[tool.poetry]
package-mode = false
[tool.poetry.group.dev.dependencies]
humanize = "4.11.0"
EOF
P="uvx -q poetry@2.5.1"
$P config virtualenvs.in-project true --local
$P lock -q
echo "--- poetry install --only main"
$P install --only main 2>&1 | grep "Installing"
echo "--- poetry install (adds the dev group)"
$P install 2>&1 | grep "Installing"
echo "--- poetry sync --only main (removes it again)"
$P sync --only main 2>&1 | grep -E "Installing|Removing"Output
--- poetry install --only main Installing dependencies from lock file - Installing six (1.16.0) --- poetry install (adds the dev group) Installing dependencies from lock file - Installing humanize (4.11.0) --- poetry sync --only main (removes it again) Installing dependencies from lock file - Removing humanize (4.11.0)
The first install brings only six. A plain install adds the dev group. poetry sync makes the environment match the selection exactly, so it removes humanize.
Group selection options
| Option | Installs |
|---|---|
| (none) | main plus all non-optional groups |
| --only main | Only the main dependencies |
| --without dev | Everything except the dev group |
| --without dev,test | Several groups, comma-separated |
| --with docs | Also an optional group (optional = true) |
| --only dev | Only the dev group (for tool-only CI jobs) |
| --no-dev | Removed in Poetry 2.0; deprecated since 1.2 |
The same options work with poetry sync, poetry show and poetry export (the export plugin).
Optional groups
[tool.poetry.group.docs]
optional = true
[tool.poetry.group.docs.dependencies]
mkdocs = "^1.6"An optional group is installed only with --with docs or --only docs. Mark groups optional when most developers do not need them.
Pitfalls
- Copying an old Dockerfile with
poetry install --no-devto Poetry 2 fails with The option "--no-dev" does not exist. --only mainstill installs the project itself in package mode; add --no-root when the code is not there yet.- Runtime imports declared under the dev group work locally and fail in production. Move them with
poetry add pkgandpoetry remove --group dev pkg. Adding dev dependencies is covered in poetry add --group dev. - Groups are a Poetry feature; with PEP 735
[dependency-groups]the equivalent in uv is uv sync --no-dev.
FAQ
What is the difference between --only main and --without dev?
--only main installs the main dependencies and nothing else. --without dev removes just the dev group, so other non-optional groups (test, lint) are still installed. For production, --only main is the safer choice.
Why does poetry install --no-dev fail?
--no-dev was deprecated in Poetry 1.2 and removed in Poetry 2.0, which answers The option "--no-dev" does not exist. Use --only main or --without dev instead.
Does --only main remove dev packages that are already installed?
No. poetry install only adds and updates. Use poetry sync --only main (Poetry 2) or poetry install --sync --only main (Poetry 1.x) to also remove what is not in the selected groups.