Open Source

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

MethodDescription
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

One install. Full control.

Start talking to your Roku in five minutes.