DEV Community

Cover image for Common Third-Party GUI Integration Patterns
Samuel Ruiz
Samuel Ruiz

Posted on • Edited on

Common Third-Party GUI Integration Patterns

At some point, almost every product needs to embed or integrate a third-party UI: payments, analytics, scheduling, support widgets, internal tools, or partner features.

There are four common patterns, each with very different tradeoffs around security, UX, ownership, and complexity:

  1. 🧱 Iframe embed
  2. πŸ“œ Script tag / JavaScript SDK
  3. πŸ“¦ NPM package / component library
  4. 🧬 Micro-frontend (MFE)

Choosing the wrong one early can lock you into painful rewrites later.


⚑ Quick Decision Guide

  • πŸ›‘οΈ Safest, fastest β€œjust embed it” β†’ Iframe
  • ⚠️ Quick integration + tight UX (accepts global JS risk) β†’ Script tag / JS SDK
  • 🎯 Best UX + full control + shared design system β†’ NPM package
  • πŸ—οΈ Independent deploys + large teams β†’ Micro-frontend (MFE)

If you’re unsure, start with iframe. You can always move down the listβ€”but moving up is expensive.


🧱 1. Iframe Embed

πŸ” What it is

You render third-party UI inside an <iframe> pointing to a URL hosted by the vendor (or another internal team).

The iframe runs in a separate browsing context, isolated from your app’s JS and CSS.


πŸ’» Basic Example

<iframe
  src="https://vendor.example.com/widget?tenant=acme"
  title="Vendor Widget"
  width="100%"
  height="700"
  loading="lazy"
  style="border:0; border-radius:12px;"
></iframe>
Enter fullscreen mode Exit fullscreen mode

πŸ” Secure Sandbox Example

<iframe
  src="https://vendor.example.com/widget?tenant=acme"
  title="Vendor Widget"
  width="100%"
  height="700"
  sandbox="allow-scripts allow-forms allow-popups"
  allow="clipboard-read; clipboard-write"
  style="border:0;"
></iframe>
Enter fullscreen mode Exit fullscreen mode

πŸ” Parent ↔ Child Communication (postMessage)

Parent

const iframe = document.getElementById("vendor-iframe") as HTMLIFrameElement;

window.addEventListener("message", (event) => {
  if (event.origin !== "https://vendor.example.com") return;

  if (event.data?.type === "READY") {
    iframe.contentWindow?.postMessage(
      { type: "SET_THEME", theme: "dark" },
      "https://vendor.example.com"
    );
  }
});
Enter fullscreen mode Exit fullscreen mode

Child

window.parent.postMessage(
  { type: "READY" },
  "https://host.example.com"
);
Enter fullscreen mode Exit fullscreen mode

βœ… Pros

  • πŸ›‘οΈ Strong isolation (security, CSS, JS)
  • πŸ”„ Easy rollback
  • πŸš€ Vendor deploys independently

❌ Cons

  • 🎨 Styling consistency is harder
  • πŸ” Requires postMessage plumbing
  • πŸ” SEO & accessibility limitations

🎯 Use when

  • Vendor is untrusted
  • Security > UX polish
  • You want minimal blast radius

πŸ“œ 2. Script Tag / JavaScript SDK

πŸ” What it is

A vendor-hosted script injects UI or exposes a global SDK that runs inside your app’s origin.


πŸ’» HTML Example

<div id="vendor-root"></div>

<script src="https://cdn.vendor.com/widget/v1/widget.min.js"></script>
<script>
  VendorWidget.mount("#vendor-root", {
    tenant: "acme",
    theme: "light",
  });
</script>
Enter fullscreen mode Exit fullscreen mode

βš›οΈ React Wrapper Example

import { useEffect, useRef } from "react";

export function VendorWidget({ tenant }: { tenant: string }) {
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const instance = (window as any).VendorWidget.mount(ref.current, { tenant });
    return () => instance?.unmount?.();
  }, [tenant]);

  return <div ref={ref} />;
}
Enter fullscreen mode Exit fullscreen mode

βœ… Pros

  • 🎯 Better UX than iframe
  • ⚑ Fast integration
  • 🧩 No build-time dependency

❌ Cons (Real Risks)

  • ☠️ Executes untrusted JS in your origin
  • 🎨 CSS / global JS conflicts
  • 🐞 Painful debugging
  • πŸ“¦ CDN version drift

πŸ›‘οΈ Required Safety Measures

  • πŸ”’ Pin exact versions
  • 🧾 Use SRI
  • 🚧 Lock down CSP
  • 🧩 Demand namespaced CSS or Shadow DOM

🎯 Use when

  • Vendor is trusted
  • Widget is small
  • Speed matters more than isolation

πŸ“¦ 3. NPM Package / Component Library

πŸ” What it is

You install the vendor UI as a dependency and render it directly.

This gives the best UXβ€”and the most responsibility.


πŸ“₯ Install

npm install @vendor/ui @vendor/sdk
Enter fullscreen mode Exit fullscreen mode

βš›οΈ React Example

import { VendorCheckout } from "@vendor/ui";

export function Checkout() {
  return (
    <VendorCheckout
      customerId="cust_123"
      theme="light"
      onSuccess={(result) => console.log(result)}
    />
  );
}
Enter fullscreen mode Exit fullscreen mode

βœ… Pros

  • πŸ† Best UX
  • πŸ§ͺ Fully testable
  • πŸ”’ Explicit version control
  • 🎨 Design system alignment

❌ Cons

  • πŸ“¦ Bundle size impact
  • πŸ”— Dependency conflicts
  • πŸ’₯ Vendor bugs can break builds
  • 🚫 No isolation

🧠 Best Practices

  • πŸ”’ Pin versions
  • ⏳ Lazy-load heavy UI
  • 🧱 Wrap with adapter components

🎯 Use when

  • UI is core to your product
  • You own UX decisions
  • You accept upgrade ownership

🧬 4. Micro-Frontend (MFE)

πŸ” What it is

A separately built and deployed frontend loaded at runtime.


πŸ—οΈ Host Loader Example

async function loadRemote(url: string) {
  await new Promise<void>((resolve) => {
    const s = document.createElement("script");
    s.src = url;
    s.onload = () => resolve();
    document.head.appendChild(s);
  });

  return (window as any).RemoteApp;
}
Enter fullscreen mode Exit fullscreen mode

πŸ”Œ Remote App Contract

export function mount(el: Element, opts: { tenant: string }) {
  return { unmount() {} };
}

(window as any).RemoteApp = { mount };
Enter fullscreen mode Exit fullscreen mode

βœ… Pros

  • πŸš€ Independent deploys
  • πŸ§‘β€πŸ€β€πŸ§‘ Team scalability
  • πŸ”„ Shared runtimes

❌ Cons

  • 🧠 High complexity
  • πŸ”— Version coordination pain
  • 🐒 Slower local dev

🎯 Use when

  • Multiple teams
  • Independent release cycles
  • Large UI surface area

πŸ“Š Comparison Table

Pattern Isolation UX Complexity Risk
🧱 Iframe High Medium Low Low
πŸ“œ Script SDK Low High Low Medium–High
πŸ“¦ NPM Library Low Very High Medium Medium
🧬 MFE Medium High High Medium

⚠️ Critical Engineering Concerns

πŸ” Authentication

  • Avoid long-lived tokens in URLs
  • Prefer short-lived sessions
  • Never expose secrets to iframes

🎨 Styling

  • Use theme contracts
  • Avoid global CSS
  • Prefer Shadow DOM when possible

⚑ Performance

  • Lazy-load non-critical UI
  • Cache remote assets
  • Watch for duplicate bundles

πŸ›Ÿ Reliability

  • Loading states
  • Timeouts
  • Graceful fallbacks

🧭 Practical Recommendations

  • πŸ›‘οΈ Untrusted vendor β†’ Iframe
  • ⚠️ Trusted widget β†’ Script SDK
  • 🎯 Core UI β†’ NPM library
  • πŸ—οΈ Large org β†’ MFE

Top comments (0)