Matter.js 0.18.x

This file tracks the matter.js 0.18.0 deltas compared with matter.js 0.17.9 that matter for Matterbridge.

Released version: 0.18.0 (published on npm on October 20, 2026), used by Matterbridge on the dev branch.

Audited dev version: 0.18.0-alpha.0-20261015-9c1725759 (npm dev verified on October 15, 2026). The findings were first audited on 0.18.0-alpha.0-20261008-6066b7499 and rechecked on 0.18.0-alpha.0-20261013-2e5a97ca3, with the full test suite giving the same results on both historical snapshots. The three upstream validation issues reported on that October 13 snapshot are now resolved as recorded below, and the fixes ship in the 0.18.0 release. The audit sections below record the work done on these dev snapshots before the release. Add newly discovered drifts here as the migration progresses.

Validation results

Verified on October 21, 2026, on branch dev with matter.js 0.18.0.

Validation Result
Lint, format, type-check Passed - root and frontend
Full matterbridge Vitest with coverage 3,797 tests passed across 174 files in strict mode
Full frontend Vitest with coverage 608 tests passed across 41 files
Full Bun suite with coverage 1,958 tests passed across 113 files in strict mode
Full chip-test suite 524 conformance tests passed

Renamed commodity fields

The generated CommodityMetering and CommodityTariff types now use Ids instead of IDs in property names.

Previous name 0.18 name
dayEntryIDs dayEntryIds
dayPatternIDs dayPatternIds
tariffComponentIDs tariffComponentIds

This affects metered quantities, tariff periods, days, day patterns, calendar periods, and the GetTariffComponent response. Fixtures, property access, and response expectations must all use the new names.

Inherited device cluster requirements

The audited snapshot includes the inherited Base Binding requirement in device definitions. Matterbridge now includes Binding in the affected Simple device definitions with mandatory application clients.

Open enums typed as Enum | number

The audited snapshot types the fields of enums that reserve ranges for derived clusters and manufacturers as a union with number. Examples:

This follows Matter 1.6.1:

A device can therefore report a value that is not a member of the base enum.

The type-aware lint rule typescript/no-unsafe-enum-comparison now flags every direct comparison of these fields with an enum member, such as state.operationalState === OperationalState.OperationalStateEnum.Paused or tag.value === RvcRunMode.ModeTag.Idle, and the case labels of a switch on them. The rule stays on: the source widens the member to number instead, state.operationalState === (OperationalState.OperationalStateEnum.Paused as number), which keeps the comparison correct for vendor and derived values.

Endpoint device type validation

matter.js 0.18 adds server-side validation of endpoints against their declared device types and the inherited Base requirements (Matter 1.6.1 Core §9.2). It checks mandatory and disallowed clusters, required server-cluster features and elements, component endpoint counts and requirements, singleton placement, and explicitly supplied condition names. Client clusters are checked for presence only; remote ClientNode peers are not validated.

The endpoint.validation variable, also available as MATTER_ENDPOINT_VALIDATION, selects the mode:

Mode During construction Automatic checks after construction
warn (upstream default) Reject new misplaced singletons; warn about other new violations. Log and record violations without rejecting changes.
strict Reject any new device type violation. Log and record violations without rejecting changes.
off Only retain the early check for misplaced singletons declared by ancestor endpoints. Disabled.

Matterbridge sets warn in production and strict in the test helpers before creating server nodes:

For explicit checks, obtain DeviceTypeConformanceService from the node's environment and call validate() or validateNodeScope(). Use { refuse: false } to report violations without throwing a conformance error. Explicit validation also works in off mode, but does not record results there.

Migration implication: endpoint definitions and test fixtures must satisfy their advertised device types, and mandatory command stubs can now prevent initialization. strict is not continuous enforcement of every runtime mutation.

See the upstream Device Type Validation documentation for the full rules and limitations.

Resolved upstream validation issues

All three points reported in matter-js/matter.js#4744 were fixed by the following PRs, both merged on October 13, 2026. The fixes are present in the 0.18.0 release.

Issue point Resolution Upstream PR
1. Utility components on the composing endpoint A utility device type listed on the composing endpoint counts as a component instance and is checked against that endpoint's clusters. This supports the Heat Pump, Solar Power, Battery Storage and Electrical Meter layouts. matter-js/matter.js#4745
2. Root Node conditions blocking strict validation Violations caused only by Root assertions are flagged assertedAtRoot, log at debug level and never refuse endpoints. This covers the camera-family, Intercom, meter and Groupcast conditions without weakening other strict checks. matter-js/matter.js#4746
3. Non-serializable conformance errors DeviceTypeViolationError.endpoint is now a getter backed by a private field, not an own enumerable property, so serializers that copy only own properties no longer traverse the node graph. See the note below. matter-js/matter.js#4745

Point 3 is only partly resolved for tests: Vitest's error serializer also reads getters on the prototype. A DeviceTypeConformanceError that reaches Vitest, as a rejected promise or a rejected construction.ready, still leads through endpoint into the node and the Matter model, whose getters build new objects on each read, and the worker runs out of memory (SIGABRT, no message). Bun reports the failure instead. The tests avoid it by adding devices with addDevice() / addBridgedDevice(), which catch the error, and by keeping the fixtures valid; a toJSON() on the matter.js validation errors would fix it upstream.

The Root-assertion fix removes the validation blocker; it does not implement Time Synchronization, TLS Certificate Management or TLS Client Management. All 18 warning-mode workarounds have been removed from the Vitest and Bun device and behavior test setups, which now use the default strict validation. Tests of the validation-mode option still exercise off and warn, then restore strict before creating the server.

Door lock validation and events

Door-lock tests now use a supported user type when schedule features are disabled, send null UserStatus and UserType when adding credentials to existing users (§5.2.10.20), and assert SetCredential response statuses. These test changes also pass with matter.js 0.17.9.

The audited snapshot reports the user index in LockUserChange.DataIndex for user changes (§5.2.11.5.7), and reports UserIndex 0xFFFE when clearing credentials for all users (§5.2.11.5.4). The corresponding event expectations are specific to 0.18; 0.17.9 reports null for these fields.

Level control On/Off coupling corrected

In 0.17.9, downward MoveWithOnOff supplied an unbounded target (-Infinity) that the coupling logic compared directly with MinLevel, incorrectly taking the turn-on path. The audited 0.18 snapshot clamps the target to the device range and turns the endpoint off when CurrentLevel reaches MinLevel, as required by Matter 1.6.1 Application Cluster §1.6.7.6.

Ordinary Step then has no effect while off unless ExecuteIfOff permits execution (§1.6.4.1.3). The LevelControl test now checks this no-op, then turns the endpoint on before checking that Step increases the level. This test update applies only to matterdev; no Matterbridge server change is needed.