Cross-extension code sharing via manifest exports field
Opened by keeb · 4/21/2026
Problem
Extensions cannot import code from other swamp extensions. The only mechanisms for code reuse today are (a) vendoring (copy-paste) or (b) publishing to npm. This creates duplication and drift across extensions that share helpers.
How the bundler works today (src/domain/models/bundle.ts):
- Per-model bundles produced via
deno bundle/ esbuild. - Only
npm:zod@4is externalized; every other import is inlined. https://imports are not supported;jsr:specifiers are explicitly skipped.- There is no mechanism to externalize an alias that points at another installed extension.
What dependencies: in manifest.yaml does today (src/libswamp/extensions/pull.ts:999-1030):
- Triggers auto-pull of dependent extensions at install time.
- Blocks
rmwhen another extension depends on it. - Zero effect on bundling — not a code-import mechanism.
Concrete evidence this is painful:
@keeb/proxmoxdeclaresdependencies: [@keeb/ssh]in its manifest, and ALSO vendorslib/ssh.tsbyte-for-byte from@keeb/ssh. The two files are 59 lines each anddiffbetween them is empty. The dep tells swamp "install ssh alongside me" but does nothing for the code that proxmox's method implementations actually need.- Another concrete ask:
@adam/cfgmgmtwould like to use the transport from@retr0h/natswithout vendoring. Today there is no supported path.
Proposed solution
Add an exports: field to manifest.yaml that declares library modules the extension makes importable by other extensions. Combined with the existing dependencies: field, this gives extension authors a first-class shared-code path.
Sketch:
# @keeb/ssh manifest.yaml
exports:
- path: lib/ssh.ts
alias: "@keeb/ssh/lib/ssh"// @keeb/proxmox code
import { ssh } from "@keeb/ssh/lib/ssh";Scope of changes:
- manifest schema (
src/domain/extensions/extension_manifest.ts) — add optionalexportsarray. - Bundler (
src/domain/models/bundle.ts) — resolve alias imports against installed extensions at bundle time, either inlining the exported module's source or wiring an--externalentry to a shared runtime module. - Pull / install path (
src/libswamp/extensions/pull.ts) — ensure exported paths are included in the tarball and extracted to a predictable location. - Validation — reject publishes where
exportsreferences files outside the extension, or where a consumer imports an alias not declared in any installed dep'sexports.
Pairs naturally with existing dependencies: — the dep triggers install, the exports declaration makes the code importable. No change needed to how models/workflows/CEL already reference each other.
Alternatives considered
- Publish helpers to npm. Works today but forces Deno-native extension authors onto npm for purely-internal sharing.
- Vendoring. Works today; causes silent drift when the source extension updates.
- First-class
jsr:support (filed as a separate issue). Smaller scope, also addresses part of the same problem without a manifest change.
Open
No activity in this phase yet.
Sign in to post a ripple.