HarmOS Volt. hvolt defines its own project layout — one hvolt.toml per module over a
flat source tree — and builds it with its own toolchain: ArkTS compilation, HAP packing, signing
and the device protocol are all implemented in this repository. No
build-profile.json5, module.json5, oh-package.json5 or build/ tree is written by hand, and
no external build tool, package manager, JDK, or device binary is invoked.
- Features
- Install
- Quick start
- Example projects
- Project layout
- Commands
- Requirements
- Signing and AGC
- DevEco Studio (optional)
- Development
- Project status
- Contributing
- Acknowledgements
- Flat project layout — one
hvolt.tomlper module oversrc/andresources/; no hand-written build files, no generated standard project - Build chain — compile ArkTS → pack HAP → sign → install → launch, all from one CLI
- SDK management — list remote versions, download, import, switch, remove
- Native (C++/NAPI) — declare a native module as a dependency; CMake and the types bridge are wired automatically
- Package gate and introspection —
hvolt check(reads the archive itself),hvolt hap info(reads the package itself) - Signing — OpenHarmony localSign (public test chain) in this tree; AppGallery Connect remote signing through an optional backend that is not published here
- Devices — native device protocol (USB + TCP), cross-machine install targets, hilog, screenshot, UI tree dump, file transfer both ways, uninstall
- Emulator — list / start / stop / create / delete / images / license
- Editor support —
hvolt lsp --stdioserves ArkTS completion, hover, signature help, definition, references, outline, rename, semantic highlighting, inlay hints and call hierarchy out of the TypeScript build inside the installed SDK, rewrites ArkUI blocks so the service has scope insidebuild(), and publishes diagnostics from type checking, unsaved buffers included (see lsp/DESIGN.md) - Few dependencies — Rust to build; the SDK compilers (
es2abc,restool) at runtime. No JDK, no external build tool, no package manager, no device binary
hvolt lsp --stdio is a language server; the VS Code client lives in its own repository,
hvolt-project/hvolt-vscode.
hvolt lsp --stdio # any LSP client can drive this
hvolt lsp --stdio --log-file /tmp/lsp.log # record the protocol trafficWhat it provides: ArkTS syntax highlighting (TypeScript grammar + ArkTS rules), completion, hover,
signature help, definition, references, outline, rename, semantic highlighting, inlay hints,
call hierarchy, folding, workspace symbols and quick fixes from the SDK's own TypeScript build
(ArkUI blocks are rewritten first, so build() has scope); diagnostics from
type checking, unsaved buffers included, mapped onto the flat sources;
hvolt.toml key completion, route completion, validation and dependency navigation; commands for
build, sign, install, screenshot and log. Design and measurements: lsp/DESIGN.md.
Version numbers are SDK version + a release counter: 26.0.0-0 is the first release for SDK
26.0.0, 26.0.0-1 the next, and an SDK bump moves the whole number (26.1.0-0, 27.0.0-0).
hvolt --version prints the same number with the SDK it defaults to:
$ hvolt --version
hvolt 26.0.0-0 (SDK 26.0.0)
A project pins its own SDK in hvolt.toml (sdk_version = "26.0.0"), so upgrading the tool never
changes what an existing project targets.
npm install -g @hvolt/climacOS arm64 and Linux x86-64 without Node.js:
curl -fsSL https://raw.githubusercontent.com/hvolt-project/hvolt/main/install.sh | shWindows PowerShell:
irm https://raw.githubusercontent.com/hvolt-project/hvolt/main/install.ps1 | iexBoth scripts download the release archive for the current platform, verify it against the release's
SHA256SUMS.txt, and install hvolt into ~/.local/bin (%LOCALAPPDATA%\hvolt\bin on Windows);
override with HVOLT_PREFIX / -Prefix, or pin a version with HVOLT_VERSION / -Version.
From source:
cargo install --path . # needs Rust 1.85+Archives are also published as release assets (hvolt-<version>-<platform>.tar.gz|.zip) for packaging.
# Create a project (this is the format hvolt defines)
hvolt init my-app
cd my-app
# Provide an SDK and the build tools once
hvolt sdk download 26.0.0.38 # or: hvolt sdk set /path/to/an/existing/sdk
# Build, sign, push, launch
hvolt runBoth are the canonical reference for the format — each has a README.md next to its sources.
| Project | What it shows |
|---|---|
examples/hello-world |
The smallest project: one module, one UIAbility, one page |
examples/hello-native |
The same app plus a C++/NAPI native module (mylib/): CMakeLists.txt, napi_init.cpp, Index.d.ts, called from ArkTS |
cd examples/hello-world && hvolt build
cd examples/hello-native && hvolt build # C++ compiled through CMake + NDKOne application root, one directory per module:
my-app/
├── hvolt.toml # application config (bundle, version, members, dependencies)
├── src/ # a module
│ ├── hvolt.toml # module config (entry ability, routes, device types)
│ ├── EntryAbility.ets
│ └── pages/Index.ets
├── resources/base/ # element/{string,color,float}.json + media/
└── mylib/ # optional native module (see hello-native)
├── hvolt.toml # name / type = "native" / types / version
├── CMakeLists.txt
├── napi_init.cpp
└── Index.d.ts
hvolt build compiles that tree directly: the ArkTS sources are transpiled and turned into
modules.abc, the resources are compiled by the SDK's restool, and the parts are packed into a
HAP under build/hvolt-out. The flat tree is the source of truth; build/ is generated output.
[app]
bundle = "com.example.app"
name = "my-app"
version = "1.0.0"
vendor = "example"
icon = "$media:layered_image"
sdk_version = "26.0.0"
compile_sdk_version = "26.0.0"
members = ["src"] # module directories
[app.signing] # optional
store_file = "signing/debug/debug.p12"
store_password = "..."
key_alias = "debugKey"
key_password = "..."
certpath = "signing/debug/debug.cer"
profile = "signing/debug/debug.p7b"
sign_alg = "SHA256withECDSA"
[dependencies]
# libhello = { path = "mylib", version = "1.0.0" } # type = "native" → C++/NAPI module[module]
name = "src"
routes = ["pages/Index.ets"]
entry = "EntryAbility.ets"
device_types = ["phone", "tablet", "2in1", "car"]A native module is a directory with its own hvolt.toml (type = "native"), a CMakeLists.txt,
C++ sources and an Index.d.ts type declaration. It is declared only in [dependencies] —
never in members. The module name fixes the artifact: name = "hello" → libhello.so, which is
also what the CMake target, nm_modname and the ArkTS import must say. The build compiles the
sources with the SDK toolchain, generates types/<dependency>/, and wires the resulting .so
into the packed package.
| Command | Description |
|---|---|
hvolt init <name> |
Scaffold a new project (this layout) |
hvolt migrate [--from <dir>] [--out <dir>] [--dry-run] |
Turn a DevEco project into this layout: only hvolt.toml, sources and resources survive |
hvolt build |
Compile ArkTS, pack the HAP and sign it (own toolchain) |
hvolt run [device] [-d <device>] |
Build + sign + push + launch in one shot |
hvolt clean |
Remove build artifacts |
| Command | Description |
|---|---|
hvolt check [--size-limit 50K] |
Package quality gate (duplicates, big files, suffix sizes, read from the archive) |
hvolt hap info [path] |
bundle / version / abilities / permissions, read from the package itself |
| Command | Description |
|---|---|
hvolt sdk info |
Show SDK configuration and detected paths |
hvolt sdk list-remote |
List available SDK versions (per-component sizes) |
hvolt sdk download <version> |
Download and install an SDK version |
hvolt sdk import <path> |
Import an existing SDK directory into ~/.hvolt/sdk/ |
hvolt sdk list |
List installed versions |
hvolt sdk use <version> |
Switch the active version |
hvolt sdk remove <version> --yes |
Remove an installed version (irreversible; --yes required) |
hvolt sdk set <path> [--global] |
Use the SDK at <path> for this project (or for all projects) |
| Command | Description |
|---|---|
hvolt config get |
Show all configuration values |
hvolt config set <key> <value> |
Keys: sdk_path, node_home, sdk_support_version, device_target, device_host |
hvolt config unset <key> |
Remove a configuration value |
| Command | Description |
|---|---|
hvolt sign [HAP] |
Remote signing via AppGallery Connect — needs the optional backend (see Signing and AGC). With HAP, signs that bare package with the localSign test chain and writes <name>-signed.hap in the package's own directory (an input ending in -unsigned becomes -signed); an already-signed package is refused. Pass --p12/--profile/--cert to sign it with your own materials instead |
hvolt sign --local [HAP] [--apl normal|system_basic|system_core] [--flavor debug|release] |
OpenHarmony localSign with the official public test chain (dev boards / emulators / source-built ROMs; not retail devices). With HAP, binds the profile to that package's own bundleName |
hvolt agc login|whoami|certs [delete <id> --yes]|devices |
AppGallery Connect resources — needs the optional backend; cert delete is irreversible |
| Command | Description |
|---|---|
hvolt push [device] [-d <device>] [--hap <FILE>] |
Push the newest output/*-signed.hap to the device; --hap installs the package at that path instead and refuses an unsigned one |
hvolt uninstall [bundle] [-d <device>] |
Uninstall an app (default bundle: from hvolt.toml) |
hvolt log [-T tag] [-D domain] [-k keyword] [--level D,I,W,E,F] [--bundle <b>] [--crash] [-f] [--tail <n>] |
Stream or dump hilog with filters |
hvolt screenshot [-o out.jpeg] [-d <device>] |
Device screenshot |
hvolt ui dump [-o layout.json] [-d <device>] |
ArkUI layout tree |
hvolt file send|recv <a> <b> [-d <device>] |
File transfer with the device |
| Command | Description |
|---|---|
hvolt device list |
List connected devices |
hvolt device connect <addr> |
Connect to a device over TCP |
hvolt device remote <host> <serial> |
Register a device attached to another host (cross-machine install) |
| Command | Description |
|---|---|
hvolt emulator list [--details] / start <name> / stop <name> / delete <name> |
Manage instances |
hvolt emulator create <name> --os-version <v> [--type <t>] |
Create an instance (needs a downloaded image) |
hvolt emulator images [download <ver>] |
List system images, fetch one |
hvolt emulator license |
Accept the HarmonyOS emulator software agreement |
| Command | Description |
|---|---|
hvolt doctor |
Environment / SDK / tools / device / auth / project consistency, with a fix hint per failed check |
| Dependency | Version | Notes |
|---|---|---|
| Rust | 1.85+ | Build-time only (clap 4.6 MSRV) |
| Node.js | 20+ | Only for hvolt lsp and the emulator wrapper |
| HarmonyOS SDK | 26.x recommended | hvolt sdk download <version>; the remote list covers API 10–26, and anything below 26 is flagged as deprecated |
Local signing (in this tree). hvolt sign --local uses OpenHarmony's public test certificate
chain, fetched from the OpenHarmony repository (Apache-2.0) and pinned by SHA-256. That identity is
pre-trusted only by development boards, emulators and source-built ROMs; a retail HarmonyOS device
needs a certificate and provisioning profile issued to a Huawei developer account.
Remote signing through AppGallery Connect (not in this tree). hvolt sign without --local and
the hvolt agc commands need a backend that talks to AppGallery Connect — the login flow, token
handling and the certificate / device / provisioning requests that humans otherwise perform in
DevEco Studio. That backend is not published here: this repository contains no AGC endpoints, no
login flow and no request/response handling for those services.
Release binaries do carry it. The overlay sits outside the repository and reaches the release runner
as a repository secret (AGC_OVERLAY_B64); the workflow decodes it next to the crate and builds with
--features agc-local. Without that secret the same workflow produces the public build, whose
hvolt agc commands report that the backend is absent — scripts fail loudly instead of silently
doing nothing. Source never enters the repository, so a build from a clone has no AGC backend.
If you maintain your own AppGallery Connect integration, it can be compiled in as an overlay: place
it in agc-local/ next to the crate and build with cargo build --features agc-local. The overlay
is a private artefact; it is not part of this repository and not accepted as a contribution. Overlay
builds additionally mask their string constants at compile time and ship stripped symbols, so the
protocol details do not show up in strings output — that raises the cost of inspection, it is not
a security boundary, and no one should rely on it as one.
Whatever path you use, the terms of the Huawei developer services you authenticate against apply, and
signing material you generate stays under ~/.hvolt/ and in your project directory.
hvolt downloads its own SDK, so no DevEco Studio install is needed for any command:
init, build, sign, push, run, check, hap, log, screenshot, ui,
file, uninstall, device, sdk, config, doctor or agc.
From the SDK it only takes the official compilers (es2abc, restool).
The one exception is the emulator:
| Command | What it needs | After that |
|---|---|---|
hvolt emulator ... |
the emulator binary and system images, which ship only with DevEco Studio on Windows/macOS | install DevEco there, or use a physical device — Linux has no official emulator binary at all |
git clone https://github.com/hvolt-project/hvolt.git
cd hvolt
cargo build
cargo testThree checks gate every change; all must pass before a pull request:
cargo fmt --all --check # empty output
cargo clippy --all-targets -- -D warnings # "Finished"
cargo test # all passingConventions this codebase relies on: no compatibility shells (a binary crate has no downstream
API), no swallowed Result (let _ = … needs a stated reason), a comment that names a CLI command
must match hvolt --help, and a comment claiming a mechanism carries the measurement that produced
it. Details and examples in CONTRIBUTING.md.
0.1.0 — usable end to end (translate, build, sign, deploy, lint, device tooling), but pre-1.0:
the CLI surface may still change between minor versions. hvolt is an independent community project,
not affiliated with or endorsed by Huawei; "HarmonyOS", "DevEco Studio" and "Huawei" are trademarks
of Huawei Technologies and are used here only to describe compatibility.
Bug reports and pull requests are welcome. CONTRIBUTING.md lists the checks a change must pass; report vulnerabilities privately as described in SECURITY.md; release notes live in CHANGELOG.md. By participating you agree to the Code of Conduct.
Built in pair-programming sessions with the deepseek-flash model (DeepSeek). Those sessions set the working habit this codebase keeps: a claim about how something behaves comes with the measurement behind it, and a wrong assumption gets settled by running the code, not by arguing about it.
GPL-3.0-or-later — see LICENSE. Third-party components and the origin of fetched artifacts are listed in THIRD_PARTY_NOTICES.md.