Reading guide
Auto.js Pro 9 ships a Node.js–based runtime and a second-generation JavaScript API (the first-generation / Rhino API from Pro 8 remains available). You keep full Android / Java interop from Node, plus the npm ecosystem on the order of millions of packages.
This site documents the v9 (Node.js) API. For the legacy API, switch the documentation tree to v8.
The v9 runtime can still exhibit memory leaks in some patterns. Do not treat it as the default choice for new scripts or for AI-generated samples unless you explicitly need Node/npm—or you are migrating or comparing behavior. For day-to-day automation, prefer the first-generation (Rhino) API unless you know you need v9.
Second-generation vs first-generation
Advantages of Node.js (v9) over Rhino (v8):
- JavaScript execution is orders of magnitude faster than Rhino.
- Scripts packaged with the Node engine get stronger protection; reversing is not practical today.
- Modern ES2021+ language features; Rhino stays near ES5 plus a subset of ES6.
- Fewer engine-level surprises; Rhino’s module system and edge cases have historically been painful.
- The v9 API surface is cleaner and closer to platform norms.
require("npm-package")works for supported dependencies.- More learning material exists on the open web for Node than for Rhino-in-Auto.js.
Disadvantages:
- Higher learning curve—Promises, async flows, and tooling matter, especially for beginners.
- Generated docs are dense; they follow TypeScript typings, so naming and edge-case notes can still evolve.
- The v8 / Rhino community still has more scripts, snippets, and Q&A in Chinese forums.
- v8 feels “batteries included” for small linear automations.
Choosing an engine when you start out
Prefer Rhino + v8 if you:
- Have little programming background and do not plan to go deep.
- Only need scripts that “run once” without caring about structure.
- Can live with older syntax and occasional engine quirks.
No extra header is required—Rhino remains the default in Pro 9.
Prefer Node + v9 if you:
- Already develop software or are comfortable reading modern JS.
- Want industry-standard patterns (async/await, modules, npm) as a foundation for Android / JS / Web later.
- Care about maintainability and structure.
- Need stronger packaging / obfuscation for shipped scripts.
- Want npm for databases, protocols, parsers, etc.
- Need maximum JS throughput.
- Enjoy experimenting with new stacks.
You can still skim v8 docs—most concepts (intents, selectors, UI) transfer.
Quick start: run on the Node engine
For compatibility, files still run on Rhino unless you opt into Node. Either:
- Put
"nodejs";on the first line of the script:
"nodejs";
console.log(`Node.js version: ${process.version}`);- Name the file
*.node.jsor*.mjs(.mjsalso enables ES modules per Node rules).
Node.js built-in modules
You get the usual Node built-ins, for example:
fs— filesystem (similar idea to Pro 8’sfilesmodule).http/https— clients and small servers.worker_threads— parallel JS (rough analogue to Pro 8threads).path,crypto,buffer, … — see the official index.
Full reference: Node.js 16.x docs (the version bundled with Pro 9).
Example — read a text file with fs:
"nodejs";
const fs = require("fs");
// https://nodejs.org/dist/latest-v16.x/docs/api/fs.html#fsreadfilepath-options-callback
fs.readFile("/sdcard/scripts/test.txt", { encoding: "utf-8" }, (err, data) => {
if (err) {
console.error("Read file failed:", err);
} else {
console.log("Read file success:", data);
}
});Pro 9 built-in modules
Node covers general-purpose APIs; Pro 9 still ships Android-centric modules, for example:
app— intents, other packages, broadcasts, email, etc.ui— layouts, activities, WebView-backed screens.accessibility— UI automation through the accessibility tree.image,media_projection,dialogs, … — browse the sidebar.
Every Pro 9 module must be
require’d. Globals such as bareapp/$appfrom Pro 8 are gone—useconst app = require("app");.
Most v9 calls are async (Promise) instead of blocking the JS thread the way v8 often did. Example: requestScreenCapture in v8 blocked until the user answered; in v9 it returns a Promise—use await / .then(). Clipboard helpers moved from globals into clip_manager (setClip / getClip).
Example — screenshot + template match:
const { readImage, findImage } = require("image");
const { requestScreenCapture } = require("media_projection");
async function main() {
const capturer = await requestScreenCapture();
const template = await readImage("./template.png");
const capture = await capturer.nextImage();
const result = await findImage(capture, template);
console.log("findImage: ", result);
capturer.stop();
template.recycle();
}
main();Install npm packages into a project
- Create a Node.js project from the file manager template (bottom-right menu → Project).
- Fill in the app label and a real application id containing a dot, e.g.
com.example. - Open the project toolbar → Terminal.
- Run
npm i --no-bin-links <package>(installs intonode_modules). - Import with
require("package")(orimportinside.mjs).
"nodejs";
const uuid = require("uuid");
console.log("uuid:", uuid.v4());Use cd into the project folder before installing additional packages.
--no-bin-linksavoids symlinked.binshims—FAT/SD storage on Android often cannot create symlinks. Call CLI entrypoints vianode node_modules/<pkg>/bin/...jsinstead, or move scripts to an app-private directory whose filesystem supports links (understand that uninstall wipes that storage).
Global npm tools
You can still npm i -g typescript and run tsc from the built-in terminal, bundle with webpack-cli, etc.
Do not upgrade the embedded npm—support assumes the shipped version. Global installs must omit
--no-bin-links, otherwise shell shims will not register.
Calling Java / Android APIs
$autojs exposes helpers such as $autojs.java:
"nodejs";
const $java = $autojs.java;
const StringBuilder = $java.findClass("java.lang.StringBuilder");
const sb = new StringBuilder();
sb.append("Hello");
sb.append(2);
console.log(sb.toString());See globals / $java docs for thread modes, wrap, create, etc.
For a Pro-8–style java.* / android.* surface, call:
"nodejs";
require("rhino").install();
const StringBuilder = java.lang.StringBuilder;
const sb = new StringBuilder();
sb.append(android.util.Base64.decode("YXV0b2pz", 0));
console.log(sb.toString());
importClass/importPackage/JavaAdapterare not supported in this mode yet.
Threads and UI
Single-threaded Node model
Pro 9 follows Node’s single-threaded event loop—you cannot spawn Rhino-style threads workers.
Heavy work (findImage, gestures, I/O) is exposed as async APIs so multiple operations can overlap. For Java calls, pass a thread hint such as "io" or "ui" on .invoke(...) (see globals Java).
For CPU-bound pure JS in parallel, use worker_threads (consult Node docs). Workers do not see $autojs, Auto.js modules, or Android APIs—only Node built-ins.
UI entry headers
Prefix the first line with "nodejs ui" or "nodejs ui-thread" when you must touch widgets on the main thread:
"nodejs ui";
const { isUiThread } = require("ui");
console.log(isUiThread());ui— you are building a visible Activity / layout flow (see the UI module).ui-thread— no extra Activity, but code runs on the UI thread (typical for floating windows).
For one-off UI work from a background script, marshal to "ui" via Java .invoke(..., "ui") (e.g. view.setText.invoke(view, ["hello"], "ui")).
How to read generated module docs
Docs are generated from TypeScript typings—knowing the layout helps.
Open app, for example. Sections mean:
- Interfaces — skip on first pass unless you need field-level detail.
- Variables — exported singletons/constants (
packageName, …).
"nodejs";
const app = require("app");
console.log(app.packageName);packageName is marked const (string)—assigning to it throws; the name tells you it is the current package id.
- Functions — e.g.
editFile,startActivity. Signatures look like:
startActivity(target: string | IntentOptionsWithRoot): Promise<void>string shortcuts mirror Pro 8 ("console", "settings", …). For objects, open IntentOptionsWithRoot—note root?: boolean and inheritance from IntentOptions. Toggle Inherited in the type viewer to see merged fields (action, data, flags, …).
Putting it together:
"nodejs";
const app = require("app");
app.startActivity({
root: false,
action: "android.intent.action.VIEW",
data: "https://pro.autojs.org",
});