Two components, one path
A control writes variables.home.score and a graphic reads it. That pairing is the whole model — nothing to declare, no store to configure, and no wiring between the two files.
Scoreboards, lower thirds and clocks as React components — driven from an operator's board inside OBS. No server, no backend, and the graphics keep working when the network does not.
Both halves name the same path. That is the entire mental model.
// src/control/Control.jsx — the operator's board, in an OBS dock
import { Field, Panel, Stepper } from '@single-studio/core/control'
export default function Control() {
return (
<Panel title="Scores">
<Field name="home.name" label="Home" />
<Stepper name="home.score" label="Home score" />
</Panel>
)
}// src/sources/Scoreboard.jsx — one file per OBS browser source
import { Scene, Variable } from '@single-studio/core/source'
export default function Scoreboard() {
return (
<Scene>
<Variable name="home.name" fallback="Home" />
<Variable name="home.score" fallback="0" />
</Scene>
)
}Press + on the board and the scoreboard changes. There is no step in between to write.
You do not clone Single Studio. You start from Single-Studio-Template — press Use this template, name your repository, and clone that:
npm install
npm run devThe board opens at the printed URL. Its header menu lists every graphic's browser-source URL with a copy button — that is what you paste into OBS.
Your studio is your own repository from the first commit. Single Studio is a dependency in it, upgraded with a version bump.
Getting started → · Components → · Your own data → · Plugins → · Working with other people →