Skip to content

Node-compatible importable API for use in non-Bun environments #95

@mindsocket

Description

@mindsocket

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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions