
pnpm 12.4 Now Installs Your Python and Rust Deps
Quick answer: pnpm 12.4, released 10 September 2026, can resolve PyPI and crates.io dependencies in the same workspace as your npm packages, and ships pnpm pipeline, a cached task runner that lands squarely on Turborepo and Nx territory. It is explicitly early — pnpm's own note says the settings and the layout it writes may still change. Try it on a branch; do not put your production Python lockfile behind it yet.
Package managers grow by absorbing the thing next to them. npm absorbed script running. Yarn absorbed workspaces. pnpm has now absorbed two other language ecosystems and a build cache, which makes 12.4 the most interesting release it has shipped in years and also the one most likely to be misread as production-ready.
What actually shipped
Two opt-in flags in pnpm-workspace.yaml turn the feature on:
cargo:
enabled: true
python:
enabled: true
After that, pnpm add pypi:httpx and pnpm add crate:serde work, and a single pnpm install resolves all three ecosystems together. The scheme prefix is the whole interface, which is a good sign: it means pnpm is routing, not abstracting.
The important design decision is that pnpm did not invent new file formats. Each ecosystem keeps its own manifest and its own lockfile. That is the difference between a router and a wrapper, and it is why this is worth taking seriously instead of dismissing.
The Python side, precisely
| Concern | What pnpm does |
|---|---|
| Manifest | Standard pyproject.toml |
| Lockfile | Standard pylock.toml, validated independently with uv |
| Environment | A managed .venv per project |
| Execution | pnpm run and pnpm exec put the venv on PATH |
Two details deserve credit. Using pylock.toml means the lockfile is a standardised artefact rather than a pnpm dialect, so a Python developer who has never run pnpm can still read it. And validating the output independently with uv is the kind of check you would want but rarely see announced.
The venv-on-PATH behaviour is the part that will actually change your day. It removes the single most common failure in polyglot repos: a script that works for the person who remembered to activate the environment and fails for everyone else.
The Cargo side is more invasive
Rust dependencies stay in Cargo.toml and Cargo.lock, and resolve against crates.io or whatever sparse registry cargo.indexUrl names. But pnpm then vendors them into a Cargo directory source and wires that up through .cargo/config.toml.
That is a real intervention in a file Rust developers own and edit. If your repo already has a .cargo/config.toml with a registry mirror, a custom linker, or build flags, that is the first place to look when something behaves oddly. Vendoring also means your dependency bytes now live in the workspace rather than in Cargo's shared cache, which is a trade you should make deliberately.
pnpm pipeline is the bigger story
Buried under the polyglot headline is a task runner with a content cache. pnpm pipeline installs frozen dependencies, runs a named set of workspace tasks, selects affected projects, and keeps going after a failure so you get every error in one run instead of one per CI attempt.
tasks:
build:
dependsOn: ['^build']
outputs: ['dist/**']
test:
dependsOn: ['build']
outputs: []
pipelines:
default: [build, test]
If that shape looks familiar, it is because it is the shape Turborepo taught everyone. inputs narrows the cache key, env adds environment values to it, and cache: false opts a task out.
One design choice stands out: outputs: [] is a positive statement that a task writes no files, not merely an omission. Anyone who has debugged a cache that silently skipped a task because it was misconfigured will recognise why that distinction matters. Start with pnpm pipeline --dry-run before you trust it in CI.
There is also pnpm change check, which validates committed workspace versions against versioning.epics bands and versioning.fixed groups. It reads no change intents, which is exactly why it belongs as a pull-request check rather than a release step.
The practical draw is that a monorepo with a Node frontend, a Python service and a Rust binary currently needs three install commands, three caches and three CI steps that each know nothing about the others. Collapsing that into one dependency graph is worth real time on a small team. The practical risk is that you now have one tool that can break all three at once, and a much smaller pool of people who have hit your exact failure before.
The honest objection: who owns the lockfile
Here is the question to answer before you enable either flag. When your Python dependency resolution goes wrong at 2am, do you want the answer to be a uv or pip problem you can search for, or a pnpm problem in a code path that shipped weeks ago?
pnpm's own release note is unambiguous about maturity: this is early, and the settings and layout it writes may still change. That is not a reason to ignore it — it is a reason to keep the blast radius small. A tools service or an internal script repo is a fine place to try it. The repo that builds your product is not, at least not this quarter.
The second consideration is social rather than technical. A polyglot monorepo usually means more than one team, and asking a Python team to adopt a Node-shaped entry point is a negotiation, not a config change. The prize — one install command, one task graph, one cache — is real, but it is worth more when the people who own each ecosystem agreed to it first.
What we would actually do
Upgrade to 12.4 for the platform coverage and the registry-metadata fix alone — metadata is now kept separate for registries that differ in URL path or scheme, which quietly closes a class of cross-registry contamination, and the first install after upgrading refetches metadata automatically. Leave python.enabled and cargo.enabled off in anything that ships.
Then spend an afternoon on a branch with pnpm pipeline, because that is the piece most likely to replace a tool you are currently paying attention to. If you are auditing what else is in this space first, the developer tools category and our open-source listings are the fastest way to see the alternatives side by side. For the config files themselves, the YAML to JSON converter is handy when you want to diff a workspace file against what a tool actually parsed.
This is the same judgement call we made about Vite 8 and Rolldown and about Node 26 type stripping: adopt the boring half of the release immediately, and let the ambitious half prove itself on someone else's repo first.
FAQ
Does pnpm replace uv or pip?
It replaces the command you type, not the formats. Dependencies stay in pyproject.toml and a standard pylock.toml, and pnpm manages a .venv per project. pnpm reported validating its lockfile output independently with uv.
Is this production-ready?
pnpm says no, in as many words: it is early, and the settings and the layout pnpm writes may still change. Treat both ecosystem flags as experimental.
How do I install a Python or Rust package?
Enable the ecosystem in pnpm-workspace.yaml, then use a scheme prefix: pnpm add pypi:httpx or pnpm add crate:serde. A plain pnpm install then resolves every enabled ecosystem in one pass.
Does pnpm pipeline replace Turborepo or Nx?
It covers the same core job — a task graph with dependsOn, cacheable outputs, and affected-project selection — without a second tool in your dependency tree. Whether it replaces yours depends on how much of Turborepo's or Nx's wider tooling you actually use.
Will enabling Cargo support touch my existing config?
Yes. pnpm vendors crates into a Cargo directory source and wires it up through .cargo/config.toml. If you already keep registry mirrors or build settings in that file, review it after enabling the flag.
What else is in 12.4 worth upgrading for?
Registry metadata is now kept separate for registries differing in URL path or scheme, and binary releases now cover Android arm64 and x64, FreeBSD x64, and Linux ppc64le, s390x and RISC-V.
Every package manager eventually wants to be a build system. The good ones admit it in the release notes.


