Skip to content

SDK package layout

The Matrix SDK is not a single package. It is a small constellation of workspace packages, with @open-matrix/core at the centre. Anyone consuming the SDK depends on @open-matrix/core and, in tests, on @matrix/test-utils.

Workspace packages that make up the SDK

Workspace packagePurposeRepo path
@open-matrix/coreHeadless actor base, browser shell, runtime, transports, config resolver, wire types.projects/matrix-3/packages/core/
@matrix/test-utilsTest fixtures: InMemoryBus, daemon harness, NATS harness, port allocator, assertions.projects/matrix-3/packages/test-utils/
@matrix/federationCross-root federation transport. Consumed by core for MatrixActor.invoke().projects/matrix-3/packages/federation/
@omega/coreLISP/CESK runtime used by membrane and dynamic compilation. Consumed by core.projects/omega-refactored/packages/core/

@open-matrix/core declares both @matrix/federation and @omega/core as dependencies (projects/matrix-3/packages/core/package.json:339-345). The browser package nats.ws and @nats-io/nats-core live there too — those are the wire libraries createBrowserNatsTransport and NatsTransport use.

Source tree under packages/core/

projects/matrix-3/packages/core/
├── package.json
├── tsconfig.build.json
├── fix-esm-imports.mjs
├── src/
│   ├── index.ts                       ← root barrel; primary entrypoint
│   ├── _node-compat.ts                ← DOM stubs for Node-side imports
│   ├── core/                          ← headless actor + supervision + identity
│   │   ├── MatrixActor.ts
│   │   ├── RootActor.ts
│   │   ├── Supervision.ts
│   │   ├── ComponentRegistry.ts
│   │   ├── identity/
│   │   ├── messaging/
│   │   ├── security/
│   │   ├── membrane/
│   │   ├── lisp/
│   │   └── composite/
│   ├── framework/                     ← browser-side adapters
│   │   ├── MatrixActorHtmlElement.ts
│   │   ├── ActivityFrame.ts
│   │   ├── PageManifest.ts
│   │   ├── components/
│   │   └── primitive-elements.ts
│   ├── runtime/                       ← MatrixRuntime + DOM strategy + config
│   │   ├── MatrixRuntime.ts
│   │   ├── HeadlessHost.ts
│   │   ├── BrowserDomStrategy.ts
│   │   ├── PackageConfigResolver.ts
│   │   └── ComponentFactory.ts
│   ├── transport/                     ← in-memory + NATS adapters
│   │   ├── InMemoryBroker.ts
│   │   ├── InMemoryTransport.ts
│   │   ├── NatsTransport.ts
│   │   ├── createTransport.ts
│   │   ├── createBrowserNatsTransport.ts
│   │   ├── TransportProxy.ts
│   │   └── FederationTransportAdapter.ts
│   ├── engine/                        ← message bus, mailbox, request/reply
│   │   ├── core/                      (IMatrixContext, MatrixContext, Lifecycle)
│   │   ├── messaging/                 (TopicRouter, MxEnvelope, LamportClock)
│   │   ├── mailbox/                   (IMailbox, MailboxFactory)
│   │   ├── remoting/                  (RequestReply, RemoteProxy, ITransportAdapter)
│   │   ├── reflection/                (IInterfaceDescriptor)
│   │   └── utils/                     (NameUtils.toHandlerCase)
│   ├── flow/                          ← FlowBuilder, FlowEngine
│   ├── lisp/                          ← LISP-on-protocol runtime
│   ├── topology/                      ← TopologyBuilder, TopologyDeployer
│   ├── browser/                       ← browser-only helpers
│   ├── middleware/                    ← retry, circuit breaker
│   ├── serialization/                 ← IComponentSchema
│   └── services/                      ← ServiceRegistry
├── dist/                              ← `tsc` output (gitignored)
└── tests/                             ← package-level unit tests

The browser-only modules under src/browser/ and the framework wrappers in src/framework/ are conditionally importable from any environment because the root barrel imports _node-compat first (src/index.ts:5), which provides DOM stubs for Node so class extends HTMLElement does not blow up on import.

Build output and dist

@open-matrix/core has a single build script (package.json:325):

bash
tsc -p tsconfig.build.json && node fix-esm-imports.mjs

tsc writes dist/src/**/*.{js,d.ts,d.ts.map} mirroring src/. fix-esm-imports.mjs rewrites relative imports to add the .js extension TypeScript omits but Node ESM requires.

Consumers see this layout via the exports map in package.json:23-324. Highlights:

SubpathConsumer pattern
@open-matrix/coreRoot barrel — most imports go through here.
@open-matrix/core/core/MatrixActorDirect import of MatrixActor.
@open-matrix/core/framework/MatrixActorHtmlElementBrowser shell.
@open-matrix/core/runtime/MatrixRuntimeRuntime class.
@open-matrix/core/transport/InMemoryTransportIn-process bus.
@open-matrix/core/transport/NatsTransportNATS adapter.
@open-matrix/core/runtime/PackageConfigResolverConfig helpers.

The full subpath table is on Core subpath exports.

Consumer pattern

A typical Matrix package depends on the SDK like this:

json
// packages/your-package/package.json
{
  "dependencies": {
    "@open-matrix/core": "workspace:*"
  },
  "devDependencies": {
    "@matrix/test-utils": "workspace:*"
  }
}

Source imports prefer the root barrel for legibility. Deep subpath imports are valid and covered by the exports map; they are useful when bundlers benefit from finer-grained tree-shaking.

ts
// idiomatic
import { MatrixActor, MatrixRuntime, InMemoryTransport, InMemoryBroker } from '@open-matrix/core';

// equivalent, deep imports
import { MatrixActor } from '@open-matrix/core/core/MatrixActor';
import { MatrixRuntime } from '@open-matrix/core/runtime/MatrixRuntime';
import { InMemoryTransport } from '@open-matrix/core/transport/InMemoryTransport';

Note: Cross-package ../../ imports across workspace boundaries are forbidden. See the project-root CLAUDE.md § "Coding standards" #2. Every dependency on the SDK goes through @open-matrix/core's exports.

@matrix/test-utils layout

projects/matrix-3/packages/test-utils/src/
├── index.ts            ← exports surface (see below)
├── InMemoryBus.ts      ← lightweight pub/sub for unit tests
├── BusMiddleware.ts    ← wrap pub/sub with logging/observation
├── daemon-harness.ts   ← start/stop a real Host process for integration tests
├── nats-server.ts      ← spawn nats-server for integration tests
├── nats/               ← NATS-helper scripts
├── test-ports.ts       ← getAvailablePort, uniqueRealm, retry, waitFor
├── file-scan.ts        ← findFilesContainingPattern, countPatternInFile
├── assertions.ts       ← assertActorMounted, assertHttpResponse, assertWithinBudget
├── dom-polyfill.ts     ← minimal DOM polyfill for shell tests
└── setup-dom.ts        ← register polyfill as a Node test hook

Public surface, verbatim from src/index.ts:

ts
export {
  getAvailablePort, getAvailablePorts,
  uniqueRealm, uniqueCorrelationId, uniqueTestDir,
  createTestProject,
  waitFor, retry,
} from './test-ports';

export { InMemoryBus, type Unsub, type BusMeta, type Handler, type IEventBus } from './InMemoryBus';
export { wrapBus, type BusMiddleware, type BusMiddlewareFn, type BusMiddlewareObj } from './BusMiddleware';
export { createDaemonHarness, createNatsHarness, isNatsServerAvailable, type DaemonHarness, type NatsHarness } from './daemon-harness';
export { startNatsServer, resolveNatsBinary, type IRunningNatsServer } from './nats-server';
export { findFilesContainingPattern, countPatternInFile, escapeRegExp, type ScanOptions } from './file-scan';
export { assertActorMounted, assertMessagePublished, assertMessageNotPublished, assertHttpResponse, assertWithinBudget, guardNotNull } from './assertions';

See also

Source: projects/matrix-3/packages/core/package.json:23-324 (exports), projects/matrix-3/packages/core/src/index.ts (root barrel), projects/matrix-3/packages/test-utils/src/index.ts:1-58.