This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
bsbench is a benchmarking suite for Roku's BrightScript/SceneGraph runtime, written in BrighterScript (a typed superset of BrightScript). It measures operations-per-second for various BrightScript language constructs so developers can compare the relative cost of different coding patterns on real Roku hardware.
npm install # Install deps (postinstall runs: ropm copy)
npm run build # Compile BrighterScript → BrightScript (output: ./dist/)
npm run benchmark -- --host ROKU_IP --password ROKU_DEV_PASSWORD # Build + sideload + run
npm run package # Package ./dist/ → ./out/bsbench.zip (no sideload)
npm run build-complib # Build component library → ./dist/componentLibraries/complib.zipTo run a single benchmark suite, add @only annotation to the target namespace, then run normally. Remove before committing.
The system has four layers that work together at build-time and runtime:
Each file declares one suite via BrighterScript annotations:
@suite()on anamespace— declares a suite; accepts optional config withvariantsmap for parameterized runs@test("name")on asub/function— declares a benchmark casesetup()/teardown()inside the namespace — bodies get injected into every test by the plugin
The core build-time transformation engine, registered in bsconfig.json. It:
- Wraps each
@testbody in afor __bsbench_i = 0 to iterationsloop - Injects
setup()andteardown()body statements into each test - Sandwiches
roTimeSpancalls around the loop for timing (CreateObject("roTimeSpan")before,.TotalMicroseconds()after) - Expands
variantsconfigs into multiple suite entries - Injects an
allSuitesconst array intobsbench.bs— no runtime reflection needed
Runs on the Roku device:
- Auto-calibrates iteration count: starts at 1, triples until run exceeds 50 ms, then scales to hit ~500 ms per sample
- Runs 5 samples per benchmark
- Emits
bsbenchStatus: <JSON>lines to stdout (consumed by the Node.js orchestrator); disabled during debug sessions vialaunch.jsonbsConstoverride bs_const=PRINT_STATUS=trueinsrc/manifestenables telnet output in benchmark runs
cli.ts— parses--host/--passwordargs, runsRunnerRunner.ts— builds, zips, sideloads viaroku-deploy, listens on telnet, parsesbsbenchStatus:JSON linesTelnetMonitor.ts— wraps a Node.js socket connecting to Roku's debug port 8085, emits buffered lines
A separate Roku component library (BrsComponent, XmlComponent) used by the ComponentCreation benchmark. Has its own complib/bsconfig.json.
findChildren: always pass{ walkMode }explicitly — the default also visits expressions.*Recursiveoptions to cross into child function bodies.- Diagnostics:
program.diagnostics.register({ location, severity, code, message })— useastNode.location, not.range. - Removing nodes:
editor.arraySplice(parentArray, array.indexOf(node), 1).
- Suppressing unused variable warnings: prefix the variable name with
_(e.g.,catch _e,sub doNothing(_p0)). BrightScript will not warn about unused variables whose names start with_. - Type literals: use
&suffix forLongIntegerliterals (e.g.0&,1000&),#suffix forDoubleliterals (e.g.1.0#),!suffix forFloat. No suffix meansInteger(32-bit). - Type conversion functions: BrightScript provides
CInt()(Float→Integer, rounds),CDbl()(Integer→Float, despite the name returns single precision),CSng()(Integer→Float),Fix()(Float→Integer, truncates),Int()(Float→Integer, floor) — there is noCLngInt(),LongInt(), or similar for casting toLongInteger. To coerce toLongInteger, assign into a typed variable or use a&-suffixed expression. - Integer overflow:
Integeris 32-bit (max ~2.1 billion). UseLongInteger(64-bit) for iteration counts or microsecond values that could exceed this.
setup()/teardown()bodies are inlined into each test, then the functions are removed from the output.__bsbench_suppressVarWarnings = [...]is injected after timing to suppress Roku's unused-variable warnings.
| File | Purpose |
|---|---|
bsconfig.json |
BSC config: rootDir=./src, stagingDir=./dist, registers scripts/src/Plugin.ts as compiler plugin |
src/manifest |
Roku manifest; bs_const=PRINT_STATUS=true enables telnet status output |
.vscode/launch.json |
Debug config; overrides PRINT_STATUS=false to silence telnet JSON during interactive debugging |