Dependency alignment for applications
One command brings a standalone application's dependency versions and declared peers back into step with the framework release it has installed.
- What it is
- Tool — something you run.
- What it does
- An application aligns its dependency declarations to the framework release it actually installed — the pins the framework tested against, and the peers each framework package expects a consumer to supply.
- Where it stops
- It never changes a framework version.
wildo align-deps reads the framework packages an application actually has installed, derives from
them the third-party versions the application should pin and the peer dependencies each of its
packages must declare, and reports or writes the difference. It is what an application runs after
moving to a new framework release, and it needs no framework checkout to do it.
The problem it solves
When an application is scaffolded, the versions it pins and the peers it declares are computed from the framework at that moment. Afterwards nothing recomputes them. The application moves to a newer framework release, keeps the old third-party versions, and quietly runs a set of libraries the new engine was never tested against.
The peer half is worse, because it cannot be repaired by reinstalling. A package manager override rewrites a version some manifest wrote down; it never creates one. So a peer dependency that no manifest declares is resolved automatically, that resolution is recorded, and it is then never re-derived: the same install command, repeatedly, changes nothing. The visible symptom arrives later, when a version range narrows and a resolution frozen months earlier starts reading as a live conflict, at which point the code looks like the culprit and is not.
What it does
An application aligns its dependency declarations to the framework release it actually installed — the pins the framework tested against, and the peers each framework package expects a consumer to supply.
Everything is derived from the framework packages resolved in the application’s own tree. Nothing new has to be published for that to work: the publish lane already substitutes the framework’s single root pin into every published manifest — exact for ordinary dependencies, widened for peers — so the pin set and the peer closure are recoverable from the installed packages themselves. That is why it reads the installed tree rather than a published list: the data cannot drift from the packages it describes, because it IS them.
Findings split on two axes rather than being degrees of one thing: whether a name belongs in the application’s own pins or in a package’s dependency list, and whether it is absent or present and wrong. The one worth naming is a peer declared at a concrete version rather than as a wildcard — because the framework’s pin then cannot reach it, and a later version bump silently will not land.
Exclusions are the application’s own, in a file seeded when the application is scaffolded. That is the right owner: the application knows which names its own toolchain controls, and it is the party that breaks when the judgement is wrong.
A scenario that creates a new workspace package inside an application reads a delivered copy of the peer closure, so a site, a portal or a background worker is born with the peers it needs declared rather than with none.
What you decide
wildo align-deps
Read-only by default, exiting non-zero on drift. The upgrade order matters and the command states it: bump the framework versions, install, align, install again — the new pin set can only be read once the new framework version is on disk.
Limits
It never changes a framework version. Which release to adopt is the operator’s decision, and everything else follows mechanically from it.
It never removes a name. A managed name the closure does not require may still be the application’s own dependency — and an early version that pruned surplus entries stripped real dependencies out of two packages.
It writes declarations only. It does not install, so the resolution is unchanged until the next install, and the peer half specifically needs that second install to take effect.
A freshly scaffolded application legitimately needs one alignment run after its first install, because scaffolding writes pins from the framework checkout while pinning the framework itself to the published release — and those disagree whenever the checkout is ahead of the last release.