BrightScript Simulation Engine for Node.js
July 27, 2026 ยท View on GitHub
An interpreter for the BrightScript language that runs as a CLI and Roku apps in Node.js.
Overview
The BrightScript Simulation Engine provides a complete BrightScript interpreter, bundled as a set of libraries and a command-line interface, for executing, testing, and packaging Roku apps on Node.js platforms. Perfect for automation, CI/CD pipelines, development workflows, and server-side BrightScript execution.
๐จ Important:
Since v1.9.0, this package was split from the browser package, to use the simulation engine with web based applications check out the brs-engine package.

Key Features
๐ฅ๏ธ Command Line Interface
- Interactive REPL - Read-eval-print loop for BrightScript
- File Execution - Run
.brs,.zip, and.bpkfiles directly - Folder Execution - Run BrightScript apps from a folder
- App Packaging - Create encrypted
.bpkpackages from.zipfiles - Terminal Screen Rendering - Show the app screen as ASCII art, Unicode blocks or real images (iTerm2/Kitty)
- Interactive Control - Keyboard remote control, PNG screenshots (Ctrl+S) and text output logging to file
- Batch Processing - Execute multiple files and automate workflows
โ๏ธ BrightScript Interpreter
- Full BrightScript language interpreter, with specs aligned up to Roku OS 15.3
- Draw 2D API - Full support for the BrightScript 2D drawing components
- SceneGraph Framework - Experimental support for the Roku SceneGraph components (see section below)
- Video Playback - Via
roVideoPlayerandVideonode - Audio Playback - Via
roAudioResources,roAudioPlayerandAudionode - Image Processing - Support for PNG, JPEG, GIF, BMP and WEBP formats
๐บ Device Simulation
- Screen resolutions - Support for various Roku display modes
- Input Handling - Keyboard and gamepad simulation for remote control input, see docs for more details
- File System Simulation - Including
pkg:/,tmp:/,cachefs:/,common:/andext1:/volumes - Registry simulation - Roku device registry emulation, persisted to a local
registry.jsonin the user data folder when--registryis used - Micro Debugger - Step-through debugging capabilities, similar to the Roku experience
- ECP Server - External Control Protocol for remote control
- SSDP Discovery - Device discovery simulation
- Localization - Language and region settings
- Customization - You can customize device features and behaviors, see docs for more details
SceneGraph Extension
The brs-scenegraph extension is bundled with the brs-node package (as bin/brs-sg.node.js). The CLI loads it automatically so the REPL and apps can run SceneGraph without additional setup โ use the --no-sg flag to disable it for a given CLI session. When embedding the library:
- With the synchronous
executeFile, register it in-process:registerExtension(() => new BrightScriptExtension()). - With the worker-based
executeApp, declare it on the payload (payload.extensions+payload.device.extensions) so every worker thread loads its own instance โ see the Node.js library guide.
Refer to the extensions guide for more information about the extension architecture.
โ ๏ธ Note:
SceneGraph extension is mostly complete, with beta versions available for testing. See the current state of the SceneGraph implementation and other limitations of the engine in the Current Limitations document.
Installation
Global Installation (CLI)
npm install -g brs-node
Project Installation (Library)
npm install brs-node
Libraries
The package libraries require Node.js v22 or higher, and are organized as follows:
| Library File | Description |
|---|---|
bin/brs.cli.js | Executable CLI application that can be used from the terminal |
bin/brs.node.js | The engine library (the package main): exposes the interpreter to Node.js applications, and is also the worker entry used to run apps and SceneGraph Tasks on worker threads |
bin/brs.ecp.js | A worker thread library, used by the CLI to launch the ECP and SSDP services |
bin/brs-sg.node.js | The SceneGraph extension bundle, loaded dynamically into the engine (and into each worker thread) when SceneGraph support is needed |
How the libraries relate
brs.node.jsis the core โ everything else plugs into it. It offers two execution models:executeFile(payload)runs the interpreter synchronously on the calling thread โ ideal for tests, CI and scripting. SceneGraphTasknodes do not spawn in this mode.executeApp(payload)runs the app on a dedicated worker thread and spawns one worker per running SceneGraphTask, mirroring the browser engine and a real Roku device. The worker entry isbrs.node.jsitself.
brs-sg.node.jsis deliberately a separate bundle (not compiled into the core): the interpreter stays SceneGraph-agnostic and loads it through the public extension API โ the same contract available to third-party extensions. It binds to the running engine at load time (itsbrs-engineimport resolves to the already-loadedbrs.node.jsmodule), so both must always come from the same package version. The CLI loads it automatically (--no-sgdisables); library consumers register it per the examples in the Node.js library guide.brs.cli.jsis a consumer of the other three: it requiresbrs.node.jsfor execution, loadsbrs-sg.node.jsfor SceneGraph apps, and spawnsbrs.ecp.jsas a worker when--ecpis passed.
Documentation
Learn how to use the package and its libraries by reading the documents below:
- How to use the Node.js Library
- How to run as a Command Line Interface
- How to customize the Engine behavior
- Remote Control Simulation
- How to build from source
- How to contribute to this Project
Changelog
- Read the project changelog to view the release notes.
Developer Links
- My website: https://lvcabral.com
- My threads: @lvcabral
- My Bluesky: @lvcabral.com
- My X/twitter: @lvcabral
- My podcast: PODebug Podcast
- Check my other GitHub repositories
License
Copyright ยฉ 2019-2026 Marcelo Lv Cabral. All rights reserved.
Licensed under the MIT license.