This package helps browser pages exchange messages between a parent window and an iframe with a small postMessage wrapper.
The service performs a three-way handshake before application messages are delivered:
- Parent sends
SYNto the iframe. - Iframe responds with
SYN+ACK. - Parent sends
ACK; both sides can then exchange messages.
The target origin must be explicit. The wildcard origin ("*") is rejected.
npm install iframe-messagingThe package ships compiled JavaScript (connection.js) and type declarations (connection.d.ts), so it works in both JavaScript and TypeScript projects.
import { MessagingService } from "iframe-messaging";
const iframe = document.querySelector<HTMLIFrameElement>("#child-frame");
if (!iframe) {
throw new Error("Missing iframe");
}
const messaging = new MessagingService("https://child.example", iframe);
const handlerId = messaging.addMessageHandler(message => {
console.log("Message from iframe:", message);
});
messaging.postMessage({ type: "parent-ready" });
// Remove handlers when they are no longer needed.
messaging.removeMessageHandler(handlerId);import { MessagingService } from "iframe-messaging";
const messaging = new MessagingService("https://parent.example");
messaging.addMessageHandler(message => {
console.log("Message from parent:", message);
});
messaging.postMessage({ type: "iframe-ready" });| Parameter | Type | Description |
|---|---|---|
target |
string |
Required origin used to send and validate messages. The wildcard "*" is rejected. |
frame |
HTMLIFrameElement |
Optional. When provided, the service acts as the parent window and initiates the handshake with that iframe. When omitted, the service acts as the iframe side and waits for an incoming handshake. |
overrideId |
string |
Optional fixed identifier for the window. A random id is generated when omitted. |
logger |
Logger |
Optional logger that receives diagnostic messages during the handshake and message exchange. |
Registers a handler that receives the data of each incoming application message and returns an id used to remove it later.
Removes a previously registered handler.
Broadcasts data to every initialized channel. Throws if no channel exists or none has finished the handshake.
interface Logger {
log(data: string): void;
}Channels move through the states SYN, SYN+ACK, and ACK. Once a frame accepts the final ACK, it transitions to the terminal FIN state and the channel is ready for application messages.
- Call
postMessageonly after the handshake has completed. - Messages sent before a channel is initialized throw an error.
- Messages whose origin does not match the configured target are rejected.
- Messages with unknown channel tokens are ignored.
npm install # install dependencies
npm test # run the Vitest test suite
npx tsc --noEmit # type-check the source- Added tests for handshake states, timer cleanup, origin validation, unknown tokens, and uninitialized channels.
- Improved reconnect timer cleanup after successful handshakes.
- Tightened message handler typings while keeping the existing API shape.
- Expanded usage documentation.