npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@launchmystore/app-bridge

v1.0.3

Published

LaunchMyStore App Bridge SDK — postMessage-based communication between app iframes and the LaunchMyStore admin host. Dispatch Toast, Modal, ResourcePicker, TitleBar, NavigationMenu, SessionToken and 15+ other action families.

Downloads

676

Readme

@launchmystore/app-bridge

Vanilla JavaScript / TypeScript SDK for LaunchMyStore apps. Lets your iframe-embedded app communicate with the LMS admin host (toasts, modals, resource pickers, session tokens, redirects, and more) over postMessage.

Framework-agnostic. If you're using React, install @launchmystore/app-bridge-react instead — it wraps this SDK in hooks.

About LaunchMyStore

LaunchMyStore is a multi-tenant e-commerce platform that renders Shopify-compatible Liquid themes and runs a full app ecosystem on top of them. Merchants get a branded storefront on a custom domain; developers ship apps that extend the storefront, checkout, and admin via the same Apps row, OAuth scopes, webhooks, and declarative function manifests. This SDK is the bridge between your app's iframe and the LMS admin shell.

Learn more: launchmystore.io · Docs: docs.launchmystore.io

Installation

npm install @launchmystore/app-bridge

Quick Start

import { createApp, Toast, Modal } from '@launchmystore/app-bridge';

const app = createApp({
  apiKey: 'your-app-api-key',
  host: window.__LMS_HOST__, // base64-encoded admin origin, injected by host
});

// Show a toast
const toast = Toast.create(app, { message: 'Saved!', duration: 3000 });
toast.dispatch(Toast.Action.SHOW);

// Make an authenticated API call
const token = await app.getSessionToken();
const res = await fetch('/api/v1/products.json', {
  headers: { Authorization: `Bearer ${token}` },
});

Core API

createApp(config)

Creates an App instance and starts listening for messages from the host.

const app = createApp({
  apiKey: string,   // your app's API key
  host: string,     // base64-encoded host origin (injected as ?host= query param)
});

app.dispatch(action, payload)

Fire-and-forget message to the host. Returns a message id.

app.dispatch('TOAST_SHOW', { message: 'Hello', duration: 3000 });

app.dispatchAndWait(action, payload)

Dispatch and await the host's response. Rejects on error or after a 10s timeout.

const { selection } = await app.dispatchAndWait('RESOURCE_PICKER_OPEN', {
  resourceType: 'product',
  multiple: true,
});

app.subscribe(action, callback)

Subscribe to broadcast actions from the host (e.g. LIFECYCLE_EVENT, HISTORY_POP). Returns an unsubscribe function.

const unsubscribe = app.subscribe('LIFECYCLE_EVENT', (payload) => {
  console.log('Lifecycle:', payload.event);
});

app.getSessionToken()

Returns a short-lived JWT for authenticated calls to /api/v1/*.

const token = await app.getSessionToken();

app.redirect.dispatch({ url, newContext })

Navigate within the admin shell. Set newContext: true to open in a new tab.

app.redirect.dispatch({ url: '/products' });

app.destroy()

Remove the message listener and clear pending callbacks. Call on unmount.

Available Actions

All actions live under their namespaced exports and follow the Action.create(app, options) pattern.

UI

  • Toast — success / error / warning / info notifications
  • Modal — full or sheet modals with primary/secondary actions
  • TitleBar — admin title bar actions + breadcrumbs
  • NavigationMenu — app sidebar menu items
  • ContextualSaveBar — sticky save/discard bar
  • Loading — global loading indicator

Pickers & dialogs

  • ResourcePicker — pick from 11 resource types (product, variant, collection, customer, order, blog, article, page, menu, file, metaobject)
  • LeaveConfirmation — block navigation with a confirm dialog
  • Scanner — barcode / QR code scanner

Navigation & lifecycle

  • Redirect — admin or external navigation
  • History — replace / push state inside the iframe
  • Lifecycle — install / uninstall / app-config events
  • Fullscreen — request / exit fullscreen mode

Data APIs

  • User — current admin user
  • Config — shop config, plan, feature flags
  • Environment — runtime environment info
  • Features — which App Bridge features the host implements
  • SessionToken — JWT for authenticated REST calls
  • RestApi — fetch wrapper that auto-attaches the session token

Browser

  • Print — trigger window.print() on the host
  • Share — Web Share API proxy
  • Clipboard — read/write the system clipboard (must go through host in cross-origin iframes)

Storefront / checkout

  • Cart — read cart state, apply line / metafield changes
  • BuyerJourney — intercept checkout steps (post-purchase, checkout extensions)
  • I18n — locale + translation state

Cross-extension

  • Intents — launch other extensions by intent (e.g. open Reviews extension from Products page)

Examples

Modal with primary action

import { createApp, Modal } from '@launchmystore/app-bridge';

const app = createApp({ apiKey, host });

const modal = Modal.create(app, {
  title: 'Confirm import',
  message: 'Import 1,200 products from Shopify?',
  primaryAction: {
    content: 'Import',
    onAction: async () => {
      await runImport();
      modal.dispatch(Modal.Action.CLOSE);
    },
  },
  secondaryActions: [{ content: 'Cancel' }],
});

modal.dispatch(Modal.Action.OPEN);

Resource picker

import { createApp, ResourcePicker } from '@launchmystore/app-bridge';

const app = createApp({ apiKey, host });

const picker = ResourcePicker.create(app, {
  resourceType: ResourcePicker.ResourceType.Product,
  multiple: true,
});

picker.subscribe(ResourcePicker.Action.SELECT, ({ selection }) => {
  console.log('Picked', selection);
});

picker.dispatch(ResourcePicker.Action.OPEN);

Session token + authenticated fetch

import { createApp } from '@launchmystore/app-bridge';

const app = createApp({ apiKey, host });

async function authedFetch(path, init = {}) {
  const token = await app.getSessionToken();
  return fetch(path, {
    ...init,
    headers: { ...(init.headers || {}), Authorization: `Bearer ${token}` },
  });
}

const res = await authedFetch('/api/v1/orders.json');
const { orders } = await res.json();

Contextual save bar

import { createApp, ContextualSaveBar } from '@launchmystore/app-bridge';

const app = createApp({ apiKey, host });
const saveBar = ContextualSaveBar.create(app, {
  saveAction: { onAction: handleSave },
  discardAction: { onAction: handleDiscard },
});

function onFormDirty() {
  saveBar.dispatch(ContextualSaveBar.Action.SHOW);
}
function onFormClean() {
  saveBar.dispatch(ContextualSaveBar.Action.HIDE);
}

TypeScript

Full type definitions ship with the package — no @types/* install required.

import type {
  AppConfig,
  AppBridgeMessage,
  AppBridgeResponse,
  ToastOptions,
  ModalOptions,
  ResourcePickerOptions,
  ResourceType,
} from '@launchmystore/app-bridge';

Wire format

Iframe → host:

{ "type": "APP_BRIDGE_ACTION", "action": "TOAST_SHOW", "id": "ab_…", "payload": { … } }

Host → iframe:

{ "type": "APP_BRIDGE_RESPONSE", "action": "TOAST_SHOW", "id": "ab_…", "payload": { … } }

The host validates event.origin against the registered redirect URLs; the SDK validates event.origin against the decoded host config.

License

MIT