Skip to content

Packages and sharing them between plugins

Keep the model (types, initial values) and the logic (pure transitions) in a plain package under packages/<name>/ — no kernel, no React. The plugin is only the adapter layer: events, handlers, store slice, declarative UI. See Architecture: packages, plugins and the shell and packages/notes-core used by plugins/notes-tsx.

When plugin B depends on plugin A and both need the same package, B must not bundle its own copy. A registers the single instance and B marks the package as shared:

// plugin A (owner) — setup()
ctx.providePackage("notes-core", notesCore);
plugins/b/plugin.json
{ "shared": ["notes-core"] }

The builder rewrites every import of notes-core in B’s bundle — including imports inside other bundled packages — to a lazy bridge that resolves against A’s instance at call time. dependsOn: ["a"] guarantees activation order. Convention: shared packages export functions and types only.

Demo: plugins/demo-shared-a + plugins/demo-shared-b (bun test tests/shared-packages.test.ts).

Documentation under CC BY 4.0 · © SCFlow contributors ·Back to supplychainflow.org