# embedding · static-site integration
Vendor one file, add one script tag, and use your component like a native HTML element. No build pipeline to bolt onto your backend — it just serves static files.
This is a whole page — a paragraph of static HTML with a reactive component dropped in, importing straight from the vendored bundle. Edit it and hit Run.
You already have a page — server-rendered, static, whatever — and you want one reactive widget in it. Here's what the usual options actually cost.
createElement, addEventListener, and re-render it yourself on every change. State and DOM slide out of sync — the classic bug. The Jellyfin modal below was 230 lines of exactly this.
To render one widget you take on npm, a bundler, JSX/SFC compilation and a mount step. Your static page grows a node_modules/, a package.json and a CI build — and rots on the framework's schedule.
Skips your build, but ships a big runtime, usually still wants a compile step for JSX/SFC, and bolts a third-party CDN — its uptime and its supply chain — onto a page that used to be self-contained.
Great for some flows, but now instant local state — a converter, a filter, an inline form — is a network request and a server endpoint away from working.
Vendor a 23 KB file, add a module script, write declarative reactive components — the demo above is the whole thing. No npm, no bundler, no CDN, no round-trip, and nothing to upgrade later. See COMPARISON.md for the line-for-line against hand-written DOM.
Bigger integrations, each a self-contained static page you can view source on.
Reactive components inside a plain HTML page: unit converters, vanilla-JS event binding, DOM attribute propagation, and rich data passed in via component references.
A production-shaped settings modal — 230 lines of manual DOM replaced with reactive components, forms, validation, and notifications.
A service worker with versioned, atomic offline caches — the cache coherency of a bundler, without a bundler or any change to your source.
A page that exercises every framework feature straight from the single bundle, plus an interactive counter to prove it's live.
dist/framework.js into your project — say, vdx/framework.js. Commit it.<!-- your existing static page --> <my-widget></my-widget> <script type="module"> import { defineComponent, Component, html } from './vdx/framework.js'; class MyWidget extends Component { state = { n: 0 }; template() { return html`<button on-click="${() => this.state.n++}"> clicked ${this.state.n}</button>`; } } defineComponent('my-widget', MyWidget); </script>