Appearance
Matrix SDK
Motivation
Authoring a Matrix actor is a contract, not just a class. The SDK exists so that every package in this stack arrives with the same shape: a typed declaration of what it accepts, emits, and streams; a manifest the runtime can load without guessing; and a small set of invariants — credentials only through Factotum, one mailbox per actor, additive-only schema evolution — that keep the substrate composable as it grows. These docs are for anyone building a package, whether for personal use, for HiveCast, or for publication to a wider audience. The payoff for following the contract is concrete: every actor that earns it becomes discoverable, addressable, and reusable by every other actor on the bus, including agents that did not exist when you wrote it.
What this is and why
The Matrix SDK is the package every Matrix package depends on. It ships the actor base class, the browser element wrapper, the runtime, the transports, the configuration resolver, and the wire-format types.
If Matrix is docker-for-actors / npm-for-actors, this SDK is the toolkit you use to author the images. You write a package — matrix.json plus a TypeScript bundle — and the substrate (docs-matrix, docs-runtime-host, docs-hivecast) does the rest: load it into a Runtime, mount its actors at typed addresses, route requests, project it into the registry, expose it through every protocol gateway.
The shipping artifact is @open-matrix/core (private workspace package, semver 0.1.x). Test fixtures live in @matrix/test-utils. Both are consumed via the workspace protocol — there is no published npm tarball for either today.
Source: the substrate framing (docker-for-actors, packages-as-images, DeploymentInstance-as-container) is normative in
WORKSTREAMS/thesis/THESIS.mdPart 1 andP1.40. The SDK implements the package-author side of that contract.
Where this fits
This is substrate-side developer documentation. It explains how to build a Package; it does not explain how to operate a Host, run a HiveCast account, or use any of the verticals (Chat, Director, FlowPad).
| Layer | Owned by |
|---|---|
| Protocol contract (bus, addressing, registry, security) | docs-matrix |
| Author the package (this SDK) | docs-sdk |
| Operate the Host that runs your package | docs-runtime-host, docs-edge |
| Author → publish → install → run lifecycle | docs-package-lifecycle |
| Registry, catalog, install resolution | docs-registry |
| The HiveCast product on top | docs-hivecast |
Five-minute quickstart
Build the smallest possible Matrix package: one MatrixActor subclass exposed at one mount.
ts
// src/runtime/HelloActor.ts
import { MatrixActor } from '@open-matrix/core';
export class HelloActor extends MatrixActor {
static accepts = {
'hello.greet': {
description: 'Reply with a greeting addressed to the supplied name.',
schema: { name: { type: 'string', description: 'Person to greet' } },
returns: { greeting: { type: 'string', description: 'Polite hello' } },
},
};
async onHelloGreet(payload: { name: string }) {
return { greeting: `Hello, ${payload.name}!` };
}
}json
// matrix.json
{
"name": "@my-org/hello",
"version": "0.1.0",
"description": "Smallest possible Matrix package.",
"runtime": {
"language": "typescript",
"entry": "./dist/runtime/index.js",
"isolation": "shared"
},
"instance": {
"defaultMount": "hello",
"factory": "createHelloInstance",
"singleton": false
},
"components": [
{
"type": "HelloActor",
"export": "HelloActor",
"relativeMount": "",
"accepts": { "hello.greet": { "description": "..." } }
}
]
}Status: target state — ships in v1. The single-source
matrix.jsonwithruntime.isolation,instance.{defaultMount,factory,singleton}, and per-componentrelativeMountis the v1 manifest spec fromP1.41. Today many packages still carry bothmatrix.jsonandmatrix.service.json, with the bootstrap reading the latter; the migration is in flight. Look atprojects/matrix-3/packages/director/matrix.jsonandprojects/matrix-3/packages/chat/matrix.jsonfor what is actually wired right now, and at Package manifest for the complete current-vs-target field map.
Run it locally through mx-cli (no DeploymentInstance shape yet — uses the default mount):
bash
pnpm --filter @matrix/mx-cli exec matrix run . --env dev --serve --home /tmp/matrix-home
matrix invoke hello hello.greet '{"name":"world"}'
# → { ok: true, result: { greeting: "Hello, world!" } }Conceptual map
| Section | What you'll find |
|---|---|
| Overview | Where the SDK sits, what's @open-matrix/core and what's not, package layout, stability levels. |
| Actors | Subclassing MatrixActor: the six static declarations, op handler naming convention, emit, sendTo, invoke, sessions, state, testing idioms. |
| Components | MatrixActorHtmlElement, the two browser-component patterns, shadow DOM, packaging a UI. |
| Packages | matrix.json reference, runtime entrypoints, app surfaces, the in-flight manifest reconciliation. |
| Transports | InMemoryTransport (in-process broker), NatsTransport (Node), createBrowserNatsTransport (browser WebSocket + JWT). |
| Configuration | resolveConfiguredPackageConfig: schema, defaults, env/file/service providers, secrets-by-reference, config explain. |
| Testing | Five layers: unit, contract (accepts/emits fidelity), runtime smoke (real Host harness), package-proof (end-to-end), browser (Playwright). |
| Reference | Subpath exports, public API ledger, deprecations, migration guides. |
Audience
- Package authors — building a new Matrix package with
matrix.json, an actor, and a UI component. - App developers — composing existing packages, writing custom components, talking to Matrix actors from the browser.
- Framework contributors — modifying
@open-matrix/coreitself.
Source-code map
projects/matrix-3/packages/core/
├── package.json ← exports surface
├── src/
│ ├── index.ts ← root barrel
│ ├── core/MatrixActor.ts ← headless actor base
│ ├── framework/MatrixActorHtmlElement.ts ← browser adapter
│ ├── framework/ActivityFrame.ts ← $prompt → activity protocol
│ ├── runtime/MatrixRuntime.ts ← unified runtime (headless + browser)
│ ├── runtime/PackageConfigResolver.ts ← env/file/service config
│ ├── runtime/IRuntimeConfig.ts ← runtime config surface
│ ├── transport/InMemoryTransport.ts ← in-process pub/sub broker
│ ├── transport/InMemoryBroker.ts ← shared broker
│ ├── transport/NatsTransport.ts ← NATS adapter (Node + ws)
│ └── transport/createBrowserNatsTransport.ts ← browser ws wiring + JWT
└── tests/ ← unit + integration
projects/matrix-3/packages/test-utils/ ← @matrix/test-utils
├── src/InMemoryBus.ts ← lightweight pub/sub for unit tests
├── src/daemon-harness.ts ← legacy filename; current Host harness lives here
├── src/nats-server.ts ← real-NATS harness
├── src/test-ports.ts ← port allocation, unique roots
├── src/file-scan.ts ← repo grep helpers
└── src/assertions.ts ← actor/HTTP/budget assertionsNote:
@open-matrix/coreis a workspace package ("private": true). It is not published to npm. Every Matrix package consumes it viaworkspace:*. See SDK package layout for the full layout and Core subpath exports for the import surface.
Source-portability contract
Every page in this domain is plain CommonMark + GFM. No MDX, no Vue components, no :::tip admonitions, no VitePress-only line highlights. See PORTABILITY-RULES.md — the same rules that gate docs-hivecast apply here.
Sister docs
docs-matrix— protocol contract your package satisfies.docs-runtime-host— the Host that runs your package.docs-package-lifecycle— author → build → test → publish → install → run end-to-end.docs-omega— Omega Lisp, the in-loop scripting layer your actor can embed via$eval.
Source: Authoritative implementation in
projects/matrix-3/packages/core/src/. Public surface defined byprojects/matrix-3/packages/core/package.jsonexports.