Tweakit

The two builds

One source tree, two builds, one API. The only observable difference is when heavy controls exist.

EntrySizeLoading
tweakit~32 KB gzipone self-contained file; every control inlined, fully synchronous
tweakit/core~18 KB gzipcode-split; color engine and heavy controls dynamic-import on first use

Pick the monolith for drop-in simplicity (it's also the no-bundler choice — copy dist/tweaks.js anywhere). Pick /core when panels are part of a real app and you'd rather not ship the color engine to users who never open a picker.

panel.ready

tweaks() returns synchronously on both builds — the panel element, params and methods are live at once. On the split build, a panel whose schema needs lazy modules builds all of its controls when panel.ready resolves (until then the shell is an empty frame); on the monolith, ready resolves immediately. This page runs the split build — the stamp shows the real load.

const stamp = target.querySelector(".im-stamp");
const t0 = performance.now();
const panel = tweaks("Ready", {
  motion: { type: "spring", stiffness: 220, damping: 18, mass: 1 }, // lazy here
  speed: [1, 0, 3, 0.1],                                            // built-in
});
mount.append(panel.el);   // the shell mounts now; controls build at ready

panel.ready.then(() => {
  stamp.textContent = `panel.ready resolved in ${Math.round(performance.now() - t0)} ms`;
});

mount is the panel's slot inside the stage; target is the demo surface it controls. In your own page you'd just document.body.append(panel.el).

What loads when

On the split build, these schema types trigger a dynamic import the first time any panel (or [data-tw] host) uses them — once loaded, they're synchronous for the rest of the session:

  • color enginecolor, and gradient (which builds on it)
  • one module eachinterval, spring, cubicbezier, point, plot, image, tabs
  • monitorsmonitor and fpsgraph share a module

Everything else — slider, number, text, checkbox, list, radiogrid, button, buttongroup, folder, separator — ships in core and is always synchronous.

The exports map

Everything the package ships, by import path. Types ride along with both entries.

import { tweaks, enhance } from "tweakit";        // monolith
import { tweaks, enhance } from "tweakit/core";   // code-split
import "tweakit/css";                             // panel styles

import type { Schema, Panel, Theme, TweaksOptions } from "tweakit";