ADR 0013: Plugin API version 1 is stable
- Status: accepted when the PR that adds it is merged (the owner's review)
- Date: 2026-11-03
Context
ADR 0012 made optional features plugins and kept the plugin interface experimental "until our own plugins have proven it". Its section 6 sets the condition for declaring it stable as API version 1: all three of our plugins run on it unchanged from their own repositories. That is now true:
@smaltdb/io,@smaltdb/externaland@smaltdb/parquetlive in their own repositories (step 5);- their code builds against smaltdb's published types and entry points only (
smaltdb/engine,callPlugin), checked by each plugin's declaration build. Only some of their tests reach into the engine's source, to drive the engine server directly.
Nothing is published before the interface is declared stable (owner's decision, 2026-11-02). Declaring it stable is a promise to plugin authors, so this record says exactly what is promised.
Decision
1. What API version 1 is
Plugin API version 1 is what Writing plugins documents:
- The types a plugin uses, exported from
smaltdb/engine:SmaltPlugin,PluginHost,ConnectionTypeSpec,PluginMethod,MethodContext,AskError;FormatReader,FormatRequest,FormatResult,FormatColumn,RandomAccessFile;SourceHandler,SourceTarget,SourceContext,OpenedFile,RandomFile,ListedFile;SqlValue,StaticTypeandZone, as far as these types use them;- the constant
PLUGIN_API_VERSION.
- The behaviour those pages describe:
- when
setupruns and what the registration methods accept and refuse; - how the engine calls formats and sources, including
pushdown, patterns, validators and thewholeFileMayHelpretry; - how errors map to codes: a plain
ErrorbecomesSMALT_EXTERNAL, aSMALT_…code is kept, andAbortErrorbecomesSMALT_INTERRUPT; askand itsAskErrorreasons;onSessionClosedordering.
- when
- The application side of plugins:
Database.open(…, { plugins }),Database.openMemory({ plugins })andserve({ plugins });db.plugins;callPlugin(plugin, method, args, options)andonPluginMessage(plugin, handler)on the clientDatabase, andcallPluginon the engineDatabase.
Not part of it:
- the engine's internals and the worker protocol between client and engine worker, which are always the same smaltdb version;
- the
smaltdb-src/...imports that our plugins' tests use.
MethodContext.db is the engine Database. Its own API is the public smaltdb/engine API and follows smaltdb's versioning, not this record.
2. How version 1 may change
Within version 1, changes are additive only:
- New optional members may be added to the interfaces a plugin implements (
SmaltPlugin,FormatReader,SourceHandler,OpenedFile,RandomFile,ConnectionTypeSpec), and new fields to what the engine passes in (FormatRequest,SourceContext,MethodContext). A plugin that ignores them keeps working. - New members may be added to
PluginHost, and new options tocallPlugin. - Not allowed within version 1:
- making an optional member required;
- removing or renaming a member;
- changing a member's type in a way existing plugins can't accept;
- changing documented behaviour.
- One exception: a new
AskErrorreason or a new value in another string union a plugin only reads. A plugin should treat an unknown value like'failed'or ignore it, and the reference says so.
Anything else is a new API version:
PLUGIN_API_VERSIONbecomes 2, and a new ADR records why.- The release notes say what plugins must change.
- An engine that implements version 2 says which versions it still accepts. It refuses others with
SMALT_MISUSE, naming both versions, as it does today.
test/plugin-api.test.ts holds a version 1 plugin that implements only the required members and uses every PluginHost member. It type-checks in CI, so a change that would break a version 1 plugin fails it.
3. Releases and peer dependencies
Unchanged from ADR 0012:
- Core and smaltdb's own plugins are released together with the same version number.
- Each plugin's peer dependency on
smaltdbstays limited to the minor version (>=0.9.0 <0.10.0).
A wider range, which would let a plugin outlive several smaltdb minors, is possible later without changing this record's promise. It is the owner's call when publishing.
Consequences
- For plugin authors: the reference is a stable contract. "Not stable yet" notes leave the docs.
- For us: a change to the plugin interface now needs a decision: additive within version 1, or a new version. A change needed by one of our plugins still lands in smaltdb first (ADR 0012).
- For the plan: ADR 0012's step 6 is done when this is accepted. Next is the pre-publish check (pack smaltdb and the three plugins, run smaltui and smaltbi against them), then the 0.9.0 release.