mountly
Framework components. Any page. On demand.
mountly turns React, Vue, Svelte, and TSRX components into lazy,
HTML-addressable features. Drop them into CMS pages, marketing sites, legacy apps,
partner embeds, or framework migrations without a host-app rewrite. Light DOM is the default;
use shadow: true when you need hard style isolation.
Small core + explicit subpaths.
mountly keeps a small top-level core entry and exposes focused subpath
imports (for example mountly/attach, mountly/elements,
mountly/shadow, mountly/assets). In browser import-map
hosts, map only the subpaths you use.
One primitive. Several high-value jobs.
The core idea is simple: a component becomes a mountable widget, then mountly loads and activates it from plain HTML when the page says it is time. Marketing reuse, strangler-fig migration, island-style UI, and embeds are all applications of the same runtime.
What you keep
- Normal React, Vue, Svelte, or TSRX components
- Existing CMS, static, legacy, or app host pages
- Current routing, query-string state, and deployment model
- Per-widget ownership by the component team
No new component authoring model. No full app rewrite.
What mountly adds
- HTML tags like
<signup-card> - Activation on idle, viewport, click, hover, media, or URL change
- Shadow-DOM style isolation and automatic CSS loading
- Module/data caching, teardown, and prop updates
A small runtime for component delivery, not an app platform.
Where the primitive pays off.
Six ways to say “now”.
A trigger is the signal that moves a feature from idle to preload to
mount. Pick the one that matches user intent — or compose your own with a plugin.
requestIdleCallback to preload during quiet moments.One state machine, five states. The same shape on every framework.
Every feature moves through the same sequence regardless of trigger or framework. You can hook into any phase, abort in flight, and unmount cleanly.
shadow: true).A widget. A feature. A trigger. Three lines you’ll write.
Components stay components. The adapter wraps them as widgets. The host can wire a feature imperatively, or declare it directly as HTML.
import { createWidget } from 'mountly-react';import SignupCard from './SignupCard.tsx';import styles from './SignupCard.css?inline';
// 1. Wrap a component as a framework-agnostic widgetexport default createWidget(SignupCard, { styles });import { createOnDemandFeature } from 'mountly';
// 2. Add the on-demand lifecycle around a widgetconst signup = createOnDemandFeature({ moduleId: 'signup-card', loadModule: () => import('./signup-card.js'), render: ({ mod, container, props }) => mod.mount(container, props),});
// 3. Attach it to a DOM trigger — preload on hover, mount on clicksignup.attach({ trigger: document.querySelector('#cta')!, preloadOn: 'hover', activateOn: 'click',});Styling — CSS is auto-loaded with the module and applied before render. No FOUC. Default light DOM lets the host’s design system reach in; pass
shadow: truefor full isolation.
<signup-card trigger="viewport" props='{"plan":"pro"}'></signup-card>
<script type="module"> import { defineMountlyFeature } from 'mountly';
defineMountlyFeature('/widgets/dist/index.js');</script>Composable with frameworks. Useful where framework boundaries end.
| Approach | Best at | Tradeoff | Complexity |
|---|---|---|---|
| Traditional SPA | One app owns every surface | Poor fit for CMS, legacy, or partner-hosted UI | Low |
| Framework code-splitting | Routes inside a single framework app | Does not standardize HTML drops or host-agnostic lifecycle | Medium |
| Microfrontend orchestrators | Independent apps with org-level ownership | Operationally heavy for component-sized features | High |
| mountly | Component features in any HTML page | Not a router, SSR framework, or control plane | Low |
One runtime, four adapters, one optional design preset.
createWidget(Component, { styles }).mountly-vueVue adapter — same surface, createApp under the hood.mountly-svelteSvelte adapter — auto-detects v4 class API and v5 functional API.mountly-tailwindOptional Tailwind v4 design preset. Tokens shared with the runtime.