npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

roku-perfetto

v1.0.2

Published

Library for Roku Perfetto tracing — ECP control, WebSocket recording, trace analysis with PerfettoSQL, and AI-friendly performance reports

Readme

roku-perfetto

Library for Roku Perfetto tracing — ECP control, WebSocket recording, trace analysis with PerfettoSQL, and AI-friendly performance reports.

Requires Roku OS 15.1+ with Perfetto tracing support.

Install

npm install roku-perfetto

Quick Start

Record a trace

import { PerfettoClient } from 'roku-perfetto';

const client = new PerfettoClient('192.168.1.86');
await client.enable('dev');
await client.startRecording('trace.perfetto');
// ... interact with the app ...
const result = await client.stopRecording();
console.log(`Saved ${result.bytesWritten} bytes to ${result.filePath}`);

Analyze a trace

import { openTrace } from 'roku-perfetto';

const analyzer = await openTrace('trace.perfetto');
const summary = await analyzer.performanceSummary();
console.log(summary.overallAssessment);
console.log(summary.frameDrops.suggestion);
await analyzer.close();

Run a custom PerfettoSQL query

import { openTrace } from 'roku-perfetto';

const analyzer = await openTrace('trace.perfetto');
const result = await analyzer.query(
  "SELECT * FROM slice WHERE name = 'swapBuffers' ORDER BY dur DESC LIMIT 10"
);
console.log(result.rows);
await analyzer.close();

Compare two traces

import { comparePerfetto } from 'roku-perfetto';

const report = await comparePerfetto('before.trace', 'after.trace');
console.log(report.summary);
console.log(`Regressions: ${report.regressions.length}`);
console.log(`Improvements: ${report.improvements.length}`);

CLI

# Enable tracing on a device
roku-perfetto enable 192.168.1.86 dev

# Record a 30-second trace
roku-perfetto record --host 192.168.1.86 --channel dev --duration 30 -o trace.perfetto

# Full performance summary
roku-perfetto analyze summary trace.perfetto

# Specific analysis
roku-perfetto analyze frame-drops trace.perfetto --threshold 16
roku-perfetto analyze key-events trace.perfetto
roku-perfetto analyze observers trace.perfetto
roku-perfetto analyze rendezvous trace.perfetto
roku-perfetto analyze set-fields trace.perfetto
roku-perfetto analyze threads trace.perfetto

# JSON output (for programmatic consumption)
roku-perfetto analyze summary trace.perfetto -f json

# Raw PerfettoSQL query
roku-perfetto query trace.perfetto "SELECT * FROM slice WHERE name = 'keyEvent' ORDER BY dur DESC"

# Compare two traces
roku-perfetto compare before.trace after.trace

# Trace metadata
roku-perfetto info trace.perfetto

API Reference

PerfettoClient

Handles ECP communication and WebSocket trace recording with a Roku device.

| Method | Description | |--------|-------------| | enable(channelId?) | Enable Perfetto tracing for a channel via ECP POST | | startRecording(filePath, channelId?) | Open WebSocket and stream binary trace data to a file | | stopRecording() | Close WebSocket, finalize file, return recording stats | | isRecording() | Check if a recording session is active | | getSession() | Get current session info (host, bytes, duration) |

RokuAnalyzer

High-level Roku-specific trace analysis with AI-friendly suggestion fields.

| Method | Description | |--------|-------------| | RokuAnalyzer.open(tracePath, opts?) | Open a trace file and return an analyzer | | performanceSummary(opts?) | Full report: frame drops + key events + observers + rendezvous + threads | | analyzeFrameDrops(opts?) | swapBuffers duration analysis with drop rate | | analyzeKeyEvents(opts?) | OnKeyEvent duration analysis | | analyzeObservers(opts?) | observer.callback analysis | | analyzeRendezvous(opts?) | Cross-thread synchronization analysis | | analyzeSetFields(opts?) | roSGNode.setField call analysis | | analyzeThreads(opts?) | Per-thread overview with top slices | | traceInfo() | Trace duration, slice count, thread count | | query(sql) | Run a raw PerfettoSQL query | | close() | Shut down the trace processor |

TraceProcessor

Low-level wrapper around the Perfetto trace_processor binary.

| Method | Description | |--------|-------------| | TraceProcessor.open(tracePath, opts?) | Spawn trace_processor with --httpd, wait for ready | | query(sql) | Execute PerfettoSQL, return structured rows | | status() | Check trace processor status | | close() | Kill the trace processor process |

comparePerfetto(beforePath, afterPath, opts?)

Compare two trace files and return a ComparisonReport with metric deltas, regressions, and improvements.

openTrace(tracePath, opts?)

Convenience function that opens a trace and returns a ready-to-use RokuAnalyzer.

Analysis Modes

| Mode | What it checks | Key metric | |------|---------------|------------| | summary | Everything below combined | overallAssessment | | frame-drops | swapBuffers durations | Frame drop rate % | | key-events | keyEvent handler durations | Avg response time | | observers | observer.callback durations | Slow callback count | | rendezvous | Cross-thread sync points | Long rendezvous count | | set-fields | roSGNode.setField calls | Avg setField duration | | threads | Per-thread activity overview | Top slices by duration |

Built-in PerfettoSQL Queries

The library exports the Roku-specific queries as constants for custom use:

import { FRAME_DROPS_QUERY, KEY_EVENTS_QUERY, OBSERVER_QUERY } from 'roku-perfetto';

trace_processor Binary

The library automatically downloads the Perfetto trace_processor prebuilt binary from https://get.perfetto.dev/trace_processor on first use. The binary is cached at ~/.roku-perfetto/bin/trace_processor.

Supported platforms: macOS and Linux.

You can provide a custom binary path:

const analyzer = await RokuAnalyzer.open('trace.perfetto', {
  binPath: '/usr/local/bin/trace_processor',
});

Prerequisites

  • Node.js 18+
  • Roku OS 15.1+ on the target device
  • For sideloaded apps: run_as_process=1 in the manifest
  • For production/beta apps: device must be keyed with the app signing key

License

MIT