Skip to content

The validator

Every time you press “Save version”, the Studio validates the draft. It does it in two layers:

  1. Static review. It reads the four files without running them: that the manifest is valid JSON, that the menu is consistent, that index.html, style.css and script.js use nothing forbidden, and that what you declare and what you use match (events, parameters, actions and files).
  2. Run test. It opens the widget in a test browser connected to a Streamer.bot simulator, fires the declared events and watches what happens: whether it connects, subscribes, reacts, survives a reconnection and whether a message with HTML ends up turned into elements.
  • An error blocks publishing the version.
  • A warning does not block it, but flags something you almost surely want to fix.
  • Some codes are a warning in the draft and an error when saving a version (for example, asset_not_found).

Every finding carries a code (like js_forbidden_eval), the file and, when known, the line. They are all in the list of codes, with what they mean and how to fix them.

  • Size: 300 KB across the four files and 64 KB for manifest.json. The alerts design (alerts) counts separately, up to 128 KB.
  • Your own files: up to 30 in assets.
  • Run test: 20 seconds at most, and a memory cap; if a widget goes over, the test is cut (runtime_timeout and runtime_memory).
  • Queue: a Widget.queue task lasts at most 90 seconds and 50 fit while waiting.

Widgets run inside OBS, which is why the validator is strict about what they may do:

  • Network: no fetch, WebSocket and the like. Data arrives through Streamer.bot events.
  • Dynamic HTML: no innerHTML; text is painted with Widget.dom.
  • Dynamic code: no eval or Function, and no workers.
  • Windows: the widget does not navigate, open windows or touch others.
  • External resources: only images from the emote and badge CDNs and Google Fonts. Yours go in your library.