Skip to content

Dependencies

Few dependencies here are replaceable. isolated-vm runs the isolates, capnweb provides the RPC session, and the upstream package this executor stands in for defines the dialect the adapter has to match. None of those three can be swapped in an afternoon, so most of the work a dependency costs here is spent before it is installed.

Read a dependency from its real repository: the sources, the tests, the history. Built dist output and rolled-up typings tell you what a function accepts. But only the repository tells you who owns a behaviour, which layer decided it, and whether anyone decided it on purpose.

  • Read the API at the released tag matching the installed version, never at the clone’s HEAD. Behaviour on main may be months away from a release, and building on it means building on something no consumer has.
  • Ground an integration decision in the upstream layer that owns the behaviour, read before deciding. Decisions taken from the package surface guess at ownership and call the guess a design.
  • Check whether the problem already has an upstream answer before designing one here. An open pull request, or a merged commit waiting on a release, changes what the right fix is.

Byte-level copying from another project, in place of importing it, needs explicit approval before a single line lands. A copy forks upstream the moment it is made: the original keeps moving, the copy does not, and no tool anywhere reports the divergence.

Sometimes a duty falls to this executor because upstream cannot deliver its implementation to this runtime. That duty gets a module of its own here, written from the requirement and never transcribed, and Module design states the rule in full. The differential suite in Testing then proves compatibility end to end.

Patch upstream first, carry the patch locally

Section titled “Patch upstream first, carry the patch locally”

When a dependency needs a fix, the fix goes upstream. A local patch bridges the wait. That patch is exactly upstream’s commit, not a local reinterpretation of it, so the patched tree and the eventual release behave the same and the upgrade is uneventful.

Cutting a patch takes two commands. pnpm patch copies the package into a directory it prints, and pnpm patch-commit turns the edits left in that directory into a patch file:

Terminal window
pnpm patch <name>@<version>
# apply upstream's commit inside the directory it printed, then
pnpm patch-commit <that directory>

patch-commit writes the file under patches/ and records it under patchedDependencies, keyed by the exact version it was cut against.

  • Keep the key on the exact version the patch applies to. A version bump then forces somebody to look at the patch, where an unkeyed one would be silently dropped or misapplied.
  • Retire a patch the moment the upstream release carrying the fix lands. A patch that outlives its release is a fork of upstream that nobody decided to keep.
  • Resolve the consumer gap before publishing. Local patches apply to this repository’s installs and never reach consumers of the published packages. So a fix that consumers depend on ships as a released dependency version, not as a patch file.

Dependencies stay current. An advisory names a version range, and a tree that stops moving falls inside more of those ranges over time.

  • Scope an advisory override to the majors actually present in the tree, and say in a comment which dependent has to move before the override can drop. Unscoped overrides quietly rewrite versions nobody audited.
  • Treat the minimumReleaseAge cooldown as supply-chain protection and not as friction. Freshly published versions are exactly the shape a compromised release takes. But wanting a version sooner is not a reason to bypass the wait.
  • Prefer removing a dependency over patching it, whenever the code it carries is smaller than the integration it demands.

@cloudflare/codemode is a peer dependency, and packages/cloudflare-codemode/package.json declares its range with both ends stated.

  • Never pin the integration target as a direct dependency of a published package. Pinning turns a compatible upgrade on the consumer’s side into a conflict they did not ask for.
  • Prove the declared range, never assert it. The compatibility suite installs the newest supported line under the upstream package name and every older line under a versioned npm alias. Each line gets its own run in the version matrix, so the range in peerDependencies and the range under test are the same set.
  • Widen or narrow the range and the matrix in one change. A range that outruns its matrix is an untested promise, and because the promise is written in semantic versioning terms, a consumer’s resolver acts on it without asking anyone first.