Getting Started
Install
Section titled “Install”npm i prop-for-thatThree usage modes
Section titled “Three usage modes”1. Auto (zero-config)
Section titled “1. Auto (zero-config)”Import prop-for-that/auto and it wires everything for you — declaratively, with nothing attached unless the DOM asks for it:
- Scans the DOM for
[data-props-for]attributes and binds the named sources to those elements. Globals are declared too — put them on the root<html>and they write to:root. - Loads plugin sources on demand. The first time a
data-props-forkey needs a plugin, its chunk is dynamically imported and registered, then the binding attaches — noregisterPlugins(), no separate plugins import. - Keeps everything in sync with a single
MutationObserver: elements added later are bound, removed elements are torn down and their properties cleaned up, and editing an element’sdata-props-forvalue re-syncs just the keys that changed — so you can add or drop a source at runtime by changing the attribute alone.
Because plugins lazy-load via dynamic import(), load auto as a module script (the bare <script src> drop-in is gone):
<!-- from a CDN that serves the dist tree verbatim (unpkg / jsDelivr file paths) --><script type="module" src="https://unpkg.com/prop-for-that/dist/auto.js"></script><!-- or, with a bundler --><script type="module">import 'prop-for-that/auto'</script>
<html data-props-for="viewport pointer"> <!-- globals → :root -->
<input type="range" min="0" max="100" data-props-for="range"><section data-props-for="size visibility">…</section>input { background: hsl(calc(var(--live-value-pct) * 120) 80% 50%);}
section { opacity: var(--const-has-entered); transition: opacity 0.4s;}Want the values to interpolate? Add data-props-typed to the root <html> and every --live-* this page writes is registered as an @property — the markup equivalent of configure({ typed: true }):
<html data-props-typed>…</html>2. Imperative
Section titled “2. Imperative”Import individual functions for explicit control over which sources are active and when they’re torn down:
import { propsFor, configure } from 'prop-for-that'
// write viewport to :root (pointer is now an opt-in plugin — see Plugins)propsFor(['viewport'])
// write the range source to a specific element; returns a disposer.// an element's id is a ready-made global in JS — no query selector needed.// here, <input id="slider" type="range" min="0" max="100">const dispose = propsFor(slider, ['range'])
// later, tear it down cleanlydispose()Use configure() to change the property prefixes or the global root target, before attaching any sources:
import { configure } from 'prop-for-that'
configure({ livePrefix: '--pft-', constPrefix: '--pft-const-' })3. Head constants
Section titled “3. Head constants”A few values are read once and matter for the first paint: scrollbar width, device pixel ratio, CPU cores. Load the head entry as a synchronous inline script so the properties exist before any CSS applies:
<head> <script type="module">import 'prop-for-that/head'</script> <!-- sets --const-scrollbar-w, --const-scrollbar-thin-w, --const-dpr, --const-cores, --const-mem --></head>These use --const-* names and are never overwritten after that first write.