# Getting started

> Install tweakit, import a build, add the styles, and wire your first live parameter panel.

The page: https://ryankiley.github.io/tweakit/getting-started.html. Every page as Markdown: https://ryankiley.github.io/tweakit/llms.txt

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.

```sh
npm install tweakit
```

## Import 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 →](https://ryankiley.github.io/tweakit/imports.md)

```js
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](https://ryankiley.github.io/tweakit/theming.md)). Import it through your bundler, or link the file directly.

```js
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.

```js
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.

```js
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 way
```

## Ask 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](https://ryankiley.github.io/tweakit/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 controls:

```text
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.
```

Tune a motion:

```text
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.
```

Apply copied values:

```text
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)" }
```
