The rk device command manages and queries Roku devices.

This document describes LAN devices, which are Rokus on your network. The command lists Roku Cloud Emulator (RCE) devices beside them, but RCE devices are registered in a file of their own and have their own commands (add --rce, start, stop, status, snapshot, input, and so on). The subcommands below that take a device also accept an RCE device as rce:<name> where it makes sense, and the other subcommands refuse it with DEVICE_KIND_UNSUPPORTED. See Roku Cloud Emulator devices for more information.

Device configuration model

The tooling uses a layered model to support shared device lists across multiple worktrees. The model has the following layers:

  • The central device list is the ~/roku-dev-config.json file:
    • The file holds the canonical devices[] definitions.
    • The file holds shared defaults such as defaultPassword.
    • The file holds LAN devices only. The tooling keeps Roku Cloud Emulator registrations in ~/roku-rce-devices.json, beside the RCE token, and never in a local file. See Before you start for more information.
  • The per-worktree override is the nearest .roku/roku-dev-config.json file, which the tooling searches for upward from the current directory. The ROKU_DEV_CONFIG_CEILING variable stops the search at that directory. The SDK's own tests set it so that they never read your .roku/ directory.
    • The file stores the activeDeviceId pointer for that worktree.
    • The file can also contain legacy devices[] for backward compatibility.

Resolving the device list

The tooling resolves the device list in the following order:

  1. Local legacy mode: If the nearest local file has a non-empty devices[], the tooling uses that local list.
  2. Layered mode: If ~/roku-dev-config.json exists, the tooling uses the home devices[] and applies the local activeDeviceId override when present.
  3. Local pointer-only mode: If the local file has only activeDeviceId and the home file is missing, a persistent device list is not available.
  4. Env fallback: When a config file does not exist at any level, the tooling uses ROKU_DEV_TARGET and ROKU_DEV_PASSWORD as an ephemeral runtime target.

ROKU_DEV_PASSWORD is also the password for --host when --password is not given (--password wins; an empty or whitespace-only value counts as unset). It does not apply to a stored or --device target.

Writing device definitions

The device commands write to the following files:

  • The rk device add, update, and rm commands write device definitions to the home store when it exists, to the local legacy store when present, and otherwise to a new ~/roku-dev-config.json file.
  • The rk device set-active and clear-active commands write only the local activeDeviceId pointer.

Understanding migration behavior

Migration works as follows:

  • Existing local legacy files continue to work, and the tooling does not force a migration.
  • If both legacy devices[].active and activeDeviceId are present, activeDeviceId takes precedence.
  • The env fallback is runtime-only and does not persist devices to disk.

Synopsis

The following syntax shows how to run the command:

rk device <subcommand> [options]
rk device <subcommand-tree> [options]   # For example, device lease acquire or device pool status

The subcommands share the --json option, which produces JSON output for supported subcommands and suppresses the ASCII banner.

Nested subcommands

In addition to the flat subcommands that this document describes, rk device has two nested subcommand groups that interact with the device-pool seam:

  • rk device lease: Acquires, releases, and reaps a device lease. You can use it for parallel CI and shared-device coordination. It is available as soon as @roku-sdk/tooling is loaded. The local provider is built in, and Roku-internal tooling or custom extensions add other providers.
  • rk device pool: Shows the status of the currently configured pool's inventory and live state.

Subcommands

The following sections describe each subcommand.

ls

The ls subcommand lists configured devices and indicates the active device:

rk device ls [--rce] [--json]
rk device ls --org [--json]

The ls subcommand behaves as follows:

  • The text output is a table with the columns Active, Name, IP, ID, and Tags, with the title "Device list". Once you register an RCE device, the table adds Kind and Status columns, and a line says where the RCE token comes from.
  • With --json, the command returns { devices, activeId, source } (the output omits the password). Every row has kind: "lan" or kind: "rce", and RCE rows carry status instead of ip. The command reports anything that it could not read on stderr.
  • The --rce option lists only the registered RCE devices, and the --org option lists every device in the RCE organization. See Roku Cloud Emulator devices for more information.
  • If no devices are configured, the command prints a guidance message to add one.

set-default-password

The set-default-password subcommand sets the default password for all devices:

rk device set-default-password <password>

The set-default-password subcommand behaves as follows:

  • Updates defaultPassword in the configuration file.
  • The password cannot be an empty string.
  • If the command cannot read or write the config file, it shows an error.

store-path

The store-path subcommand prints the effective device config source path:

rk device store-path [--json]

The store-path subcommand behaves as follows:

  • The text output prints the effective source path.
  • With --json, the command returns { path }.
  • If no config exists at any level, JSON mode returns { path: null }.

add

The add subcommand adds or updates a device in the canonical device list store (home-preferred, with legacy fallback):

rk device add <ip> [--name <name>] [--id <id>] [--tag <t> ...] [--json]

The add subcommand behaves as follows:

  • Validates the IP format.
  • Generates a stable device id from the IP and optional name unless you provide --id.
  • De-duplicates by id and IP.
  • If this is the first device that you add and no device is active, the command sets it as the active device automatically. An active RCE device stays active.
  • Refuses a name that starts with rce: (DEVICE_NAME_RESERVED) because that prefix selects an RCE device.
  • The --json option prints { device: { id, ip, name, tags }, active }.
  • Supports adding one or more tags through repeated --tag <t> flags and removes duplicates.
  • Warns if the local .roku/ directory is not gitignored.

update

The update subcommand updates an existing device's properties:

rk device update <target> [--name <name>] [--id <id>] [--ip <ip>] [--password <pwd>] [--tag <t> ...] [--json]

The <target> argument can be a device ID, an IP address, or an exact name (case-insensitive).

The update subcommand behaves as follows:

  • Updates the specified device if found.
  • Supports adding tags through repeated --tag <t> flags.
  • Shows the updated device list after successful update.
  • An RCE device (rce:<name>) takes its own options instead and prints only what changed (--json: { device }). See Registering a device for more information.

rm

The rm subcommand removes a device from the configuration:

rk device rm <target>

The <target> argument can be a device ID, an IP address, or an exact name (case-insensitive).

The rm subcommand behaves as follows:

  • Removes the specified device if found.
  • If the removed device was active, the active device is unset afterward.
  • For an RCE device (rce:<name>), the command forgets only the registration. It does not stop or change the device in RCE.
  • Shows the updated device list after successful removal.

set-active

The set-active subcommand sets a device as the active device:

rk device set-active <target>

The <target> argument can be a device ID, an IP address, or an exact name (case-insensitive).

The set-active subcommand behaves as follows:

  • Sets the specified device as active. The <target> argument may also be rce:<name>.
  • Only one device can be active at a time, LAN or RCE.
  • Shows the updated device list after successful activation.

ip

The ip subcommand gets the IP address of the active device:

rk device ip [--json]

The ip subcommand behaves as follows:

  • The text output prints the IP address with the title "Active device IP".
  • With --json, the command returns { ip } without banner text.
  • If an active device is not configured, the command prints an error and exits with a non-zero status.
  • An active RCE device does not have an IP address; the command says so and exits with a non-zero status.

open

The open subcommand opens the active device's web UI in the default browser:

rk device open

The open subcommand behaves as follows:

  • Opens http://<active-device-ip> in the default browser.
  • If an active device is not configured, the command prints an error and exits with a non-zero status.

reboot

The reboot subcommand reboots the target Roku device:

rk device reboot [<selector>] [--json]

The <selector> argument can be a device ID, an IP address, or an exact name (case-insensitive). If you omit it, the command uses the active device.

The reboot subcommand behaves as follows:

  • Sends POST /plugin_swup with mysubmit=Reboot.
  • Uses the device password from the device store.
  • If a password is not configured for the selected device, the command prints an error.
  • Requires Roku OS 15.0.4 or later.
  • The --json option returns a machine-readable success or error payload.

dev-id

The dev-id subcommand prints the developer ID registered on the target Roku device:

rk device dev-id [<selector>] [--json]

The <selector> argument can be a device ID, an IP address, or an exact name (case-insensitive). If you omit it, the command uses the active device.

The dev-id subcommand behaves as follows:

  • Queries GET /query/device-info through the existing ECP path.
  • Reads the keyed-developer-id field from the response.
  • If the field is missing or empty, returns null.
  • If the device cannot be reached or the query fails, the command prints an error and exits with a non-zero status.
  • The --json option returns { devId }.

check-update

The check-update subcommand triggers a firmware update check on the target Roku device:

rk device check-update [<selector>] [--json]

The <selector> argument can be a device ID, an IP address, or an exact name (case-insensitive). If you omit it, the command uses the active device.

The check-update subcommand behaves as follows:

  • Sends POST /plugin_swup with mysubmit=CheckUpdate.
  • Uses the device password from the device store.
  • If a password is not configured for the selected device, the command prints an error.
  • Requires Roku OS 15.0.4 or later.
  • The --json option returns a machine-readable success or error payload.

Understanding the devices store

See Device configuration model for more information about precedence and migration.

Schema and credentials

The device store has the following structure:

  • The store contains devices: Device[] and the required defaultPassword for sideloading and debugging.
  • Each Device can define password. When you omit it, the command uses defaultPassword.
  • The username is always rokudev and cannot be changed.
  • Commands that talk to device endpoints (including reboot and firmware update checks) read passwords from the device store. If a password is not configured, those commands fail with an error.
  • The SDK provides a VS Code JSON Schema mapping for both .roku/roku-dev-config.json and roku-dev-config.json.

Device identification

Devices are identified as follows:

  • Each device has a stable id derived from its attributes (IP and optionally name).
  • Subcommands that accept a target support id, ip, or exact name (case-insensitive).
  • When a LAN device and an RCE device share a name, the name selects the LAN device and prints a warning on stderr. You can use rce:<name> to select the RCE device.

Examples

The following examples show common ways to use the subcommands:

# Add two devices (first one becomes active automatically)
rk device add 192.168.1.10 --name Office
rk device add 192.168.1.11 --name LivingRoom

# Set default credentials for all devices (required for sideloading/debugging)
rk device set-default-password aaaaaaaa

# Update a device's name and add tags
rk device update Office --name HomeOffice --tag work --tag primary

# Note: To configure passwords, edit ~/roku-dev-config.json
# and add "defaultPassword" at the top level, or "password" for specific devices

# List devices (text and JSON)
rk device ls
rk device ls --json

# Set the active device by name (shows updated device list)
rk device set-active LivingRoom

# Open the active device web UI in the browser
rk device open

# Reboot the active device
rk device reboot

# Trigger a firmware update check for a named device
rk device check-update LivingRoom

# Print the developer ID of the active device
rk device dev-id

# Print developer ID as JSON for a named device
rk device dev-id LivingRoom --json

# Get the device IP (JSON)
rk device ip --json

# Show where the devices store is located (JSON)
rk device store-path --json

The following example shows the structure of the central ~/roku-dev-config.json file:

{
    "defaultPassword": "aaaaaaaa",
    "devices": [
        {
            "id": "office-192-168-1-10",
            "name": "Office",
            "ip": "192.168.1.10",
            "active": true
        },
        {
            "id": "livingroom-192-168-1-11",
            "name": "LivingRoom",
            "ip": "192.168.1.11",
            "active": false
        }
    ]
}

RCE registrations go in ~/roku-rce-devices.json instead. The roku-rce-devices.example.json file shows an example.

The following example shows the local per-worktree pointer file (.roku/roku-dev-config.json):

{
    "activeDeviceId": "livingroom-192-168-1-11"
}

Notes

The following notes apply to the rk device command:

  • When you specify --json for any command that supports JSON, the command suppresses the ASCII banner to ensure clean machine-readable output.
  • The older devices command is deprecated and removed in favor of the consolidated device command family.
  • The CLI does not read device IP from roku-config.ts; the devices store is the canonical source for device selection.

Migrating from older configs

The following notes apply to older configs:

  • The tooling still reads default: true on a device for backward compatibility.
  • Legacy local lists with non-empty devices[] remain supported as they are.
  • New pointer files use activeDeviceId to select the active device for each worktree.

Related documentation


Did this page help you?