Migration to v3

Keep the path. Gain a contract.

Version 3 preserves the established imports and mutable message surface while making object input, invalid shapes, and error serialization explicit.

Version 3.0.0 is available on npm.

Install it with npm install js-message. Review the stricter envelope validation and browser-global descriptor changes below before upgrading an existing integration.

What stays compatible

  • import Message from 'js-message' remains the canonical package import.
  • js-message/Message.js remains a supported deep ES-module path.
  • js-message/js-message-vanilla.js still creates globalThis.Message.
  • type and data remain mutable, enumerable instance fields.
  • JSON remains a getter and load() still returns undefined.
  • Buffer, boxed-string, typed-view, and custom JSON-coercible text inputs remain accepted.
  • The declared Node.js engine floor remains >=13.2.0.

What becomes stricter

Earlier behaviorModernized behavior
Valid JSON such as {}, [], or 0 could silently leave fields undefined.Any value without an own type and data pair becomes an error envelope.
The browser global and ES-module implementations could drift.Both surfaces share the same tested contract and recovery behavior.
Serialized native errors collapsed to {}.Error JSON exposes stable name and message fields while the live value remains an Error.
The browser-global script installed own JSON and load properties.They are non-enumerable prototype members, matching the ES-module class. Native JSON.stringify() now uses the normalized two-key envelope.
Audit code that relied on incomplete envelopes.

If your receiver intentionally sent objects without both keys, add the missing key or branch on message.type === 'error'.

An invalid cyclic or BigInt response is retained for debugging. Native serialization can still throw while that response is present; the error object itself remains serializable.

New supported conveniences

const fromObject = new Message({
    type: 'ready',
    data: { ok: true }
});

const fromJSON = new Message(
    '{"type":"ready","data":{"ok":true}}'
);

JSON.stringify(fromObject) === fromObject.JSON; // true

Constructor input, object loading, and toJSON() make js-message fit both text and structured-clone transports without replacing its original API.