Multiple Package Managers
Prevents lockfile conflicts by directing agents to the package manager already used.
Scenario
You maintain a repository containing several independently managed projects.
The repository is unusual because not every project uses the same package manager.
For example:
- the modern web application uses pnpm;
- a legacy service still uses npm;
- migration of the legacy service is planned but has not happened yet.
A coding agent must not assume that the package manager used at the repository root applies everywhere.
Repository Structure
platform/
├── AGENTS.md
├── pnpm-lock.yaml
├── apps/
│ └── web/
│ ├── package.json
│ └── src/
└── legacy/
└── reporting-service/
├── AGENTS.md
├── package.json
├── package-lock.json
└── src/
The main workspace uses pnpm.
The legacy reporting service is intentionally still managed with npm.
AGENTS.md
Root AGENTS.md:
# Repository Instructions
## Package Management
- Use `pnpm` for the main workspace.
- Run workspace commands from the repository root.
- Do not create Yarn lockfiles.
## Legacy Projects
- Some directories under `legacy/` may use a different package manager.
- Follow scoped instructions and the existing lockfile when working inside a legacy project.
- Do not migrate package managers as part of an unrelated task.
The legacy service has narrower instructions:
legacy/reporting-service/AGENTS.md
# Reporting Service Instructions
## Package Management
- This service currently uses `npm`.
- Use `npm ci` to install dependencies from the existing lockfile.
- Use `npm test` for this service's tests.
- Do not create a `pnpm-lock.yaml` in this directory.
- Do not migrate this service to pnpm unless the task explicitly requires the migration.
## Validation
Before completing changes to this service, run:
- `npm test`
- `npm run lint`
What This Does
This documents an intentional exception to the repository's normal package-management rule.
At the root:
pnpm
is the default.
Inside:
legacy/reporting-service/
the more specific instructions establish:
npm
as the correct workflow.
The agent does not need to guess based on personal preference or attempt to make the entire repository uniform.
What This Does NOT Do
The instructions do not claim that using multiple package managers is ideal.
They describe the repository as it exists today.
This is important.
AGENTS.md should not pretend that a planned architecture already exists.
The file also does not tell the agent:
- Convert npm projects to pnpm whenever you encounter them.
That would turn unrelated feature work into a dependency-management migration.
Why These Instructions Matter
Imagine an agent is asked to fix a small bug in:
legacy/reporting-service/
It sees that the main repository uses pnpm and runs:
pnpm install
That could introduce:
pnpm-lock.yaml
inside the legacy project or otherwise modify dependency state unexpectedly.
The actual task was a bug fix.
Package-manager migration was not part of the request.
The scoped instruction prevents that accidental expansion of scope.
Key Decisions
Describe reality, not the desired future
If a legacy application still uses npm, document npm.
When the migration actually happens, update the instructions.
Existing lockfiles are useful signals
Files such as:
pnpm-lock.yaml
package-lock.json
yarn.lock
provide strong evidence about the intended package manager.
AGENTS.md can make that intent explicit when exceptions exist.
Scoped instructions handle exceptions
A root rule can describe the normal case:
- Use `pnpm` for the main workspace.
A narrower file can document an exception without cluttering every other part of the repository.
Don't perform migrations accidentally
Changing package managers can affect:
- lockfiles;
- dependency resolution;
- scripts;
- CI;
- deployment;
- developer workflows.
It should be an intentional task.
When to Use This Pattern
Use this pattern when:
- a repository contains independently managed applications;
- legacy projects use different tooling;
- a migration is happening incrementally;
- different directories genuinely require different commands.
If the entire repository uses one package manager, keep the instruction simple instead of introducing unnecessary scoped rules.