Controls

Create inferred and configured controls with useControls.

useControls accepts an object and returns an object of Vue refs with the same keys. Simple values get sensible controls automatically; configuration objects let you set constraints and presentation.

Inferred controls

const controls = useControls({
  enabled: true, // boolean
  count: 12, // number
  title: 'Tres Leches', // text
  accent: '#f59e0b', // color
})
Input valueControl
booleanCheckbox
numberNumeric input
Hexadecimal string such as #f59e0b or 0xf59e0bColor input
Other stringText input
Vector2, Vector3, Euler, or a configured arrayVector inputs

Configuration objects

Wrap a value in { value, ...options } when you need more control.

Common options are:

OptionPurpose
valueInitial value or an existing ref. Required for a configuration object.
typeExplicit control type: boolean, number, range, text, color, select, button, vector, or graph.
labelHuman-readable label shown in the panel.
iconIcon class shown with the control label.
visibleSet to false to keep the control out of the panel.
min, max, stepBounds and increment for numeric, range, and vector controls.
formatFunction that formats a numeric value for display.
optionsSelect choices as primitive values or { text, value } objects.
onUpdateCallback used by graph controls.

The sections below cover each control type.

Boolean

A boolean value renders a checkbox.

const { enabled } = useControls({
  enabled: true,
})

Number

A plain number renders a numeric input with drag support. Combining explicit bounds with type: 'number' keeps the numeric input instead of switching to a range.

const { stars } = useControls({
  stars: {
    value: 4,
    type: 'number',
    min: 0,
    max: 10,
    step: 1,
  },
})

Range

Providing min, max, or step on a numeric configuration gives it the range control type.

const { speed } = useControls({
  speed: {
    value: 1,
    min: 0,
    max: 5,
    step: 0.1,
    label: 'Animation speed',
  },
})

Text

Any string that is not a hexadecimal color renders a text input.

const { title } = useControls({
  title: 'Tres Leches',
})

Color

Hexadecimal strings such as #f59e0b or 0xf59e0b render a color picker. Pick a color below and watch the demo background follow it.

const { accent } = useControls({
  accent: '#f59e0b',
})

Select

Providing options renders a select. Options can be primitives or labeled objects.

const { renderer } = useControls({
  renderer: {
    value: 'webgl',
    options: [
      { text: 'WebGL', value: 'webgl' },
      { text: 'WebGPU', value: 'webgpu' },
    ],
  },
})

The returned ref preserves the selected option's original string or number value.

Vector

Vector2, Vector3, Euler, and arrays of numbers render a vector control with one number drag per axis. Drag the x and y inputs below to move the point.

const { point } = useControls({
  point: {
    value: [1, 1],
    min: -2,
    max: 2,
    step: 0.1,
  },
})

Button

Button settings live in value; set the control type explicitly.

useControls({
  reset: {
    type: 'button',
    value: {
      label: 'Reset scene',
      variant: 'primary',
      size: 'md',
      onClick: () => resetScene(),
    },
  },
})

Button variants are primary and secondary. Sizes are xs, sm, md, lg, xl, and block.

Graph

Use a graph to visualize a changing numeric value, or enable the built-in FPS graph.

const frameTime = ref(0)

useControls({
  frameTime: {
    type: 'graph',
    value: frameTime,
  },
})

useControls('fpsgraph')

// Update the ref as usual, the graph plots each new value
const loop = (t: number) => {
  frameTime.value = (Math.sin(t / 400) + 1) * 8 + 8
  requestAnimationFrame(loop)
}
requestAnimationFrame(loop)

Pass a ref as the value, then change the ref from your own code. The graph samples its value on an interval. Its optional onUpdate callback receives the collected values.