Skip to content

Conversation

@petebacondarwin
Copy link
Contributor

@petebacondarwin petebacondarwin commented Jan 13, 2026

Summary
This PR adds CI validation to ensure packages explicitly declare their external (non-bundled) dependencies, preventing accidental dependency chain poisoning. It also bundles 13 additional dependencies to reduce supply chain risk.

(Opus assisted changes in here but guided and checked by me)

New CI Check
Adds pnpm check:package-deps (runs as part of pnpm check) which validates that:

  • Every non-workspace dependency is listed in EXTERNAL_DEPENDENCIES (in scripts/deps.ts)
  • Every item in EXTERNAL_DEPENDENCIES exists in dependencies or peerDependencies
  • Packages with external dependencies have a scripts/deps.ts file with documented reasons
    This prevents developers from accidentally adding unbundled dependencies without explicit justification.

Dependencies Bundled
Moved 13 dependencies from dependencies to devDependencies so they get bundled:

Package Dependencies Bundled
kv-asset-handler mime
miniflare acorn, acorn-walk, exit-hook, glob-to-regexp, stoppable
@cloudflare/vitest-pool-workers birpc, devalue, get-port, semver
@cloudflare/vite-plugin @remix-run/node-fetch-server, defu, get-port, picocolors, tinyglobby

Remaining External Dependencies
Updated comments to explain why they can't be bundled (not just how they're used):

Package External Deps Reason
miniflare @cspotcode/source-map-support Uses require.resolve() and require.cache manipulation to load fresh instances at runtime
miniflare sharp, workerd Native binaries
miniflare undici, ws, zod Optional native bindings / commonly shared to avoid duplication
miniflare youch dynamically required at runtime for lazy loading of pretty error pages
@cloudflare/vitest-pool-workers esbuild Native binary
@cloudflare/vitest-pool-workers cjs-module-lexer, zod Optional native N-API bindings / commonly shared
@cloudflare/vite-plugin unenv Must be resolved at runtime when bundling user's code
@cloudflare/vite-plugin ws Optional native bindings / commonly shared

Why this matters
When users install our packages, npm/pnpm also installs everything in dependencies. If those dependencies have unpinned transitive dependencies, a malicious actor could publish a compromised version that gets pulled into user installations. By bundling dependencies and validating the allowlist in CI, we control exactly what code ships.

Fixes DEVX-1580


  • Tests
    • Tests included/updated
    • Automated tests not possible - manual testing has been completed as follows:
    • Additional testing not necessary because:
  • Public documentation
    • Cloudflare docs PR(s):
    • Documentation not necessary because: CI checks

A picture of a cute animal (not mandatory, but encouraged)

@changeset-bot
Copy link

changeset-bot bot commented Jan 13, 2026

🦋 Changeset detected

Latest commit: 996466b

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 13, 2026

create-cloudflare

npm i https://pkg.pr.new/create-cloudflare@11898

@cloudflare/kv-asset-handler

npm i https://pkg.pr.new/@cloudflare/kv-asset-handler@11898

miniflare

npm i https://pkg.pr.new/miniflare@11898

@cloudflare/pages-shared

npm i https://pkg.pr.new/@cloudflare/pages-shared@11898

@cloudflare/unenv-preset

npm i https://pkg.pr.new/@cloudflare/unenv-preset@11898

@cloudflare/vite-plugin

npm i https://pkg.pr.new/@cloudflare/vite-plugin@11898

@cloudflare/vitest-pool-workers

npm i https://pkg.pr.new/@cloudflare/vitest-pool-workers@11898

@cloudflare/workers-editor-shared

npm i https://pkg.pr.new/@cloudflare/workers-editor-shared@11898

@cloudflare/workers-utils

npm i https://pkg.pr.new/@cloudflare/workers-utils@11898

wrangler

npm i https://pkg.pr.new/wrangler@11898

commit: 996466b

@petebacondarwin petebacondarwin force-pushed the pbd/ci/devdeps-lint branch 5 times, most recently from 5043293 to 0869349 Compare January 14, 2026 09:14
@petebacondarwin petebacondarwin marked this pull request as ready for review January 14, 2026 09:14
@petebacondarwin petebacondarwin requested a review from a team as a code owner January 14, 2026 09:14
Copy link
Contributor

@emily-shen emily-shen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we do need a changeset right? On the off chance this breaks something, having something in the changelog saying which dependencies got bundled would be very helpful

@emily-shen
Copy link
Contributor

I also can't see any reason why bundling these packages would break anything (and for what its worth, nor can claude), so hopefully we are okay on that front

@github-project-automation github-project-automation bot moved this from Untriaged to Approved in workers-sdk Jan 14, 2026
@petebacondarwin
Copy link
Contributor Author

i think we do need a changeset right? On the off chance this breaks something, having something in the changelog saying which dependencies got bundled would be very helpful

Ah yes! The original PR only added the validation - but now I have actually made changes, we probably should have a changeset.

Add a validation check that ensures packages explicitly declare their
external (non-bundled) dependencies to prevent dependency chain poisoning.

- Add tools/deployments/validate-package-dependencies.ts validation script
- Add check:package-deps npm script and integrate into pnpm check
- Create scripts/deps.ts allowlists for packages with external dependencies:
  - miniflare (12 deps)
  - @cloudflare/vite-plugin (8 deps)
  - @cloudflare/vitest-pool-workers (7 deps)
  - @cloudflare/kv-asset-handler (1 dep)
  - @cloudflare/workers-editor-shared (1 dep)
- Update CONTRIBUTING.md with documentation on managing dependencies
- Add unit tests for the validation logic (22 tests)
…xternal

Move mime from dependencies to devDependencies so it gets bundled into
the distributable. This follows the project's practice of bundling
dependencies to prevent dependency chain poisoning.
Move acorn and acorn-walk from dependencies to devDependencies so they
get bundled into the distributable. These are pure JavaScript parsing
libraries with no special runtime requirements, so they can be safely
bundled.
Move 13 dependencies from dependencies to devDependencies so they get
bundled into the distributed packages rather than being installed as
transitive dependencies by users.

Packages updated:
- miniflare: bundle exit-hook, glob-to-regexp, stoppable, youch
- @cloudflare/vitest-pool-workers: bundle birpc, devalue, get-port, semver
- @cloudflare/vite-plugin: bundle @remix-run/node-fetch-server, defu,
  get-port, picocolors, tinyglobby

Also updates the EXTERNAL_DEPENDENCIES comments to explain WHY each
remaining dependency cannot be bundled (native binaries, optional native
bindings, runtime resolution needs) rather than just describing how
they are used.
@petebacondarwin petebacondarwin merged commit c17e971 into main Jan 14, 2026
36 checks passed
@petebacondarwin petebacondarwin deleted the pbd/ci/devdeps-lint branch January 14, 2026 21:11
@github-project-automation github-project-automation bot moved this from Approved to Done in workers-sdk Jan 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants