| name | open-stage-control |
| description | Open Stage Control reference for OSC UI design. Use when: creating or editing OSC controller JSON sessions, designing widgets (buttons, sliders, dropdowns, panels, xy pads), writing widget scripts (onValue, onCreate, onTouch), configuring OSC addresses, building custom modules, or styling with CSS themes. |
Open Stage Control Reference
When to Use
- Creating or modifying
.json session files for Open Stage Control
- Designing UI widgets (buttons, sliders, panels, dropdowns, xy pads)
- Writing widget scripts (
onValue, onCreate, onTouch)
- Configuring OSC message routing and addresses
- Building custom modules for server-side message processing
- Styling interfaces with CSS themes
Architecture
Open Stage Control has 3 modules:
- Server: Node.js/Electron, handles OSC/MIDI, serves web client
- Launcher: Configuration GUI for the server
- Client: Web app served by the server, runs in any modern browser
Widget Types
Basics
| Type | Purpose |
|---|
button | Toggle or momentary trigger |
switch | Multi-value button group |
dropdown | Select from list |
menu | Context menu selector |
input | Text/number input field |
textarea | Multi-line text input |
file | File browser widget |
Containers
| Type | Purpose |
|---|
panel | Layout container (vertical/horizontal/grid) |
modal | Popup panel |
tab | Tabbed container |
matrix | Grid of cloned widgets |
clone | Clone another widget |
fragment | Reusable widget template |
folder | File-system-like tree |
root | Top-level session container |
Sliders
| Type | Purpose |
|---|
fader | Linear slider |
knob | Rotary control |
encoder | Endless rotary |
range | Min/max range slider |
Pads
| Type | Purpose |
|---|
xy | 2D position pad |
multixy | Multiple 2D points |
rgb | Color picker |
canvas | Scriptable drawing area |
Indicators
| Type | Purpose |
|---|
led | On/off indicator |
text | Static/dynamic text display |
Graphs
| Type | Purpose |
|---|
plot | Line/bar chart |
eq | EQ curve display |
visualizer | Audio-style visualizer |
Frames
| Type | Purpose |
|---|
frame | Embedded webpage |
svg | SVG display |
html | Raw HTML |
image | Image display |
Scripts
| Type | Purpose |
|---|
script | Invisible widget that runs JS |
variable | Stores a value without UI |
Key Widget Properties
{
"type": "button",
"id": "my_button",
"label": "Play",
"address": "/play",
"target": ["ip:port"],
"default": 0,
"on": 1,
"off": 0,
"css": "",
"visible": true,
"interaction": true,
"bypass": false,
"ignoreDefaults": false
}
Common Properties
id — Unique widget identifier (used in get(), set())
address — OSC path sent when value changes (e.g., /bass_on)
target — Override default OSC target ("ip:port")
label — Display text (supports templates: #{@{this} == 1 ? 'On' : 'Off'})
default — Initial value
css — Inline CSS styles
visible / interaction — Show/enable widget
Button-Specific
on / off — Values for active/inactive states
mode — "toggle" or "momentary" (tap)
colorWidget / colorFill — Button colors
Switch-Specific
values — Object mapping labels to values: {"Bass": 0, "L1": 1, "L2": 2}
Dropdown-Specific
values — Array or object of options
Slider/Fader-Specific
range — {"min": 0, "max": 1} or with steps
steps — Snap to N positions
XY Pad-Specific
pointSize — Size of points
rangeX / rangeY — Value ranges per axis
snap — Return to center on release
Scripting
Widget scripts execute JavaScript on events.
Event Types
onCreate — When widget is created (after children)
onValue — When widget value changes or receives a value
onTouch — When widget is touched/released
Available Variables in Scripts
get("widget_id")
getProp("widget_id", "property")
getVar("widget_id", "varName")
set("widget_id", value)
set("widget_id", value, {send: false})
setVar("widget_id", "varName", value)
send("ip:port", "/address", arg1, arg2)
send("/address", arg1)
globals.screen
globals.env
globals.ip
locals
setTimeout(id, callback, delay)
setInterval(id, callback, delay)
clearTimeout(id)
clearInterval(id)
stateGet("widget_id")
stateSet(stateObject)
updateProp("widget_id", "propName")
setFocus("widget_id")
storage
Script Example (onValue)
if (value == 1) {
set("status_text", "Playing")
} else {
set("status_text", "Stopped")
}
Script Example (onCreate)
set("this", {"Reverb": "reverb", "Echo": "echo", "Distortion": "distortion"})
OSC Communication
Address Pattern
Widgets send OSC messages based on their address property:
- Widget value changes → OSC message sent to
target with address and value as arguments
- Incoming OSC messages with matching
address → widget value updated
Receiving OSC to Update Widgets
Send an OSC message to the Open Stage Control server (default port 7777) matching a widget's address to update it:
/bass_on 1 → Sets bass_on widget to 1
/tempo 120 → Sets tempo widget to 120
Sending from Scripts
send("/custom/address", value, 42)
send("192.168.1.10:4560", "/trigger", value)
Custom Modules (Server-Side)
Custom modules run on the server and can intercept/modify OSC messages:
module.exports = {
oscInFilter: function(data) {
var {address, args, host, port} = data
return data
},
oscOutFilter: function(data) {
var {address, args, host, port} = data
return data
}
}
CSS Theming
Apply CSS via widget css property or global theme file:
.widget { background: #222; }
.on { background: green; }
.label { font-size: 14px; color: white; }
Load a theme file via server config: --theme /path/to/theme.css
Session JSON Structure
A session is a single JSON object with a root widget containing children:
{
"type": "root",
"id": "root",
"children": [
{
"type": "panel",
"id": "main_panel",
"layout": "vertical",
"children": [
{"type": "button", "id": "play_btn", "address": "/play"},
{"type": "fader", "id": "volume", "address": "/volume"}
]
}
]
}
Sonic Stage Integration
In this project, Open Stage Control communicates with Sonic Pi on port 7777: