LIGR Studio goes live in --d --:--:--→LIGR Studio is liveStart free trial →
Blog and news/Guide17 Oct 2026·8 min read

HTML5 Sports Graphics: Build One With the LIGR SDK

Build a live sports graphic in HTML, CSS and JavaScript: answer the LIGR overlay over ligr.gfx.v1, test it in a local harness and publish it. Beta.

Developer guide

No proprietary tools: your graphic is a web page, written in HTML, CSS and JavaScript, tested locally and published into a theme.

A LIGR code graphic is a web page: HTML, CSS and JavaScript that the LIGR overlay loads in a transparent frame over the video. The overlay sends it live match data over postMessage with the ligr.gfx.v1 protocol, and tells it when to show and when to hide. Operators fire it from the same control room as every other graphic, and automation and REST commands drive it by its control variables. This guide follows the Graphics SDK section of the LIGR developer docs, from the Quick start to the test checklist.

Beta. The Graphics SDK, the ligr-graphic CLI and the theme and code graphics REST routes are in beta. The protocol, the manifest and the REST shapes can change between minor versions, every change goes in the changelog, and every response from a beta route carries X-Ligr-Beta: true. The @ligrsystems/graphics-sdk and @ligrsystems/graphics-cli packages ship as 0.x versions. Test every graphic on the preview overlay of a test match before you use it on air.

Who this is for

Front-end developers, creative technologists and broadcast graphics teams who would rather write a graphic in web code than learn a proprietary template tool. If you design in Rive, there is a separate native path that does not use this SDK: see building a Rive graphic with an AI agent.

What you can build

SportGraphicWhat it reads
FootballA scorebugsportData['1'] and sportData['2'], always home and away, with score, abbreviation and kit colours, plus clock and periodShortName
TennisA scoreboard the operator points at a set or a courtControl variables of type set, round or court, which the control room shows as selectors
NetballA ladder graphicexternalData: the latest snapshot of a theme data source, read by its alias
AFL, basketball, American footballA scorebug for the codeThe sport's data shape from GET /v2/schemas/sports/{sport}, with the keys ausRules, basketball and gridiron, and sample data from GET /v2/scenarios/{sport}. The written field references for these sports are marked coming soon

How it works

1

Scaffold the graphic

Use Node 22 or later. Run ligr-graphic init from the CLI release that the Graphics SDK page names: release downloads need no npm or GitHub account. The folder holds a scorebug, the manifest graphic.json, and AGENTS.md plus a skill file for coding agents. The default template uses no framework.

2

Declare the manifest

The manifest tells LIGR the entry file, the frame size, how long to wait for your hide animation and the control variables an operator can set. This example is copied from The manifest:

{
  "schemaVersion": 1,
  "runtime": {
    "engine": "iframe-html",
    "entryFile": "index.html",
    "width": 1920,
    "height": 1080,
    "exitDurationMs": 800
  },
  "controlVariables": [
    { "id": "showAggregate", "name": "showAggregate", "type": "boolean", "defaultValue": false },
    { "id": "accent", "name": "accent", "type": "enum", "defaultValue": "home", "options": ["home", "away", "neutral"] }
  ],
  "userExpressions": []
}

You choose the variable names: there is no platform list. Pick a type from the catalogue, from string and enum to team, player and fact pickers, and the control room renders the right control. Never declare hide: LIGR adds it to every code graphic.

3

Answer the overlay

Your graphic talks to the overlay page over postMessage. createGraphic in @ligrsystems/graphics-sdk implements the listener for you, but the package is optional: any implementation of the protocol runs on LIGR.

4

Test it in the local harness

Run npm run build, then npm run dev, and open http://localhost:8080. The harness needs no API key and no dashboard login, and sends the same message order as the overlay. Play a scenario, change your control variables and press Hide: the log must show READY and HIDDEN from your graphic. With LIGR_API_KEY set, --sport loads that sport's scenarios and schemas.

5

Push, publish and put it on air

Create a theme and the graphic, then run npx ligr-graphic push and npx ligr-graphic publish --theme-version. A person activates that theme version when the operator is ready. The steps, versions and rollback are in publishing graphics through the API, and firing the graphic from a control room preset or a graphics command is in the control room setup guide.

The protocol in one table

Every message uses one envelope: protocol, sessionId, seq, type and payload. Copy sessionId from HELLO into every message you send, start seq at 1 and add 1 each time.

MessageDirectionWhen
HELLOOverlay to graphicOn frame load, repeated every 250 ms until READY, up to 20 times. No answer within 5 seconds and the graphic never loads
READYGraphic to overlayYour answer, with your version
LOAD_GRAPHICOverlay to graphicEvery data surface, after READY, and again whenever the overlay needs to resend the full state
GRAPHIC_UPDATEOverlay to graphicOnly the surfaces that changed. Merge it over the state you hold
GRAPHIC_HIDEOverlay to graphicThe only hide trigger
HIDDENGraphic to overlayWhen your out-animation ends
PING, PONGOverlay to graphic, then backEvery 10 seconds. Answer each PING with a PONG

The surfaces are sportData, controlVariables, controlVariableData, themeVariables, externalData, images and userExpressionValues. See Data binding.

Rules that keep a graphic on air

  • Render from a full load at any time. The overlay can resend LOAD_GRAPHIC, not only at the start.
  • Hide only on GRAPHIC_HIDE, and always send HIDDEN. If HIDDEN never arrives, the overlay hides the frame after exitDurationMs, 1500 ms by default, so raise it if your out-animation runs longer. A show: true update after a hide is the signal to show again.
  • Keep every frame under 16 ms at 60 fps. A graphic that stalls the page stalls every graphic on the overlay.
  • Ship everything in the bundle. Use relative paths, keep the body transparent, bundle fonts and images, and make no network call at runtime. A bundle can be 10 MiB, one file 5 MiB and one message 1 MB. With Vite, set base: './'.
  • Expect a sandbox. The frame has an opaque origin and no access to the overlay page, its cookies or its storage.

WebGL 1 and 2, WebGPU, Canvas 2D, CSS animations, the Web Animations API, WebAssembly and Web Workers are all available, as are Three.js, PixiJS, Rive, Lottie and GSAP. A vision mixer browser source runs its own Chromium, so check its version before you rely on WebGPU there.

Limits and support

  • During the beta, an organisation can own up to five themes, and the dashboard cannot create, edit or activate an owned theme. Use the CLI or REST for theme versions.
  • To see what your graphic receives on a real overlay, add ?debugCodeGraphics=1 to its monitoring or preview link and read the browser console.
  • Report code graphics, SDK and CLI problems on GitHub Issues. Account, login and app problems go to LIGR support. See Issues and support.

Frequently asked questions

What is a LIGR code graphic?

A graphic you write in HTML, CSS and JavaScript. The LIGR overlay loads it in a transparent frame over the video, sends it live match data with the ligr.gfx.v1 protocol and tells it when to show and hide. It sits in a theme beside Rive graphics and runs from the same control room.

Do I have to use the Graphics SDK package?

No. @ligrsystems/graphics-sdk is optional. Its createGraphic function implements the ligr.gfx.v1 listener for you, but any implementation of the protocol runs on LIGR, including plain HTML with no dependencies.

Which JavaScript libraries can a LIGR graphic use?

Any library that runs in a browser. The overlay is a GPU-accelerated Chromium browser, so WebGL, WebGPU, Canvas 2D, WebAssembly, Three.js, PixiJS, Rive, Lottie and GSAP all work. Keep every frame under 16 ms at 60 fps.

Can I test a graphic without an API key?

Yes. npx ligr-graphic dev runs a local harness at http://localhost:8080 that needs no API key and no dashboard login, and sends the same message order as the overlay. Without a key it uses one bundled football scenario. With LIGR_API_KEY set, it loads the scenarios of the sport you pass.

Is the LIGR Graphics SDK ready for live broadcasts?

It is in beta. The protocol, the manifest and the REST shapes can change between minor versions, with every change in the changelog. Test every graphic on the preview overlay of a test match before you use it on air.

Start building

The Quick start goes from an empty folder to a scorebug on an overlay, with the ligr-graphic CLI.

Related reading

Related posts