Browser use

Native modules or one global.

Choose standards-first ES modules for new work, or keep an existing script-tag integration with the supported browser-global file.

Native ES modules

js-message works with bundlers and without a bundler.

Bundlers resolve the bare js-message import normally. Native browser ESM resolves it through a standard import map, with no build or transpilation step.

<script type="importmap">
{
  "imports": {
    "js-message": "./node_modules/js-message/index.js",
    "js-message/": "./node_modules/js-message/"
  }
}
</script>
<script type="module">
    import Message from 'js-message';

    const ready = new Message({
        type: 'page.ready',
        data: { path: location.pathname }
    });

    console.log(ready.JSON);
</script>

This map is complete because js-message has zero runtime dependencies, so it needs no dependency or scope entries. The paths are relative to the HTML document. Serve the app over HTTP(S), and configure the server to expose these node_modules files; file:// is not supported.

Browser-global entry

<script src="./node_modules/js-message/js-message-vanilla.js"></script>
<script>
    const message = new Message();
    message.type = 'legacy.ready';
    message.data = { ok: true };
</script>

The side-effect file assigns the class to globalThis.Message. It is behaviorally tested against the module class, including object and JSON loading, optional fields, malformed-input recovery, and serializable errors.

Use a closing script tag.

HTML script elements are not self-closing. The explicit </script> prevents the browser from treating later markup as script content.

WebSockets and workers

const socket = new WebSocket(url);

socket.addEventListener('message', (event) => {
    const message = new Message(event.data);

    if (message.type === 'error') {
        console.error(message.data.err);
        return;
    }

    dispatch(message.type, message.data);
});

In a worker, use the ES-module entry or load the global file through your existing worker strategy. The global entry targets globalThis, not only window.