Library / SDK
cocopon/tweakpane avatar
cocopon/tweakpane

tweakpane: a dependency-free pane, and the 4.x line that dropped CommonJS

:control_knobs: Compact GUI for fine-tuning parameters and monitoring value changes

4,601 stars129 forksTypeScriptMIT

At a glance

What is it?
Tweakpane is a compact browser library for fine-tuning parameters and watching value changes, in the shape dat.GUI established. Its own README is short and points outward for everything, so what it does tell you is worth taking seriously: version 4 is ES modules only, CommonJS users are sent back to 3.x, and TypeScript users are told to install a second package.
Who is it for?
tweakpane suits someone building a browser demo, a WebGL sketch or a debug overlay who wants a parameter pane with no framework attached and no dependency tree to argue about. It does not suit a CommonJS project, since version 4 is ES modules and the README points you back to 3.x, and it does not suit a team that wants a component library with widgets beyond numbers, strings, booleans, colour and points.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 5, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Version 4 is ES modules, and CommonJS users are told to stay on 3.x

One line in the Development section decides which version you install. From version 4, Tweakpane has been migrated to ES modules, and if you are looking for a CommonJS version of the package, the instruction is to use version 3.x.

There is no compatibility shim mentioned and no dual build described. That makes the module format the sharpest edge in this library, because a bundler based project will never notice it and a Node script with `require` will fail on the first import.

The other thing the front page offers is a bridge from its ancestor. Tweakpane is described as inspired by dat.GUI, and dat.GUI users are pointed at a migration guide with its own anchor in the documentation. That is a small courtesy with real value: if you already have a dat.GUI setup, the question you arrive with is not what Tweakpane is but how your existing bindings move across, and the answer is written down.

The three headline qualities are a clean and simple design, being dependency-free, and being extensible. Each of the three is worth testing against your own project, and the rest of this article takes them one at a time.

TypeScript means installing @tweakpane/core as well

The Installation section is two sentences and the second one is the useful one. Refer to the Getting Started section for concrete steps, and remember to install `@tweakpane/core` if you are developing with TypeScript.

So the type definitions are not bundled into the pane package you use at runtime. A TypeScript project ends up with two things to install, one for the pane and one for its types.

That split is visible in the repository itself. The root package.json is named `tweakpane-monorepo`, is marked private, and declares workspaces of `packages/*`. Every script that touches code does so by descending into a package directory, `setup:core` runs a build inside `packages/core`, `setup:tweakpane` runs one inside `packages/tweakpane`, and the lint script runs in both in sequence.

The version field in that root file reads 4.0.5, which is the same number as the newest published release, so the monorepo and the released package track each other.

For a user, the practical takeaway is that `@tweakpane/core` is not an optional extra for type safety. If your editor has nothing to say about a binding object, you have probably missed this step.

Bindings take colour and points, readonly bindings do not

The feature list is organised by what the pane can hold, and the split between editable and readonly is where the design shows.

Bindings cover Number, String, Boolean, Color and Point in 2D, 3D and 4D. Those are the types you can change, and the point types are the reason a 3D scene can have its camera position, target and field of view driven from a pane.

Readonly bindings cover a shorter list: Number, String and Boolean. No colour and no point. That is a sensible cut, since a monitor is for watching a value that something else writes, and a colour or a vector is rarely the thing you want to watch alone, but it does mean a design that relies on monitoring a colour has no widget for it.

The purpose of both halves is in one sentence at the top: fine-tuning parameters and monitoring value changes. Tweakpane is not a settings dialog that writes to storage, and it is not a form library. It is a two-way handle on live values, which is why the type list is short and every entry is something you would otherwise expose as a slider or a debug readout.

Folder, Tab, Button, Separator, and a Figma file for plugin authors

The layout vocabulary is four items: Folder, Tab, Button and Separator. There is no list, no tree, no select and no text field beyond what the bindings already provide, which is a deliberate narrowing for a debug pane rather than an application interface.

Theming has its own section, and plugins have their own, and the extensibility claim is supported with something concrete: a Design Kit on Figma that includes the basics, styles and components for Tweakpane, described as a practical resource for creating your own plugin.

That is the detail worth noting. Extensible libraries usually ask you to read their source to match their look. Tweakpane ships a design file, so a plugin that has to sit next to an existing pane can match it without reverse engineering the CSS.

Under the miscellaneous heading there are three more capabilities: mobile support, TypeScript type definitions and JSON import and export. The last one is the interesting one for a tool like this, since a pane full of tuned parameters can be captured and reloaded rather than rebuilt by hand.

None of these are described in the README itself, which links to the official pages for details. That is the pattern for this repository: the README states what exists and where to read it, and stops.

Building your own starts with npm run setup and ends at localhost:8080

The build instructions are four commands:

bash
$ npm ci
$ npm run setup
$ cd packages/tweakpane
$ npm start

What they do is described in one sentence: they start a web server for the document, build the source files and watch for changes, and you open `http://localhost:8080/` to browse the document.

So the development loop is a documentation site with a live build. `npm run setup` at the root is the fan-out step, running `setup:core` and `setup:tweakpane` in order through npm-run-all, each of which changes into its package and runs a build. Only after that does the `npm start` in `packages/tweakpane` do anything useful.

The order matters more than usual here, because the root `setup` script builds both packages and the pane package is downstream of the core one. Running `npm start` in `packages/tweakpane` before the core build has produced output is the kind of mistake that looks like a bundler problem.

There is no test command in the README's development section, which is consistent with a repository whose README is aimed at users of the published package rather than at people hacking on it.

Coverage is merged per package and lint runs in both

The root scripts show how the project tests itself, and the shape is dictated by the monorepo layout.

Coverage is a chain. `coverage:prepare` makes a `.nyc_output` directory with mkdirp, `coverage:package:core` and `coverage:package:tweakpane` descend into each package and run its own coverage, `coverage:merge:*` merges each package's output into a single file with `nyc merge`, and `coverage:report` produces lcov output. The `coverage` script runs all four stages in order with npm-run-all.

Lint is simpler and reveals the same structure in one line: it runs in `packages/core` and then in `packages/tweakpane`, rather than once at the root. A linter that has to be invoked twice is a small cost of splitting the library in two, and it is paid in the scripts rather than in the configuration.

The devDependencies explain what the tests run on. Mocha is the runner, jsdom provides the DOM, and `canvas` is present, which is how DOM dependent behaviour such as rendering and pointer input can be exercised in Node at all. `nyc` does the instrumentation and `npm-run-all` sequences the scripts. On the lint side it is ESLint 7 with the TypeScript plugin, prettier through eslint-plugin-prettier, and eslint-plugin-simple-import-sort.

The practical note for a contributor: run the scripts from the root, and expect coverage output in two places before it is merged into one.

Dependency-free describes the package, not the repository

Dependency-free is one of the three headline claims, and it holds in the place that matters. What a project installs when it takes Tweakpane is one package with nothing behind it, which is the reason to choose a debug pane over a component library.

It does not describe this repository. The root devDependencies list is long: type packages for assert, jsdom, mocha and node, the TypeScript ESLint plugin and parser, autoprefixer, canvas, four ESLint packages, jsdom, mkdirp, mocha, npm-run-all and nyc. Every one of those is build-time, and none of them reaches a consumer.

The version record is the other thing to weigh. The releases listed are 4.0.5 on 2024-11-03, 4.0.4 on 2024-06-30 and 4.0.3 on 2023-12-22, and the last push to the default branch was on 2026-03-15. So the tree is moving and the published versions are not, which means a project that pins 4.0.5 is pinning a build from late 2024 rather than the head of the branch.

Whether that matters depends on what you need from it. For a debug pane that ships with your application and is not load-bearing, the gap is unremarkable. For anything else, check the release notes on the documentation site before assuming the branch and the package agree.

Editorial conclusion

tweakpane suits someone building a browser demo, a WebGL sketch or a debug overlay who wants a parameter pane with no framework attached and no dependency tree to argue about. It does not suit a CommonJS project, since version 4 is ES modules and the README points you back to 3.x, and it does not suit a team that wants a component library with widgets beyond numbers, strings, booleans, colour and points. Before you pick a version, decide whether you need the type definitions, which means installing `@tweakpane/core` alongside the pane, and check whether the 4.0.5 release from November 2024 is recent enough for the project you are wiring it into.

Frequently asked questions

How do I install Tweakpane, and which version should I use?

The README sends you to the Getting Started section for the concrete steps and adds one requirement: install `@tweakpane/core` if you are developing with TypeScript. From version 4 the package is ES modules only, so anyone needing CommonJS should use version 3.x.

What can I put in a Tweakpane pane?

Bindings cover Number, String, Boolean, Color and Point in 2D, 3D and 4D. Readonly bindings for monitoring values cover Number, String and Boolean. Layout comes from four UI components, Folder, Tab, Button and Separator, with theming and plugins on top.

How do I build Tweakpane from source?

Run `npm ci`, then `npm run setup`, which builds `packages/core` and then `packages/tweakpane`, then `cd packages/tweakpane` and `npm start`. That starts a web server for the document and watches for changes, browsable at `http://localhost:8080/`.

Official sources

  1. cocopon/tweakpane on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/cocopon-tweakpane.svg)](https://hysenlabs.com/projects/cocopon-tweakpane)