Motivation
Consumers like the Obsidian plugin currently call sctx validate-file --json as a subprocess. If the core validation logic were importable as a library, they could instead call it directly — no binary install required, no spawn delay, no binary path configuration.
The core validation code is nearly Node-compatible already. Only three Bun-specific APIs are used outside of CLI commands:
| API |
Used in |
Node replacement |
Glob from 'bun' |
read-space.ts, template-sync.ts |
fast-glob or Node 22 glob |
JSON5 from 'bun' |
schema.ts, config.ts, dump.ts |
json5 npm package |
Bun.markdown.render |
docs.ts |
CLI-only, no action needed |
Proposed changes
-
Replace Glob and JSON5 bun imports with Node-compatible equivalents. The runtime behaviour is identical; this just removes the Bun runtime requirement from library consumers.
-
Rename plugin-api to api — the current name implies it's only for sctx plugins, but it's the general public library surface for any consumer.
-
Extend api with runtime exports — currently types-only. At minimum, expose a validateFile(filePath, config) function (or a SpaceValidator class) that returns a FileValidationResult. Config could be passed as an object rather than a path, so callers aren't tied to the filesystem config format.
-
Mark api as external in the CLI esbuild config if needed to avoid bundling the library entrypoint into the CLI binary.
Impact on Obsidian plugin
- Drop the
exec subprocess and binary path setting entirely
- Bundle sctx validation logic directly (or add as a peer dependency)
- Faster, more reliable validation with no spawn overhead
- Vault-local config can be passed as an object, not a file path
Notes
- The Bun CLI build pipeline can continue using Bun APIs in CLI-layer code (commands, scripts). Only the importable library surface needs to be Node-compatible.
tsconfig.build.json already targets Node-compatible output; no structural changes needed.
- This does not require publishing a separate package — the
./plugin-api export path in package.json is already in place.
Motivation
Consumers like the Obsidian plugin currently call
sctx validate-file --jsonas a subprocess. If the core validation logic were importable as a library, they could instead call it directly — no binary install required, no spawn delay, no binary path configuration.The core validation code is nearly Node-compatible already. Only three Bun-specific APIs are used outside of CLI commands:
Globfrom'bun'read-space.ts,template-sync.tsfast-globor Node 22globJSON5from'bun'schema.ts,config.ts,dump.tsjson5npm packageBun.markdown.renderdocs.tsProposed changes
Replace
GlobandJSON5bun imports with Node-compatible equivalents. The runtime behaviour is identical; this just removes the Bun runtime requirement from library consumers.Rename
plugin-apitoapi— the current name implies it's only for sctx plugins, but it's the general public library surface for any consumer.Extend
apiwith runtime exports — currently types-only. At minimum, expose avalidateFile(filePath, config)function (or aSpaceValidatorclass) that returns aFileValidationResult. Config could be passed as an object rather than a path, so callers aren't tied to the filesystem config format.Mark
apiasexternalin the CLI esbuild config if needed to avoid bundling the library entrypoint into the CLI binary.Impact on Obsidian plugin
execsubprocess and binary path setting entirelyNotes
tsconfig.build.jsonalready targets Node-compatible output; no structural changes needed../plugin-apiexport path inpackage.jsonis already in place.