Bundle Format

A deployable Lapis Lazuli bundle is a directory discovered by the runtime under:

plugins/LapisLazuli/bundles/<bundle-id>/

Required Files

Every bundle must contain:

  • lapis-plugin.json
  • the runtime entrypoint referenced by lapis-plugin.json

The default CLI output is:

  • lapis-plugin.json
  • main.js

Manifest Schema

Example:

{
  "id": "hello-ts",
  "name": "Hello TS",
  "version": "0.1.0",
  "engine": "js",
  "main": "main.js",
  "apiVersion": "1.0"
}

Fields

FieldRequiredMeaning
idYesStable bundle identifier
nameYesHuman-readable plugin name
versionYesBundle version string
engineYesRuntime engine key. Supported values are "js", "node", and "python"
mainYesRelative path to the bundle entrypoint
apiVersionYesLapis Lazuli API version marker
dependenciesNoParsed by the manifest model, but not currently enforced
softDependenciesNoParsed by the manifest model, but not currently enforced

Loader Rules

The loader currently enforces:

  • the manifest file must exist
  • the entrypoint file must exist
  • the resolved entrypoint path must stay inside the bundle directory

Unknown JSON fields are ignored by manifest parsing.

Runtime-Owned Paths

The Bukkit adapter also uses these bundle-local paths:

  • config.yml
  • data/

These are created and managed by the runtime host services.

Hot reload ignores config.yml and data/ changes so that plugin persistence does not trigger reload loops.

Packaging Contract

The CLI bundles source projects into the runtime format by:

  1. compiling js and node entrypoints with Bun, or staging Python source files
  2. copying the built JS output to main.js for js and node bundles
  3. rewriting the manifest main field to the runtime entrypoint path

That means authors can keep main pointed at ./src/index.ts in source control while still shipping a runtime-ready bundle.