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

@danecodes/roku-screenshot

v0.1.0

Published

Capture, diff, and process screenshots from Roku devices

Readme

roku-screenshot

npm version License: MIT

Capture, diff, and process screenshots from Roku devices. Built on @danecodes/roku-ecp and sharp.

Install

npm install @danecodes/roku-screenshot

CLI

# Basic capture
roku-screenshot -d 192.168.0.30 -o screen.png

# Auto-discover device on network
roku-screenshot -o screen.png

# Resize to 50%
roku-screenshot -d 192.168.0.30 --resize 50 -o thumb.png

# Resize to specific width
roku-screenshot -d 192.168.0.30 --resize 960 -o half.png

# Crop a region (left, top, width, height)
roku-screenshot -d 192.168.0.30 --crop 0,0,960,540 -o top-left.png

# Convert to JPEG
roku-screenshot -d 192.168.0.30 -o screen.jpg

# Visual regression diff
roku-screenshot -d 192.168.0.30 --diff baseline.png -o changes.png
# exits 0 if identical, 1 if changed

# Watch mode — capture every 5 seconds
roku-screenshot -d 192.168.0.30 --watch 5 -o captures/screen.png
# creates captures/screen-001.png, screen-002.png, ...

Set ROKU_IP environment variable to skip --device every time.

Library

import { capture, diff, processImage, watch } from '@danecodes/roku-screenshot';
import { EcpClient } from '@danecodes/roku-ecp';

const roku = new EcpClient('192.168.0.30');

// Basic capture
const png = await capture(roku);

// Capture with processing
const thumb = await capture(roku, {
  resize: 50,        // 50% scale
  format: 'jpeg',
  quality: 85,
});

// Crop
const cropped = await capture(roku, {
  crop: { left: 0, top: 0, width: 960, height: 540 },
});

// Visual regression diff
const before = await capture(roku);
// ... do something on the Roku ...
const after = await capture(roku);

const result = await diff(before, after);
console.log(result.identical);      // false
console.log(result.changePercent);  // 12.5
console.log(result.changedPixels);  // 259200

// Save the diff image (changed pixels highlighted in red)
await writeFile('diff.png', result.image);

// Watch mode
const ac = new AbortController();
await watch(roku, 5000, async (image, seq) => {
  await writeFile(`frame-${seq}.png`, image);
}, { signal: ac.signal });

API

capture(client, options?)

Capture a screenshot and optionally process it. Returns a Buffer.

| Option | Type | Description | |--------|------|-------------| | resize | number | Percentage (1-100) or pixel width (>100) | | crop | { left, top, width, height } | Crop region | | format | 'png' \| 'jpeg' \| 'webp' | Output format (default: png) | | quality | number | JPEG/WebP quality 1-100 (default: 90) |

diff(imageA, imageB, options?)

Pixel diff two images. Returns a DiffResult.

| Option | Type | Description | |--------|------|-------------| | threshold | number | Per-channel tolerance 0-255 (default: 25) | | highlightColor | [r, g, b, a] | Color for changed pixels (default: red) |

interface DiffResult {
  image: Buffer;          // PNG with changes highlighted
  changedPixels: number;
  totalPixels: number;
  changePercent: number;  // 0-100
  identical: boolean;
}

watch(client, intervalMs, callback, options?)

Capture screenshots on a loop. Supports AbortSignal for cancellation.

processImage(buffer, options?)

Process an existing image buffer (same options as capture).

Requirements

  • Roku device in developer mode with a sideloaded channel
  • Node.js 18+

License

MIT