[WIP] fix(alchemy): make provider dependencies optional peers#312
[WIP] fix(alchemy): make provider dependencies optional peers#312aeterno-caspian wants to merge 2 commits into
Conversation
Move provider-specific packages out of the core dependency set so projects install the provider packages matching the alchemy subpaths they import. Lazy-load AWS and Cloudflare CLI provider modules so unrelated CLI commands do not require those optional peer packages at startup.
Represent lazy provider command module load failures with a tagged error that carries the provider, install command, and original cause.
|
This PR intentionally keeps the existing A possible follow-up would be a guided provider install command such as |
Mkassabov
left a comment
There was a problem hiding this comment.
What's the usecase driving this change?
We thought about this early on and it was a very conscious de scion to not do this because we need providers to be able to reference each other (e.g. for cross cloud bindings). it would also force us to have another set of packages since distilled is just raw sdks not the providers themselves
|
I think we may be talking past each other on scope. This PR does not split provider source packages, remove cross-provider references, or change the existing The use case is dependency ownership and supply-chain scope. Alchemy runs in local and CI environments that often have deploy credentials, state access, and cloud permissions. If an AWS-only project installs the Cloudflare runtime graph by default, that unused graph still enters the lockfile, install policy, and trust boundary for infrastructure execution. In our case, this included I agree cross-provider bindings are the important edge case. My expectation is that a binding spanning AWS + Cloudflare should live behind an import surface that requires both provider groups, and consumers of that surface install both. If there is a concrete module today that must be importable under partial provider installs but eagerly imports both provider graphs, that is the implementation problem I want to identify and fix. The lazy CLI change applies the same idea at command startup: For non-CLI imports, the UX cost is real: missing optional peers need clear install guidance. This PR starts that in docs/examples and typed CLI load errors, but I am open to tightening the error surface for provider subpath imports if there is a preferred pattern. So the question I’m trying to answer is narrower than “can providers reference each other?” They can. The question is whether an AWS-only consumer must install the Cloudflare runtime graph by default, or whether provider and cross-provider surfaces can own the dependency groups they actually require. |
|
We were chatting about this and think the right move is:
|
|
Noted. I will attempt to think of ways that could potentially mitigate as much DX friction as possible. Switching this PR to WIP for the time being. |
| } from "../../versions"; | ||
|
|
||
| export const corePkgs = `"alchemy@${alchemyVersion}" "effect@${effectVersion}" "@effect/platform-bun@${effectVersion}" "@effect/platform-node@${effectVersion}"`; | ||
| export const cloudflarePkgs = `"@cloudflare/workers-types@${cloudflareWorkersTypesVersion}" "@distilled.cloud/cloudflare@${distilledCloudflareVersion}" "@distilled.cloud/cloudflare-runtime@${distilledCloudflareRuntimeVersion}" "@distilled.cloud/cloudflare-vite-plugin@${distilledCloudflareVitePluginVersion}" "@distilled.cloud/cloudflare-rolldown-plugin@${distilledCloudflareRolldownPluginVersion}" "ignore@^7.0.5" "sonda@${sondaVersion}" "vite@${viteVersion}"`; |
There was a problem hiding this comment.
This is excessive, how can we reduce this?
|
As part of #321 I am removing all of the vercel AI sdk dependencies and web-tree-sitter stuff. |
|
Vendoring in the |
|
An update here. We are vendoring in more packages here https://github.com/alchemy-run/node-utils. Partly for security, but also because they're ancient and written for CJS and use weird dependencies like graceful-fs. We are dropping those and vendoring in the rest. |
|
Been a busy week. Apologize for the inactiveness. Going to catch up with the latest and get some contributions going this weekend. |
Overview
alchemyalready exposes provider-specific entry points such asalchemy/AWS,alchemy/Cloudflare,alchemy/GitHub,alchemy/Axiom,alchemy/Neon,alchemy/Drizzle, andalchemy/SQLite.This PR makes the package dependency model match that module surface. Provider and integration packages now live as optional peer dependencies, so consumers install the packages for the provider surfaces their project imports.
Behavior
A project that installs
alchemyfor core functionality now receives the core dependency graph.A project that imports a provider subpath declares that provider package group explicitly. For example, a project importing
alchemy/Cloudflaredeclares the Cloudflare resource/runtime packages, while a project importingalchemy/AWSdeclares the AWS package set.This removes install-time side effects where consumers receive provider runtime graphs for integrations their project never imports.
CLI Loading
The
alchemy aws ...andalchemy cloudflare ...command groups now lazy-load their provider implementation modules when those command groups run.That keeps provider command availability in the CLI while preventing unrelated CLI commands from requiring AWS or Cloudflare provider packages at startup.
Provider module load failures now surface as a typed
ProviderCommandLoadErrorcarrying:Documentation And Examples
The README, getting-started guide, tutorial install steps, CLI guide, and runnable example manifests now declare provider packages beside the provider imports that require them.
This keeps copy-pasted examples aligned with the dependency model.
Verification
bun tsc -p packages/alchemy/tsconfig.json --noEmitbun run --filter alchemy buildalchemy/<provider>import has matching provider package declarations.workerd,libsodium-wrappers, and@types/libsodium-wrappersdo not resolve for a core-only consumer.bun run --filter alchemy buildstill emits the existing externalized import warnings foralchemy/Cliandalchemy/Util/PlatformServices; the build exits successfully.