Appearance
Configuration
Every non-trivial Matrix package needs configuration: log levels, feature flags, default models, cache sizes, timeouts, references to credentials. The SDK provides a layered resolver — resolveConfiguredPackageConfig — that merges defaults with environment, file, and service overlays. This section is the field guide.
Pages in this section
| Page | What you'll learn |
|---|---|
| Config schema | The JSON Schema declaration in matrix.json and how it drives validation/explain tooling. |
| Defaults | The config.defaults JSON file — what to put in it and what NOT to. |
| Overrides | The four overlay layers: env → file → service → caller-overrides. |
| Secrets references | Why credentials never go in config.defaults, and the Factotum boundary. |
| Config explain | matrix config explain <package> — debugging which value came from which layer. |
The mental model
defaults (in package)
↓ deep-merge
profile (caller-supplied)
↓ deep-merge
provider 1 (e.g., env vars)
↓ deep-merge
provider 2 (e.g., file)
↓ deep-merge
provider 3 (e.g., system.config)
↓ deep-merge
overrides (caller-supplied last)
= effective configEach layer is a DeepPartial<TConfig>. The merge is recursive on objects but replaces arrays and primitives wholesale. The order is fixed: defaults → profile → providers (in declaration order) → overrides.
The function
ts
import { resolveConfiguredPackageConfig } from '@open-matrix/core';
const config = await resolveConfiguredPackageConfig<MyConfig>({
defaults, // required
contract: matrixJson.config, // optional
profile: { logLevel: 'debug' }, // optional
overrides: { auth: { provider: 'google' } }, // optional
packageName: '@open-matrix/my-package',
options: {
context, // for system.config service
env: process.env,
loadFileConfig: async (path) => readJson(path),
realm: 'COM.EXAMPLE',
timeoutMs: 5000,
},
});The function is async because service providers may issue RPCs. With only env-vars and a defaults JSON, the resolution is effectively synchronous.
Conventional layout in a package
packages/my-package/
├── matrix.json # references config/* paths
├── config/
│ ├── config.schema.json # JSON Schema
│ └── config.defaults.json # baked-in defaults
└── src/
└── runtime/
└── load-config.ts # calls resolveConfiguredPackageConfigMost packages do not need a config block — single-purpose actors with no tunables ship without one. Reach for the resolver only when configuration actually exists.
See also
- Package config contract — the
configblock inmatrix.json. - Package manifest — every other field around
config.
Source:
projects/matrix-3/packages/core/src/runtime/PackageConfigResolver.ts:1-349.