devuiGuideDemosAPIGitHub

Saving and loading

Values autosave to localStorage, keyed by location.pathname; use createGUI({ persist: 'id' }) to pick your own key. Only values you changed are stored, together with the code default they were made against. So:

The layout (open folders, windows, pins, the panel's place) is saved too. To choose what's saved:

An app that keeps its state in its URL, or whose controls start loads when set, can keep the layout and save only its look:

const gui = createGUI({ persist: { values: false } });
gui.add(state, 'scene', { options: scenes });           // the URL decides; never restored
gui.folder('Look', { persist: true }).add(look, 'grain'); // saved and restored

Menu options:

From code: gui.save() and gui.load(doc), gui.download() and gui.upload(), and gui.toCode().

Keep values in your project

import tweaks from './tweaks.json';
gui.linkFile('src/tweaks.json', { initial: tweaks });

The path is relative to the project root (where the dev server runs), not to the module. To start, create the file empty: {} (or { "devui": 1, "values": {} }, the format devui writes). You can also call linkFile('src/tweaks.json') without initial first: the dev server creates the file on the first change, and then you add the import. In the file, each control's entry has v (its value as JSON), d (the code default it was tuned against, to spot when the code changes) and n (the value as a plain literal, for the noop build).

The file is a layer between code defaults and your local tweaks, so values you commit reach everyone, and local storage only keeps what differs from the file. Presets are layered the same way: a preset you changed, added or deleted is kept locally until the file has it, and the others follow the file, so a teammate's change to one reaches you rather than being written over. While the file is writable, every finished change (a whole drag, an edit, a preset) is written to it, formatted one control per line so diffs read well. It's writable when:

linkFile also takes url (where to read the file when there's no dev server: a copy served next to the page) and server: false (never write through one). gui.file?.status is how the link is (linked, read-only, needs-permission…; the file event says when it changes), and gui.unlinkFile() lets it go.

Otherwise the file is read-only and tweaks stay in the browser. Production builds apply it: the noop build applies initial (and gui.load(doc)) to params() and add(obj, key) bindings, so a shipped build uses the values you tuned. Controls created by inspectors (gui.add(material)) need the values copied into code (Copy all as code).