Skip to content

Project-aware hooks cannot access project dependency environments #2349

Description

@j178

Current behavior

prek follows the pre-commit model of installing each hook and its additional_dependencies into a dedicated, cacheable environment. The hook then runs from the project working directory and receives project files.

This model treats three things separately:

  1. the hook tool and its runtime dependencies,
  2. the project source and configuration,
  3. the project's dependency environment.

prek provides the first two. The third remains outside the hook environment.

That boundary works for self-contained formatters and source-level checks. It breaks down for project-aware tools whose behavior depends on packages installed for the project.

Symptoms across ecosystems

Node

A Stylelint hook can be installed and executed from its isolated Node environment, while the project's stylelint.config.js references shared configs and plugins from the project dependency graph. Installing those packages as hook additional_dependencies does not necessarily make them visible to resolution originating from the project configuration. See #2128.

Python

mypy, ty, and similar type checkers can run from an isolated Python environment, but accurate analysis may require the project's complete dependency closure, including PEP 561 packages, stubs, plugins, editable installs, and local workspace packages.

Installing only the type checker isolates it from those semantic inputs. Repeating the project dependencies in additional_dependencies creates a separate dependency graph that can drift from the project. This is discussed across #780, #1485, and #1675.

The same class of problem can affect framework-aware linters, test runners, code generators, and other hooks that import or inspect project dependencies.

Root cause

The hook isolation model assumes that the project is input data, not part of the hook's runtime dependency graph.

For project-aware hooks, that assumption does not hold: the project's installed dependencies are semantic inputs to configuration loading or analysis. Running the hook from the project directory exposes source files and configuration, but package resolution still follows the hook's interpreter and environment.

The current mechanisms cover different sides of the boundary but do not connect them:

  • additional_dependencies extends the hook environment, but does not derive a complete dependency graph from project metadata or lockfiles.
  • language: system, local hooks, and commands such as uv run can use the project environment, but bypass part of prek's isolation and environment caching model.
  • Reusing an active environment introduces ambient state and can produce different results across developers and CI.
  • Creating another isolated environment from project dependencies requires project manifests, lockfiles, dependency groups, workspaces, and local packages to participate in environment construction and cache invalidation.

This is not specific to Node module resolution or Python virtual environments. It is a general mismatch between isolated hook installation and tools whose correct execution depends on the project's dependency environment.

Related issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions