CLI tool
uappx/uapp avatar
uappx/uapp

uapp wraps uni-app in a CLI that also builds offline native app packages

uapp是一款基于uni-app跨平台开发的高效cli。 源自自有产品跨平台的最佳实践,通过集成 uni-app, electron, tauri,让开发者仅需维护一套代码,就能横跨所有平台。uapp助开发者无限制重构一切软件。

671 stars99 forksJavaScriptApache-2.0

At a glance

What is it?
uapp is a command line tool for cross platform development built on uni-app, with electron and tauri alongside it, so one codebase targets phones, desktops, mini programs and browser extensions. Its real work is the offline native packaging path for Android and iOS, which needs the DCloud offline SDK and a custom base package.
Who is it for?
Adopt uapp if your team writes uni-app projects and needs offline native packaging with custom base packages, because that is the part the tool adds and the part plain uni-app scripts do not cover. Do not adopt it if you only need to compile H5 or mini programs, where the upstream preset commands already work, or if you need a published release history, since the repository has no GitHub releases.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 32 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One codebase, but the real work sits in the native packaging path

uapp is a CLI for cross platform development built by integrating uni-app, electron and tauri, so a developer maintains one set of source and targets phones, desktops, mini programs and browser extensions. The description in the repository is blunt about the audience: the goal is to let web developers do more, so a team that already knows H5 can rebuild software across platforms.

The interesting part is not the compilation. Compiling H5 and mini programs is what the upstream uni-app tooling does. What uapp adds is the offline native path, where an Android or iOS project is generated, the DCloud offline SDK is compiled against, and a custom base package is produced and published so that HBuilderX can load it.

The commands reflect that split. A single run of uapp run dev:mp-weixin generates the mini program code and opens WeChat developer tools to load it, and a single run of uapp run build:app produces a custom base package installer and publishes it under the hbx project so it can be used directly. uapp info then reports the values you need during development, including the package name, the signing md5, the dcloudkey and the jwt.

The package itself is small in npm terms. The name is uapp at version 3.2.1, the type is module, the binary is bin/uapp, and the engines field requires Node.js 18 or later. The runtime dependencies are a working set rather than a UI framework: ora for spinners, chalk for output colour, chokidar for file watching, fs-extra, nopt for option parsing, update-notifier, yazl for zipping, jsonwebtoken for signing, lodash, and a package called @uappx/tiged.

The DCloud offline SDK lives in the user home, not in your project

Installing the CLI and preparing the SDK are two separate steps:

bash
npm install -g uapp
bash
uapp sdk init

The second command initialises or updates the uappsdk. That is distinct from the uni-app offline SDK, which is the DCloud published package you download yourself for Android and for iOS. The README warns to keep the two apart, since they share a name and a similar purpose.

Once the DCloud SDK is downloaded and extracted, its SDK directory goes into a .uappsdk folder, and the top level of that folder looks like this, with the extracted SDK sitting inside each platform directory:

bash
> $HOME/.uappsdk/
.
├── android
├── ios
└── templates
    └── manifest.json

The templates directory holds a manifest.json, which is how the CLI knows which native project templates to use.

The reason the SDK sits at user level rather than inside each project is worth stating plainly. A native offline build compiles against vendor provided libraries, and those libraries are large and platform specific, so they are shared across projects on the machine instead of being vendored into every repository. The cost is that a developer needs the SDK prepared before the first native build, and a CI machine needs the same preparation scripted.

Run commands are namespaced by target, and build:app replaced the old form

The webapp project compiles mini programs and H5 through the same command shape, with the target as part of the script name:

bash
uapp run dev:h5
uapp run dev:mp-weixin
uapp run build:h5
uapp run build:mp-weixin

The electron target is treated as a custom environment, and the README links to the uni-app environment configuration docs for that:

bash
uapp run build:electron

The same namespace holds the automated test targets, which run against the HBuilderX built Node and Jest setup:

bash
uapp run test:web-chrome
uapp run test:web-firefox
uapp run test:web-safari
uapp run test:mp-weixin
uapp run test:app-android
uapp run test:app-ios-simulator
uapp run test:app-ios
uapp run test:app-harmony

One naming rule is easy to get wrong. From version 3.0 the tool dropped run build and run build:dev, aligning with uni-app so that custom extensions are easier to define. The command format is uapp run build:app*, vue2 projects use uapp run build:app-plus, and the name must start with app. Non app targets such as H5 have no such restriction.

The output formats are selected with the -r flag, and the packaging commands are:

bash
uapp run build:app
uapp run build:app -r uapp.wgt
uapp run build:app -r apk
uapp run build:app -r aab
uapp run custom

The wgt form produces a uapp.wgt package, the apk form produces an Android apk, and the aab form produces an Android aab for publishing to Google Play. There is also a custom path, uapp run custom, which runs the custom.command entry from manifest.json, and a prepare step, uapp prepare build:app, which updates the app icon and the local packaging resources.

The uapp node in manifest.json is where keys and package names live

Most of the parameters in an existing manifest.json exist for HBuilderX cloud packaging. The uapp specific parameters are an extension, and the README is explicit that uapp.* parameters are added by uapp and are not part of the DCloud standard.

Here is the shape of a manifest that carries those extensions, with the platform specific keys and the distribution config:

json
{
  "name": "uapp",
  "appid": "__UNI__ECA8F4D",
  "versionName": "1.0.1",
  "versionCode": "1000000",
  "uapp": {
    "name": "uapp",
    "package": "com.code0xff.uapp",
    "android.appkey": "b4ab7d1c668cbb3b257aeeabd75c29da",
    "ios.appkey": "aa215ff1522abe39cb7ccec5943eeb92",
    "custom.command": "cd ${SRC}/../android && uapp run build:app && node publish_apk.js"
  },
  "app-plus": {
    "distribute": {
      "sdkConfigs": {
        "oauth": {
          "weixin": {
            "appid": "wx95039516c9f72e50",
            "appsecret": "123456",
            "UniversalLinks": "https://uapp.code0xff.com/"
          }
        }
      }
    }
  }
}

The parameter table that follows explains the entries. name is the app name and defaults to the root name, package is the application package name, android.appkey and ios.appkey are the DCloud platform keys, and versionName carries the version. Any of name, package, versionName and versionCode can be prefixed for per platform values, for example android.name, android.package, ios.package and ios.versionCode, so one project can produce differently named artefacts per platform.

The custom.command value is where the pipeline gets interesting. It runs from the directory of the current manifest.json, and the ${SRC} placeholder is available to locate that directory, with ../ allowed to walk up a level so that absolute paths are avoided. In the example it changes into the android sibling directory, runs the app build, and then runs a publish script. The README also notes that the final release package has the irrelevant data stripped from its manifest.json, so the parameters in the source file are not a disclosure risk in the shipped artefact.

Native templates ship a deliberately small module set

The Android and iOS project templates include only the basics: WeChat login, Apple login and payments. Advertising and notification modules are deliberately excluded, and the README gives the reason: those categories require a data tracking declaration at review time, which complicates the submission, so they are left out unless they are truly needed, in which case you add them yourself by following the official module dependency documentation.

On Android, the dependencies are declared by putting package names into the app/sdk.libs file in the project directory, one package name per line. For iOS the module configuration is documented by DCloud.

This is a small design decision with a large operational consequence, and it cuts both ways. A template that carries only login and payment modules passes store review with less paperwork, which is what a small team wants on a first submission. It also means a project that does need ads or push notifications starts from a native project you configure by hand, at the point where the native build is the most expensive thing to get wrong.

The project creation side is short too. uapp new YourProject creates a project from the uapp-webapp template, which comes with unocss, tailwindcss and uvui integrated, plus a ready network request configuration available through uni.$uv.http. The alternative is to create the project from the HBuilderX menu using the official template, and then the required steps are to open manifest.json, confirm the appid in the basic configuration, and add the uapp node under versionCode in the source view, with the platform keys you obtained from DCloud.

Native project directories have to sit next to the src directory

For offline packaging the native projects and the webapp source live in one directory, and the layout matters. The android and ios directories are created by uapp add android and uapp add ios, and the webapp source lives in a src directory. Keeping that structure and those names means you do not need the uapp manifest command to locate the manifest.json under src.

If the current directory already has an android or ios directory, the command reports an error, so those directories have to be renamed first. That is a deliberate constraint rather than a bug, because the native build and the webapp build are two halves of one project that the tool expects to find in fixed places.

The iOS path is the one with the unusual choice. iOS project handling has traditionally been awkward, and while CocoaPods is common it does not fit the way the DCloud offline SDK is published. The author says that after repeated practice inside a product, the final choice was XCodeGen. That is a meaningful difference from the Android side, and it is the sort of thing you only learn by shipping an offline build repeatedly.

The commands that tie the pieces together are short:

bash
uapp manifest path/to/manifest.json
uapp info
uapp prepare build:app

The first reads the configuration from a manifest and updates the basic information, the second reports the dcloudkey and the values needed to talk to third party platforms, and the third updates the app icon and the local packaging resources produced by HBuilderX.

No published releases, a single author, and an English gap in the docs

Two facts about the project shape any expectation you have of it. The repository has no GitHub releases, and the package version in package.json is 3.2.1. The last push was on 2026-09-21 and the repository is not archived, so the code is being worked on, but you cannot point at a list of tagged releases to see what changed.

The package metadata lists a single author, Yin Qisen, and the repository is published under the Apache-2.0 licence with the licence file in the repository root. The licence declaration in package.json is a permissive one, so using the tool in a commercial product carries no copyleft obligation, which is a licensing note rather than legal advice.

The documentation is written in Chinese, and that is a real friction point for an international team even though the command names, the config keys and the manifest fields are all English. The repository also carries a doc/ directory alongside src/, test/, test-support/ and uappsdk/, and the npm files list publishes bin/, src/, doc/ and uappsdk/, so the local documentation ships with the package.

The test story is small but sensible. The test script is node --test, which uses the Node.js built in test runner, and the repository has separate test/ and test-support/ directories. The dependency list includes update-notifier, which means the CLI checks npm for a newer version, and nopt for option parsing.

The alternative worth comparing against is the plain uni-app preset that uapp itself points to for the full command list. That route compiles the same targets and needs no DCloud offline SDK, but it stops at the compilation step, with no custom base package, no native project generation and no key management in the manifest. If your requirement stops at H5 and mini programs, the upstream preset is the shorter path. If you need a store ready Android or iOS build, the offline SDK work is the reason uapp exists.

Editorial conclusion

Adopt uapp if your team writes uni-app projects and needs offline native packaging with custom base packages, because that is the part the tool adds and the part plain uni-app scripts do not cover. Do not adopt it if you only need to compile H5 or mini programs, where the upstream preset commands already work, or if you need a published release history, since the repository has no GitHub releases. Verify first that your machine can hold the DCloud offline SDK in the user home directory, that you have the dcloudkey values for both platforms, and that the module set baked into the Android and iOS templates matches what your app will need at review time.

Frequently asked questions

How do I install the uapp CLI and prepare the SDK?

Run npm install -g uapp to install the command, then uapp sdk init to initialise or update the uappsdk. The DCloud offline SDK for Android and iOS is a separate download that you place in the .uappsdk folder under your home directory.

What is the difference between uapp run build:app and uapp run build:app-plus?

The app-plus form is for vue2 projects, matching uni-app, while uapp run build:app is the current form. From version 3.0 the tool dropped run build and run build:dev, and any custom command name must start with app, while non app targets such as H5 have no such restriction.

Where do the android and ios project directories go in a uapp project?

They sit next to the src directory that holds the webapp source, created with uapp add android and uapp add ios. Keeping that structure and those names means the uapp manifest command is not needed to locate the manifest.json under src.

Which native modules are included in the uapp Android and iOS templates?

Only basics such as WeChat login, Apple login and payment. Advertising and notification modules are left out because they need a data tracking declaration at review time, and you can add them yourself by following the official module dependency documentation.

What does the uapp node in manifest.json configure?

It holds the uapp specific parameters, which are an extension rather than DCloud standard keys: the app name, the package name, the android.appkey and ios.appkey values from DCloud, the version, and a custom.command that runs a shell pipeline. name, package, versionName and versionCode can be prefixed per platform, such as android.package or ios.versionCode.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. README
  4. uappx/uapp on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/uappx-uapp.svg)](https://hysenlabs.com/projects/uappx-uapp)

Was this useful?