{"id":13548010,"url":"https://github.com/dollarshaveclub/postmate","last_synced_at":"2025-05-14T11:08:50.821Z","repository":{"id":10159899,"uuid":"64686622","full_name":"dollarshaveclub/postmate","owner":"dollarshaveclub","description":"📭 A powerful, simple, promise-based postMessage library.","archived":false,"fork":false,"pushed_at":"2023-06-02T12:27:05.000Z","size":1693,"stargazers_count":1898,"open_issues_count":55,"forks_count":185,"subscribers_count":46,"default_branch":"master","last_synced_at":"2025-05-12T17:22:06.880Z","etag":null,"topics":["communicate","handshake","iframe","postmessage","promise","secure","simple"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dollarshaveclub.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null}},"created_at":"2016-08-01T17:16:06.000Z","updated_at":"2025-05-10T19:36:27.000Z","dependencies_parsed_at":"2022-07-09T04:17:02.512Z","dependency_job_id":"9dc08921-b59a-47ad-9899-f8c6cea1d461","html_url":"https://github.com/dollarshaveclub/postmate","commit_stats":{"total_commits":170,"total_committers":27,"mean_commits":6.296296296296297,"dds":0.5882352941176471,"last_synced_commit":"f267096b59d469757932dd14c41f72b5c3341413"},"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dollarshaveclub%2Fpostmate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dollarshaveclub%2Fpostmate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dollarshaveclub%2Fpostmate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dollarshaveclub%2Fpostmate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dollarshaveclub","download_url":"https://codeload.github.com/dollarshaveclub/postmate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254010790,"owners_count":21998993,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["communicate","handshake","iframe","postmessage","promise","secure","simple"],"created_at":"2024-08-01T12:01:04.515Z","updated_at":"2025-05-14T11:08:50.766Z","avatar_url":"https://github.com/dollarshaveclub.png","language":"JavaScript","funding_links":[],"categories":["awesome-web-storage [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome)","JavaScript"],"sub_categories":["Comparison Table"],"readme":"\u003ca href=\"https://github.com/dollarshaveclub/postmate\"\u003e\n  \u003cimg src=\"https://dollarshaveclub.github.io/postmate/assets/postmate-v3.svg\"\u003e\n\u003c/a\u003e\n\n\u003e A powerful, simple, promise-based `postMessage` iFrame communication library.\n\n[![npm][npm-image]][npm-url]\n[![CircleCI](https://circleci.com/gh/dollarshaveclub/postmate.svg?style=svg)](https://circleci.com/gh/dollarshaveclub/postmate)\n[![Share](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/home?status=Postmate%3A%20A%20powerful,%20simple,%20promise-based%20postMessage%20library%20https%3A//github.com/dollarshaveclub/postmate%20via%20%40DSCEngineering%20%40javascript)\n\n[npm-image]: https://badge.fury.io/js/postmate.svg\n[npm-url]: https://www.npmjs.com/package/postmate\n\n_Postmate_ is a promise-based API built on `postMessage`. It allows a parent page to speak with a child `iFrame` across origins with minimal effort.\n\nYou can download the compiled javascript directly [here](/build/postmate.min.js)\n\n* [Features](#features)\n* [Installing](#installing)\n* [Glossary](#glossary)\n* [Usage](#usage)\n* [API](#api)\n* [Troubleshooting/FAQ](#troubleshootingfaq)\n* [License](#license)\n\n***\n\n## Features\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/dollarshaveclub/postmate.svg)](https://greenkeeper.io/)\n* Promise-based API for elegant and simple communication.\n* Secure two-way parent \u003c-\u003e child handshake, with message validation.\n* Child exposes a retrievable `model` object that the parent can access.\n* Child emits events that the parent can listen to.\n* Parent can `call` functions within a `child`\n* *Zero* dependencies. Provide your own polyfill or abstraction for the `Promise` API if needed.\n* Lightweight, weighing in at ~ \u003cspan class=\"size\"\u003e`1.6kb`\u003c/span\u003e (minified \u0026 gzipped).\n\nNOTE: While the underlying mechanism is [window.postMessage()](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage), only iFrame is supported.\n\n## Installing\nPostmate can be installed via NPM.\n\n**NPM**\n```bash\n$ yarn add postmate # Install via Yarn\n```\n\n```bash\n$ npm i postmate --save # Install via NPM\n```\n\n## Glossary\n* **`Parent`**: The **top level** page that will embed an `iFrame`, creating a `Child`.\n* **`Child`**: The **bottom level** page loaded within the `iFrame`.\n* **`Model`**: The object that the `Child` exposes to the `Parent`.\n* **`Handshake`**: The process by which the parent frame identifies itself to the child, and vice versa. When a handshake is complete, the two contexts have bound their event listeners and identified one another.\n\n## Usage\n1. The `Parent` begins communication with the `Child`. A handshake is sent, the `Child` responds with a handshake reply, finishing `Parent`/`Child` initialization. The two are bound and ready to communicate securely.\n\n2. The `Parent` fetches values from the `Child` by property name. The `Child` can emit messages to the parent. The `Parent` can `call` functions in the `Child` `Model`.\n\n***\n### Example\n\n**parent.com**\n```javascript\n// Kick off the handshake with the iFrame\nconst handshake = new Postmate({\n  container: document.getElementById('some-div'), // Element to inject frame into\n  url: 'http://child.com/page.html', // Page to load, must have postmate.js. This will also be the origin used for communication.\n  name: 'my-iframe-name', // Set Iframe name attribute. Useful to get `window.name` in the child.\n  classListArray: [\"myClass\"] //Classes to add to the iframe via classList, useful for styling.\n});\n\n// When parent \u003c-\u003e child handshake is complete, data may be requested from the child\nhandshake.then(child =\u003e {\n\n  // Fetch the height property in child.html and set it to the iFrames height\n  child.get('height')\n    .then(height =\u003e child.frame.style.height = `${height}px`);\n\n  // Listen to a particular event from the child\n  child.on('some-event', data =\u003e console.log(data)); // Logs \"Hello, World!\"\n});\n```\n\n**child.com/page.html**\n```javascript\nconst handshake = new Postmate.Model({\n  // Expose your model to the Parent. Property values may be functions, promises, or regular values\n  height: () =\u003e document.height || document.body.offsetHeight\n});\n\n// When parent \u003c-\u003e child handshake is complete, events may be emitted to the parent\nhandshake.then(parent =\u003e {\n  parent.emit('some-event', 'Hello, World!');\n});\n```\n\n***\n\n## API\n\n\u003e ## `Postmate.debug`\n\n```javascript\n// parent.com or child.com\nPostmate.debug = true;\nnew Postmate(options);\n```\n\n| Name | Type | Description | Default |\n| --- | --- | --- | --- |\n| `debug` | `Boolean` | _Set to `true` to enable logging of additional information_ | `false` |\n\n---\n\n\u003e ## `Postmate.Promise`\n\n```javascript\n// parent.com or child.com\nPostmate.Promise = RSVP.Promise;\nnew Postmate(options);\n```\n\n| Name | Type | Description | Default |\n| --- | --- | --- | --- |\n| `Promise` | `Object` | _Replace the Promise API that Postmate uses_ | `window.Promise` |\n\n---\n\n\u003e ## `Postmate(options)`\n\n```javascript\n// parent.com\nnew Postmate({\n  container: document.body,\n  url: 'http://child.com/',\n  classListArray: [\"myClass\"]\n  model: { foo: 'bar' }\n});\n```\n\n\u003e This is written in the parent page.  Creates an iFrame at the specified `url`. Initiates a connection with the child. Returns a Promise that signals when the handshake is complete and communication is ready to begin.\n\n**Returns**: Promise(child)\n\n#### Properties\n\n| Name | Type | Description | Default |\n| --- | --- | --- | --- |\n| **`container`** (optional) | `DOM Node Element` | _An element to append the iFrame to_ | `document.body`\n**`url`** | `String` | _A URL to load in the iFrame. The origin of this URL will also be used for securing message transport_ | none |\n**`classListArray`** | `Array` | _An Array to add classes to the iFrame. Useful for styling_ | none |\n**`model`** | `Object` | _An object literal to represent the default values of the Childs model_ | none |\n\n---\n\n\u003e ## `Postmate.Model(model)`\n\n```javascript\n// child.com\nnew Postmate.Model({\n  // Serializable values\n  foo: \"bar\",\n  // Functions\n  height: () =\u003e document.height || document.body.offsetHeight,\n  // Promises\n  data: fetch(new Request('data.json'))\n});\n```\n\n\u003e This is written in the child page. Calling `Postmate.Model` initiates a handshake request listener from the `Child`. Once the handshake is complete, an event listener is bound to receive requests from the `Parent`. The `Child` model is _extended_ from the `model` provided by the `Parent`.\n\n**Returns**: Promise(handshakeMeta)\n\n#### Parameters\n\n| Name | Type | Description | Default |\n| --- | --- | --- | --- |\n| **`model`** | `Object` | _An object of gettable properties to expose to the parent. Value types may be anything accepted in `postMessage`. Promises may also be set as values or returned from functions._ | `{}` |\n\n---\n\n\u003e ## `child.get(key)`\n\n```javascript\n// parent.com\nnew Postmate({\n  container: document.body,\n  url: 'http://child.com/'\n}).then(child =\u003e {\n  child.get('something').then(value =\u003e console.log(value));\n});\n```\n\n\u003e Retrieves a value by property name from the `Childs` `model` object.\n\n**Returns**: Promise(value)\n\n#### Parameters\n\n| Name | Type | Description |\n| --- | --- | --- |\n| **`key`** | `String` (required) | _The string property to lookup in the childs `model`_ |\n\n---\n\n\u003e ## `child.call(key, data)`\n\n```javascript\n// parent.com\nnew Postmate({\n  container: document.body,\n  url: 'http://child.com/'\n}).then(child =\u003e {\n  child.call('sayHi', 'Hello, World!');\n});\n```\n\n\u003e Calls the function `sayHi` in the `Child` `Model` with the parameter `Hello, World!`\n\n**Returns**: `undefined`\n\n#### Parameters\n\n| Name | Type | Description |\n| --- | --- | --- |\n| **`key`** | `String` (required) | _The string property to lookup in the childs `model`_ |\n| **`data`** | `Mixed` | _The optional data to send to the child function_ |\n\n---\n\n\u003e ## `child.destroy()`\n\n```javascript\n// parent.com\nnew Postmate({\n  container: document.body,\n  url: 'http://child.com/'\n}).then(child =\u003e child.destroy());\n```\n\n\u003e Removes the `iFrame` element and destroys any `message` event listeners\n\n**Returns**: `undefined`\n\n---\n\n\u003e ## `child.frame`\n\n```javascript\nnew Postmate(options).then(child =\u003e {\n  child.get('height')\n    .then(height =\u003e child.frame.style.height = `${height}px`);\n});\n```\n\n\u003e The iFrame Element that the parent is communicating with\n\n## Troubleshooting/FAQ\n\n### General\n#### Why use Promises for an evented API?\n\u003e _Promises provide a clear API for fetching data. Using an evented approach often starts backwards. if the parent wants to know the childs height, the child would need to alert the parent, whereas with Postmate, the Parent will request that information from the child in a synchronous-like manner. The child can emit events to the parent as well, for those other use-cases that still need to be handled._\n\n### Silent Parent/Child\n#### I've enabled logging but the parent or child is not logging everything.\n\u003e _Postmate.debug needs to be set in both the parent and child for each of them to log their respective information_\n\n#### The child does not respond to communication from the Parent\n\u003e _Make sure that you have initialized Postmate.Model in your child page._\n\n### Restrictive Communication\n#### I want to retrieve information from the parent by the child\n\u003e _Postmate (by design) is restrictive in its modes of communication. This enforces a simplistic approach: The parent is responsible for logic contained within the parent, and the child is responsible for logic contained within the child. If you need to retrieve information from parent -\u003e child, consider setting a default `model` in the parent that the child may extend._\n\n#### I want to send messages to the child from the parent\n\u003e _This is specifically what the `call` function is for._\n\n### Security\n#### What is the Handshake and why do I need one?\n\u003e _By default, all `message` events received by any (parent) page can come from any (child) location. This means that the `Parent` must always enforce security within its message event, ensuring that the `child` (origin) is who we expect them to be, that the message is a response from an original request, and that our message is valid. The handshake routine solves this by saving the identities of the child and parent and ensuring that no changes are made to either._\n\n#### How are messages validated?\n\u003e _The origin of the request, the message type, the postMessage mime-type, and in some cases the message response, are all verified against the original data made when the handshake was completed._\n\n## License\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdollarshaveclub%2Fpostmate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdollarshaveclub%2Fpostmate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdollarshaveclub%2Fpostmate/lists"}