Skip to content

Quick start

The CLI is the fastest path. It scaffolds a React widget pre-wired with the build pipeline, both bundle outputs, and a working host page.

Not sure mountly is the right tool? Read Choosing an architecture first — most teams should start with a monorepo npm lib, not micro frontends.

Terminal window
npx mountly init my-widget
cd my-widget

You get:

  • src/Component.tsx: a React component (you can swap in Vue or Svelte later).
  • A widget factory using mountly-react’s createWidget.
  • A tsup build that produces both dist/index.js (self-contained) and dist/peer.js (shared React).
  • An example host page.
Terminal window
pnpm install
pnpm build

Two artifacts land in dist/:

  • index.js: self-contained bundle. Includes React. Drop into any page.
  • peer.js: peer build. Excludes React. Use when the host already maps React via an import map.

See Distribution for which one to ship.

host.html
<div id="mount"></div>
<script type="module">
import widget from "./my-widget/dist/index.js";
widget.mount(document.getElementById("mount"));
</script>

The widget mounts inside the container in light DOM and the host’s CSS reaches in. For full style isolation, pass shadow: true to createWidget.

Section titled “3b. Lowest-ceremony host (recommended for plain HTML)”

On a static or CMS host, prefer declarative islands plus one script tag:

host.html
<div
data-mountly-island='{"schemaVersion":1,"id":"signup","moduleId":"signup-card","trigger":"idle","props":{"plan":"pro"}}'
>
<a href="/signup">Sign up (fallback)</a>
</div>
<script
type="module"
src="/packages/mountly/dist/host-entry.js"
data-mountly-host
data-mountly-loaders='{"signup-card":"/widgets/signup-card.js"}'
></script>

This is the default DX path: no host app code, one script tag, and fallback HTML that still works when JS is unavailable.

mount() is the bare minimum. For on-intent loading, wrap the widget in a feature:

page.ts
import { createOnDemandFeature } from "mountly";
const signup = createOnDemandFeature({
moduleId: "signup-card",
moduleUrl: "./my-widget/dist/index.js",
});
signup.attach({
trigger: document.querySelector("#cta")!,
preloadOn: "hover",
activateOn: "click",
});

mountly synthesises the loader and a default render that threads moduleUrl through to the adapter, so it fetches and applies the sibling dist/index.css for you. It fetches the widget code on first hover and mounts it on click. Open DevTools → Network and watch.

For bespoke loading or rendering, loadModule and render are still available and override the auto-derived defaults.

Try the hosted demos — no clone required:

The marketing site shows hover preload, click mount, and viewport-triggered embeds with zero host framework JS before interaction.

Run locally (optional):

Terminal window
git clone https://github.com/jagreehal/mountly
cd mountly
pnpm install && pnpm -r build
cd docs/examples/plain-html && pnpm dev

Then open http://localhost:5175/docs/examples/quickstart/host.html.