Roku ECP,
from TypeScript.
Lightweight TypeScript client for the Roku External Control Protocol.
No WebDriver. No Appium. No Selenium. No Java. Just HTTP to port 8060.
npm install @danecodes/roku-ecp The whole Roku,
over HTTP.
Discover devices, press remote keys, launch apps, inspect the UI tree, capture screenshots, read the debug console. One package, zero native dependencies.
Built as the foundation for Uncle Jesse and roku-mcp.
import { EcpClient, Key, parseUiXml,
findElement, findFocused } from '@danecodes/roku-ecp';
// Discover or connect by IP
const roku = await EcpClient.discover();
// const roku = new EcpClient('192.168.0.30');
// Remote control
await roku.press(Key.Down, { times: 3 });
await roku.press(Key.Select);
await roku.type('breaking bad');
// Inspect the UI tree with CSS selectors
const xml = await roku.queryAppUi();
const tree = parseUiXml(xml);
const button = findElement(tree, 'AppButton#play_button');
console.log(button?.attrs.text); // "Play"
// Check what's focused
const focused = findFocused(tree);
console.log(focused?.tag, focused?.attrs.name); Everything in the Roku ECP. Nothing else.
SSDP Discovery
Find Roku devices on your network automatically. No hardcoded IPs needed.
Remote & Touch
Key presses, repeated inputs, character typing, and touch coordinates over HTTP.
App Lifecycle
Launch, install, deep link, send input params, and close apps programmatically.
Device Queries
Query device info, active app, installed apps, media player state, and channel performance.
UI Tree Inspection
Parse SceneGraph XML and query with CSS-like selectors. Tag, name, attributes, descendants, nth-child, siblings.
Screenshots
Capture PNG screenshots from developer mode devices with digest auth.
Sideloading
Deploy dev channel builds from zip files or directories. No manual upload needed.
Debug Console
Read BrightScript console output on port 8085. Send commands like bt for backtraces.
Log Parsing
Structured parsing via roku-log — errors, crashes, backtraces, real-time streaming, and aggregation.
Wait Helpers
waitForElement, waitForFocus, waitForApp, waitForStable — poll until conditions are met.
Typed Errors
EcpTimeoutError, EcpHttpError, EcpAuthError — clean error handling for every failure mode.
import { parseUiXml, findElement, findElements,
findFocused, formatTree } from '@danecodes/roku-ecp';
const tree = parseUiXml(await roku.queryAppUi());
findElement(tree, 'AppButton#play'); // tag#name
findElement(tree, '#titleLabel'); // by name
findElement(tree, 'HomePage HomeHeroCarousel');// descendant
findElement(tree, 'LayoutGroup > AppLabel'); // direct child
findElement(tree, 'AppButton:nth-child(1)'); // nth-child
findElement(tree, 'Module + Module'); // adjacent sibling
findElements(tree, 'AppButton'); // all matches
findFocused(tree); // focused node
console.log(formatTree(tree, { maxDepth: 3 })); CSS selectors on SceneGraph.
Query Roku's XML UI tree with familiar syntax. Tag names, IDs, descendants, direct children, attribute selectors, nth-child, adjacent siblings.
No XPath. No custom query language. If you know CSS selectors, you know this.
API at a Glance
| Method | Description |
|---|---|
discover() | Find Roku devices via SSDP M-SEARCH |
new EcpClient(ip) | Connect by IP with configurable port, password, timeout, cooldowns |
keypress / press / type / touch | Remote control input, touch coordinates, repeat and delay |
launch / deepLink / install | App lifecycle management |
queryDeviceInfo() | Device model, firmware, serial, network info |
queryActiveApp() | Currently running app |
queryAppUi() | Raw SceneGraph XML tree |
queryMediaPlayer() | Playback state, position, duration, buffering |
sideload / takeScreenshot | Dev channel deployment and screen capture |
readConsole / sendConsoleCommand | BrightScript debug console (port 8085) |
parseUiXml / findElement | CSS selector engine for SceneGraph nodes |
parseConsoleForIssues | Structured error/crash/exception detection |
waitFor / waitForElement / waitForFocus | Poll until conditions are met with configurable timeout |
LogParser / LogStream / LogSession | Structured log parsing, real-time streaming, aggregation |
EcpHttpError / EcpTimeoutError | Typed errors for clean catch handling |
Part of the @danecodes Roku Toolchain
roku-ecp
Low-level ECP client. The foundation layer.