Tweakit

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 tweakit

Import a build

Two entries, one API. The default import is a single self-contained file (~32 KB gzip) — every control inlined, fully synchronous. The /core entry is code-split (~18 KB gzip): heavy controls (color, gradient, spring, plot…) dynamic-import on first use. More on choosing →

import { tweaks } from "tweakit";        // everything inlined, synchronous
// …or the code-split entry — heavy controls load on first use:
import { tweaks } from "tweakit/core";

Add the styles

The panel's whole appearance lives in one stylesheet, built entirely on --tw-* 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.

Tweak me
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–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 way