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

@oniroproject/oniro-app

v0.8.1

Published

Cross-platform CLI for Oniro/OpenHarmony application development.

Readme

@oniroproject/oniro-app

Cross-platform command-line interface for Oniro / OpenHarmony application development. One binary drives the whole inner loop — install the SDK and toolchain, scaffold a project, sign and build it, boot the emulator, then install, launch, and drive the app over hdc — on Linux, macOS, and Windows.

It is built for non-interactive use (CI, scripts, agents): every command takes explicit flags, results print to stdout (plain text, or JSON with --json), progress and logs go to stderr, and the process exit code reflects success or failure. No prompts, no TTY assumptions.

This is the CLI frontend for @oniroproject/core — install that package instead if you want to call the same functionality from your own code (see its README for the API).

Install

Requires Node.js 20+. For oniro-app sign you also need a JDK on PATH (java, keytool).

npm install -g @oniroproject/oniro-app
oniro-app --help

Global flags: --version, --help. Run oniro-app <command> --help for the authoritative, up-to-date flags of any command.

Quick start

Set up the toolchain, scaffold an app, then build and run it on the emulator:

# One-time: toolchain + emulator
oniro-app sdk install 6.1
oniro-app cmdtools install
oniro-app emulator install

# Per project
oniro-app create --name HelloOniro --bundle com.example.hello \
                 --location ~/projects --sdk 23
cd ~/projects/HelloOniro
oniro-app sign
oniro-app build

# Run it
oniro-app emulator start --wait-for-hdc 300
oniro-app app install
oniro-app app launch

Once a device or emulator is connected you can inspect and drive it:

oniro-app devices --json
oniro-app screenshot -o shot.jpeg
oniro-app dump layout --json
oniro-app input --type click --x 200 --y 400
oniro-app watch --log 'error|fault' --for 5000 --json

Command reference

Environment & toolchain

Install commands are idempotent (they skip when already present); pass --force to reinstall.

sdk — manage OpenHarmony SDK installs

| Command | Description | | --- | --- | | sdk install <version> [--force] | Download and install an OpenHarmony SDK (e.g. 6.1). | | sdk list [--json] | List known SDK versions; an * marks installed ones. | | sdk remove <api> | Remove an installed SDK by API level (e.g. 18, 20). |

cmdtools — manage the OpenHarmony command-line tools (provides hvigorw, ohpm, hdc, codelinter)

| Command | Description | | --- | --- | | cmdtools install [--from-zip <path>] [--force] | Install the tools. --from-zip installs from a local archive instead of downloading (required on Windows/macOS — see Configuration). | | cmdtools status [--json] | Report whether the tools are installed and their version. Exits non-zero when not installed. | | cmdtools remove | Delete the configured command-line-tools directory. |

emulator — manage the Oniro emulator (QEMU-based)

| Command | Description | | --- | --- | | emulator install [--force] | Download and install the emulator. | | emulator start [options] | Start the emulator via the bundled launcher and detach, so the CLI can exit while it keeps running. | | emulator stop | Kill running emulator processes. | | emulator connect [--address <host:port>] | Attempt an hdc connection (default 127.0.0.1:55555). | | emulator remove | Delete the configured emulator directory. |

emulator start options:

| Flag | Description | | --- | --- | | --headless | Launch headless (VNC + telnet serial, no local window). Required in CI. | | --log <path> | Redirect launcher stdout/stderr to a file (default: discard). | | --wait-for-hdc <seconds> | Block until hdc connects, up to N seconds. 0 (default) returns as soon as the launcher spawns. | | --connect <host:port> | Override the launcher's hdc port-forward bind address. Pass 0.0.0.0:55555 on hosts where QEMU refuses to bind 127.0.0.1 (some CI runners). |

Project lifecycle

create — scaffold a new app from a template

All flags are required except where a default is shown (non-interactive). On success the project path is printed to stdout.

| Flag | Description | | --- | --- | | --name <name> | Project folder name (letters, digits, ._-, no slashes). | | --bundle <bundleName> | Bundle name in reverse-DNS form, e.g. com.example.myapp. | | --location <dir> | Parent directory the new project folder is created in. | | --sdk <api> | Target SDK API level (e.g. 18, 20). | | --template <id> | Template id (default EmptyAbility). | | --module <name> | Module folder name (defaults to the template default, usually entry). | | --overwrite | Replace the destination if it already exists. |

templates — inspect bundled templates

| Command | Description | | --- | --- | | templates list [--json] | List the project templates shipped with the CLI. |

sign — generate signing keys, certs, and signingConfigs

sign [project-dir] (defaults to the current directory). Requires java on PATH. Rewrites only the signingConfigs block of build-profile.json5 (other keys are preserved). The generated profile uses the SDK's built-in development cert (issuer=pki_internal) and its validity window — dev/local builds only, not distribution. See Signing apps that need system permissions for --apl / --acls.

| Flag | Description | | --- | --- | | --apl <level> | Ability Privilege Level: normal (default), system_basic, or system_core. | | --app-feature <feature> | hos_normal_app or hos_system_app. Defaults follow --apl. | | --acls <list> | Comma-separated permissions to write into the profile's acls.allowed-acls. | | --bootstrap | No-op if signing material is already present; otherwise generate it. | | --store-password <pwd> / --key-password <pwd> | Keystore passwords (default 123456, the SDK keystore password). |

build — build the app via hvigorw

build [project-dir] (defaults to the current directory). Modules build in parallel by default.

| Flag | Description | | --- | --- | | --product <product> | hvigor product name (default default). | | --module <module> | Restrict the build to a single module. | | --mode <mode> | hvigor build mode (e.g. release, debug). | | --task <task> | hvigor task to run (default assembleHap). | | --no-deps | Skip the automatic ohpm install --all when oh_modules/ is missing. | | --no-parallel | Build modules serially. | | --json | Emit the result (discovered HAPs grouped by module, warnings) as JSON. |

lint — run the OpenHarmony codelinter

lint [project-dir] (defaults to the current directory). Exits with the codelinter's exit code.

| Flag | Description | | --- | --- | | --files <globs...> | Specific files/globs to lint (default: the whole project). | | --json | Emit findings as JSON. |

Device & app

These commands target a connected device or emulator over hdc. Most accept --device <serial> to address a specific target; omit it to use the single connected device.

devices — list connected hdc devices

| Command | Description | | --- | --- | | devices [--json] | List connected targets (serial, connection, status). |

app — install, launch, and manage built apps

| Command | Description | | --- | --- | | app install [project-dir] [--hap <path>] | Install the signed .hap via hdc. --hap overrides the resolved path. | | app launch [project-dir] [--module <m>] [--ability <name>] | Launch the app. --ability defaults to the module's mainElement / first visible ability. | | app apply [project-dir] --bundle <b> [options] | Install a HAP and verify the running process took the change — handles sign-info mismatch, asset-cache invalidation, and persistent-bundle restart. | | app uninstall <bundle> [--device <serial>] | Uninstall an app by bundle name. | | app stop <bundle> [--device <serial>] | Force-stop an app by bundle name. |

app apply options:

| Flag | Description | | --- | --- | | --bundle <bundle> | Required. Bundle to apply changes to. | | --module <module> | Module to resolve the HAP from (multi-module projects). | | --hap <path> | Explicit .hap path (else resolved from the project + module). | | --installed-hap <path> | Local copy of the currently-installed HAP, to enable the asset-cache reboot diff. | | --system | Treat as a persistent/system bundle (refuses to uninstall on a sign-info mismatch). | | --allow-uninstall | Permit uninstalling a system bundle on sign-info mismatch (dangerous). | | --json | Emit the result (method, pre/post-install pid, cacheCleared) as JSON. |

file — transfer files to/from the device

| Command | Description | | --- | --- | | file send <local> <remote> [--device <serial>] | Push a local file to the device. | | file recv <remote> <local> [--device <serial>] | Pull a file from the device. |

reboot — reboot the device

| Flag | Description | | --- | --- | | --mode <mode> | system (default), bootloader, or recovery. | | --wait-bundle <bundle> | After a system reboot, wait until this bundle is running again. | | --timeout <ms> | Max time to wait for the bundle (default 180000). | | --device <serial> | Target device serial. For a TCP target (an emulator at host:port), passing this reconnects the session across the reboot. |

wait — wait for a device condition

Specify exactly one of --log, --boot, or --bundle.

| Flag | Description | | --- | --- | | --log <pattern> | Resolve when a hilog line (tag: message) matches this regex. | | --boot | Resolve when the device is reachable. | | --bundle <bundle> | With --log: filter to this bundle. Alone: wait until this bundle is running. | | --pid-of <name> | With --boot: also require this process to have a pid. | | --domain <domain> | With --log: hilog domain filter (e.g. 0xD003900). | | --timeout <ms> | Max wait (default 30000). | | --device <serial> | Target device serial. | | --json | With --log: emit the matched entry as JSON. |

watch — collect matching hilog lines for a fixed duration

| Flag | Description | | --- | --- | | --log <pattern> | Required. Regex tested against each line (tag: message). | | --for <ms> | Duration to watch (default 10000). | | --bundle <bundle> | Filter to this bundle. | | --domain <domain> | hilog domain filter. | | --no-dedup | Do not collapse consecutive duplicate lines. | | --device <serial> | Target device serial. | | --json | Emit the collected entries as JSON. |

screenshot — capture the screen as a JPEG

Default: writes the full-resolution raw JPEG. --grid reproduces the old MCP screenshot (downscaled + grid overlay). --contact-sheet captures a burst (default 8 frames) into one tiled sheet and prints per-frame diffs (0..1) on stdout — one image instead of N, pointing you at the frame where something changed.

| Flag | Description | | --- | --- | | -o, --output <file> | Output path (default screenshot.jpeg). | | --grid | Downscale to --max-dim and overlay a 10x10 grid (axes 0.0–1.0) for picking tap coordinates. | | --max-dim <px> | Longest-side cap for --grid / --contact-sheet (256–4096, default 1024). On its own, downscales without a grid. | | --contact-sheet | Capture a burst and composite it into one tiled image with per-frame change diffs. | | --burst <count> | Capture N frames; writes <base>-<i><ext> (or sets the --contact-sheet frame count). | | --interval <ms> | Delay between burst frames (default 50). | | --json | With --contact-sheet, emit the full result object as JSON on stdout. | | --device <serial> | Target device serial. |

dump — dump device state as JSON

| Command | Description | | --- | --- | | dump [layout] | Dump the on-screen UI layout (the default and currently only target) as a pruned, 0–1-normalized tree to stdout. |

| Flag | Description | | --- | --- | | --bundle <bundle> | Filter the layout to a single window/bundle. | | --raw | Return the unpruned tree. | | --device <serial> | Target device serial. |

input / gesture — inject UI input

input injects a single event in pixel coordinates via uitest uiInput:

| Flag | Description | | --- | --- | | --type <type> | Required. One of click, doubleClick, longClick, swipe, drag, fling, keyEvent, inputText. | | --x <px> / --y <px> | Start coordinate (click / swipe start). | | --x2 <px> / --y2 <px> | End coordinate (swipe / drag / fling). | | --speed <px-per-s> | Velocity for swipe / drag / fling. | | --key <key> | Key id or symbolic name (Back / Home / Power) for keyEvent. | | --text <text> | Text for inputText. | | --device <serial> | Target device serial. |

gesture injects a multi-waypoint path:

| Flag | Description | | --- | --- | | --waypoints <json> | Required. JSON array of pixel waypoints [{"x":..,"y":..,"t":..}] (t = ms from start). | | --hold-start <ms> / --hold-end <ms> | Hold at the first/last point before moving/lifting (routes via uinput). | | --device <serial> | Target device serial. |

oniro-app gesture --waypoints '[{"x":200,"y":600,"t":0},{"x":200,"y":200,"t":400}]'

Output & exit codes

  • Results → stdout. Plain text by default; --json (where supported) writes JSON.stringify(..., null, 2). Read/observe commands (sdk list, cmdtools status, templates list, devices, wait --log, watch, lint, app apply, build) accept --json (and screenshot with --contact-sheet); dump always emits JSON; action-only commands do not.
  • Progress & logs → stderr. stdout stays clean for machine consumers, so oniro-app create … > path.txt or oniro-app devices --json | jq work cleanly.
  • Exit code. 0 on success, non-zero on failure (the error message is written to stderr). Set ONIRO_DEBUG=1 to also print full stack traces.

Configuration

The CLI reads paths and URLs from environment variables. All are optional; defaults match the layout used historically by this project. ${userHome} inside any value expands to the current user's home directory.

| Variable | Default | Purpose | | --- | --- | --- | | ONIRO_SDK_ROOT_DIR | ~/setup-ohos-sdk | SDK install root | | ONIRO_CMD_TOOLS_PATH | ~/command-line-tools | Command-line tools install root | | ONIRO_EMULATOR_DIR | ~/oniro-emulator | Emulator install root | | ONIRO_HAP_PATH | entry/build/.../entry-default-signed.hap | Default .hap used by app install (relative to the project) | | ONIRO_SDK_URL_BASE | https://repo.huaweicloud.com/openharmony/os | Base URL for SDK downloads (point at a private/CI mirror) | | ONIRO_CMD_TOOLS_URL_LINUX | Huawei mirror, x64 5.1.0.840 | Override the Linux cmd-tools URL | | ONIRO_CMD_TOOLS_URL_WINDOWS | (unset) | Self-hosted Windows cmd-tools URL | | ONIRO_CMD_TOOLS_URL_MAC | (unset) | Self-hosted macOS cmd-tools URL | | ONIRO_EMULATOR_URL | Latest oniro_emulator.zip | Emulator download URL | | ONIRO_APPLICATION_CERT_PATH | (unset) | External application-cert chain to use when signing system apps | | ONIRO_DEBUG | (unset) | Set to 1 for full stack traces on error |

Command-line tools on Windows / macOS. The Huawei mirror only publishes a Linux build of the command-line tools. On Windows and macOS you must either download the ZIP manually from the Huawei developer portal and install it with oniro-app cmdtools install --from-zip path/to/commandline-tools-<platform>.zip, or host the archive yourself and set ONIRO_CMD_TOOLS_URL_WINDOWS / ONIRO_CMD_TOOLS_URL_MAC so cmdtools install can fetch it.

Signing apps that need system permissions

oniro-app sign defaults to --apl normal / --app-feature hos_normal_app, which is fine for ordinary apps. Apps that request permissions above normal (anything with system_basic or system_core availability — e.g. ohos.permission.GET_WIFI_INFO_INTERNAL, ohos.permission.ACCESS_PIN_AUTH) need a higher APL, otherwise bm install fails with grant request permissions failed.

oniro-app sign --apl system_basic           # implies --app-feature hos_system_app
oniro-app sign --apl system_core            # implies --app-feature hos_system_app
oniro-app sign --apl system_basic --app-feature hos_normal_app  # explicit override

When --apl is system_basic or system_core, the HAP signing key automatically switches from OpenHarmony Application Profile Release to OpenHarmony Application Release, and the profile's distribution-certificate is set to the matching CA-signed OpenHarmony Application Release leaf (shipped as a code resource — the SDK only bundles the Profile Release chain). This matches the convention used by every preinstalled OpenHarmony system app's signature/ directory and is required to get past BMS's parse-profile-prop check on install.

Some privileged permissions (e.g. ohos.permission.REBOOT, ohos.permission.INJECT_INPUT_EVENT, ohos.permission.CAPTURE_SCREEN) must additionally appear in the profile's acls.allowed-acls. Pass them via --acls:

oniro-app sign --apl system_core \
    --acls ohos.permission.REBOOT,ohos.permission.INJECT_INPUT_EVENT

The signingConfigs block written to build-profile.json5 mirrors the names used by the project's products[*].signingConfig (e.g. applications/standard/systemui uses release, launcher uses default). If the project has no products section, default is used.

Programmatic use

Everything the CLI does is exposed as a library by @oniroproject/core, so you can embed the same SDK/build/sign/emulator/hdc functionality in an editor extension, an MCP server, or your own tooling. See that package's README for the API reference.

License

Apache-2.0 — see LICENSE.