Getting started
Tweakit is a single npm package with no runtime dependencies. Install it,
pick one of the two builds, add the stylesheet, and hand tweaks() a schema.
Install
From npm. Or, since there's nothing else to install, copy
dist/tweaks.js and dist/tweaks.css straight into a project
that has no build step at all.
npm install tweakitImport a build
Two entries, one API: the default import is code-split and loads heavy controls on
first use; /single is the single-file build, self-contained and fully
synchronous. Sizes and what loads when →
import { tweaks } from "tweakit"; // heavy controls load on first use
// or the single-file build: everything inlined, synchronous
import { tweaks } from "tweakit/single";Add the styles
The panel's whole appearance lives in one stylesheet, built entirely on
--twk-* custom properties (see Theming).
Import it through your bundler, or link the file directly.
import "tweakit/css"; // bundler
// or:
// <link rel="stylesheet" href="node_modules/tweakit/dist/tweaks.css" />Your first panel
tweaks(name, schema) returns the panel synchronously;
append panel.el wherever you like. Each schema value becomes a control,
inferred from its shape.
const chip = target.querySelector(".gs-chip");
const panel = tweaks("Chip", {
radius: [18, 0, 60, 1], // [value, min, max, step] → slider
visible: true, // → checkbox
tint: "#7C5CFF", // → wide-gamut color picker
});
mount.append(panel.el);
panel.on((p) => {
chip.style.borderRadius = `${p.radius}px`;
chip.style.background = p.tint;
chip.style.opacity = p.visible ? 1 : 0.08;
});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).
Reading values
Live values sit on panel.params: plain properties, updated in
place. Subscribe with panel.on(fn); the callback receives the params bag
and the key that changed. Move a slider and watch the log.
Move a control
const log = target.querySelector(".gs-log");
const panel = tweaks("State", {
size: [40, 0, 100, 1],
speed: 1.5, // a bare number works too: slider, 0–1 for a value ≤ 1, else 0–3×value
mode: ["calm", "wild"],
});
mount.append(panel.el);
const unsubscribe = panel.on((params, changed) => {
log.textContent =
`changed: ${changed}\n` + JSON.stringify(params, null, 2);
});
// call unsubscribe() to stop listening; panel.params stays live either wayAsk your coding agent
The quickest way in is to describe what you want and let your agent wire it up. The guide it reads is AGENTS.md, which also ships inside the package, so an installed copy always matches the installed version. A few prompts to try; each one copies. The last takes the JSON the panel's copy button puts on the clipboard, pasted under it.
Add a tweakit panel to this card so I can tune its shadow, corner radius and background color live. Keep the shadow's fields in a folder. Bind the values to the card's styles.This hover animation uses a spring. Add a tweakit panel with a motion control for the spring and a slider for the hover scale, and drive the animation from the panel's values.These values were copied from a tweakit panel. Apply them as the new defaults in the schema in source, and leave the panel in place.
{ "radius": 22, "shadow.blur": 28, "tint": "oklch(72% 0.14 290)" }