# no build · no deps · no rot · ai-native
Reactive components, two-way binding, routing and a 30-component UI library — running straight from source in the browser.
The dependency you never installed can't be the one that bites you.
pulled transitively, from maintainers you'll never meet
read once, reviewed once, then simply yours
npm update, because there is no npmThese run in a sandbox from the same source you'd write — code on the left, the living result on the right. Change the code and hit Run.
// a component is a class — reactive state, no setState, no virtual DOM
// two-way binding + lists — x-model, each(), when(), on-* handlers
// shared state, zero ceremony — one store, many components, no prop-drilling or provider
$ (no build)
ES modules run directly in the browser. Save a file, refresh. There is no compiler between you and the page.
deps: 0
Nothing from npm — not even transitively. The whole framework is a small set of files you can read.
router + ui
Hash and HTML5 routing, reactive stores, and a 60+ component cl-* UI library, all in the box.
<my-widget>
Import a component into any HTML page and use its tag. Perfect for a backend that just serves files.
xss ✕
Auto-escaping, URL-scheme allowlisting, and raw HTML gated behind an explicit, trust-marked opt-in.
light DOM
No shadow DOM. Your components are right there in the element tree — inspect, tweak, and debug them like normal HTML.
A modern component model without React's build chain — or vanilla's manual DOM wiring.
| VDX | React | Vanilla JS | htmx | |
|---|---|---|---|---|
| Build step | None | Required | None | None |
| Bundling & linting | Optional | Required | DIY | None |
| TypeScript | Optional | Via build | DIY | — |
| npm dependencies | Zero | Many | Zero | One script |
| Reactive state | Built in | Built in | Roll your own | Server round-trip |
| Manual DOM sync | Never | Never | Constant | Server-driven |
| XSS-safe by default | Yes | Yes | On you | On you |
| Two-way binding | x-model | Manual | Manual | — |
| Router + UI library | Included | Add packages | Add packages | — |
| Supply-chain surface | None | Large | None | Tiny |
| Survives a framework era | Vendored | Churns | Forever | Stable |
# ai-native
Most frameworks assume a human who already knows them — the right hooks, this year's patterns, the current build config. VDX assumes a reader starting from the files in front of them, human or model.
# one file
Point an agent at the source — or the single-file FRAMEWORK.md — and it has the whole model. No plugin matrix, no version-specific lore, no build config to reverse-engineer.
el.state
No shadow DOM, so any component is reachable from the DOM. Read or poke its live state in plain JS ($ is your devtools' querySelector) — no framework extension needed.$('cart-badge').stores.cart.count
no hooks
No hooks, no renderer, no act(). Grab the element, call its methods, read its state. The wiring that made React hooks a testing chore simply isn't here.
Escaping isn't a function you remember to call — it's the default.
Paste hostile input into the demo: the markup renders as plain text and the
javascript: URL goes nowhere. Rendering raw HTML is the part you ask for —
hit Edit to read the markup.
raw() tags its output at runtime, so a JSON string from an API can never masquerade as trusted markup.raw(userInput) in the source, easy to spot in review and to grep for.No installer to trust, no toolchain to set up. Drop the files in, serve them, done.
git clone https://github.com/iwalton3/vdx-web.git && cd vdx-web
python3 -m http.server 9000 # any static server — nothing to install<!-- in your page --> <my-widget></my-widget> <script type="module"> import { defineComponent, Component, html } from './vdx/lib/framework.js'; </script>