Appearance
Package metadata
Beyond the runtime contract (entry, components) and the UI contract (webapp), matrix.json carries metadata used by discovery: which environment the package can run in, what execution class it supports, what cross-package contracts it requires, and how its components want to be tagged for the catalog.
This page covers the metadata fields. The full canonical discovery spec lives in WORKSTREAMS/core-and-packaging/MATRIX-DISCOVERY-METADATA-SPEC.md. This page documents what is wired up in code today.
class — package classification
json
"class": "hybrid"Allowed values:
"webapp"— only ships UI; no headless components. Consumed by browser shells."headless"— only ships actors; no UI. Consumed by Host Service runners."hybrid"— both. Most non-trivial packages are hybrid.
The launcher uses class to decide whether to show the package in the app launcher (only webapp and hybrid show tiles). It is informational; the framework does not enforce it.
namespace — bus prefix
json
"namespace": "chat"The mount-prefix every component in components[] lives under. With namespace: "chat" and components: [{ "mount": "conversation" }, { "mount": "identity" }], the actors are reachable at <root>.chat.conversation and <root>.chat.identity.
By convention, namespace matches webapp.appName for hybrid packages so URLs and bus addresses align: /apps/chat/ ↔ chat.* actors.
runtime.environments — where the package can run
json
"runtime": {
"environments": ["browser", "headless-dom", "runtime"]
}Possible values:
| Value | Meaning |
|---|---|
runtime | Node-side runtime supervised by Host Service. |
browser | Loaded directly into a browser tab via the gateway-served HTML. |
headless-dom | Server-side render path with jsdom/synthetic DOM (used by some build pipelines and tests). |
Used by Host Service and the catalog to filter packages by environment when listing. Does not change behaviour at runtime — your runtime.entry either works or it doesn't in a given environment.
runtime.executionClassCompatibility — placement hints
json
"runtime": {
"executionClassCompatibility": [
"shared_host_service",
"dedicated_process",
"container",
"isolate",
"remote_managed_service"
]
}Discovery hint about how the package can be deployed:
| Class | Meaning |
|---|---|
shared_host_service | Runs in the same Node process as other runtimes the Host supervises. Cheapest option. |
dedicated_process | Gets its own Node process. Use when isolation matters. |
container | Runs inside a Docker container (Docker-NPM parity / Worker Cells). |
isolate | Runs in a V8 isolate — lighter than a process, heavier than shared. |
remote_managed_service | Federation: runs on a different Host, reachable over NATS leaf links. |
The supervisor reads the array and decides where to place the runtime when multiple options are valid. Today, most packages declare all five and Host Service defaults to shared_host_service. Production-deployed packages may pin themselves to dedicated_process if they have heavy native dependencies.
consumes[] — required cross-package contracts
json
"consumes": [
{ "contract": "IChatConversationService", "required": true, "bindingKey": "conversation-service" },
{ "contract": "IChatIdentityService", "required": false, "bindingKey": "identity-service" }
]Tells the supervisor: "this package needs an actor implementing each contract." The supervisor may refuse to start a package whose required: true contracts are unsatisfied — today this is informational rather than enforced strictly; tooling reads it to validate package compatibility.
bindingKey is the conventional service key the package will look up from the context (context.getService(bindingKey)).
components[] per-component metadata
json
"components": [
{
"type": "ChatConversationProxy",
"export": "ChatConversationProxy",
"mount": "conversation",
"surface": "headless",
"autoStart": true
}
]| Field | Meaning |
|---|---|
type | Class name (informational). |
export | Named export to import from runtime.entry. |
mount | Mount path under namespace. |
surface | "headless" (Node) or "browser" (custom element). |
autoStart | Whether the runner instantiates this on boot. |
The list is iterated by the runner at startup. Each entry becomes a MatrixActor instance mounted at <root>.<namespace>.<mount>. The component's static accepts/emits declarations make it discoverable via $introspect.
IComponentRuntimeMetadata — runtime-level metadata
When the runner constructs a component, it stitches together metadata from three sources (projects/matrix-3/packages/core/src/runtime/MatrixRuntime.ts:566-596):
static runtimeMetadataon the component class.componentMetadataon the props object passed toruntime.create.- The parent context's inherited metadata.
The shape (projects/matrix-3/packages/core/src/core/composite/IComponentRuntimeMetadata.ts):
ts
interface IComponentRuntimeMetadata {
version?: string;
versionSource?: ComponentVersionSource; // 'undeclared' | 'package' | 'props' | ...
sourceKind?: ComponentSourceKind; // 'runtime-direct' | 'runtime-child' | ...
// additional discovery fields
}The metadata is exported on the context under the COMPONENT_RUNTIME_METADATA key and surfaced through $introspect so callers can know which package and version a mounted actor came from. You usually don't set this manually — the runner derives it from package.json version.
Tying it all together
A discovery query like system.catalog.search({ namespace: "chat", surface: "browser" }) walks the installed packages, reads their manifests, and returns matches. The fields on this page are what determines whether your package shows up.
For a complete discovery walkthrough — what the catalog stores, what the gateway exposes through /api/apps, what package authors should declare — read WORKSTREAMS/core-and-packaging/MATRIX-DISCOVERY-METADATA-SPEC.md.
Status: target state, partially implemented. The discovery spec describes the canonical metadata vocabulary; today,
system.catalog.searchand/api/appscover the common cases, but some advanced fields (capability intents, marketplace pricing onstatic blackboard) are declared in spec and only partially read by code.
See also
- Package manifest — the
class,namespace,runtime.environmentsfields in context. - Runtime entrypoints —
runtime.entry/browserEntry/bootstrapEntry. - App surfaces —
webapp.shells,appName.
Source:
projects/matrix-3/packages/chat/matrix.json:1-164(every metadata field exercised),projects/matrix-3/packages/core/src/runtime/MatrixRuntime.ts:566-603(metadata stitching),projects/matrix-3/packages/core/src/core/composite/IComponentRuntimeMetadata.ts(type),WORKSTREAMS/core-and-packaging/MATRIX-DISCOVERY-METADATA-SPEC.md(canonical spec).