Skip to content

DevJSRuntime

Bashar Astifan edited this page Jun 9, 2025 · 41 revisions

πŸ“œ ImMobile JSRuntime

The JSRuntime in ImMobile enables powerful scripting using QuickJS, giving developers access to internal APIs through a global object called imm. It allows you to create extensions, automation scripts, and interactive tools with familiar JavaScript syntax.


πŸ”Ή Getting Started

To use JSRuntime:

  • Your script should access ImMobile's APIs via the global imm object.
  • You can use functions like setTimeout, sleepAsync, and many others.

Example:

// Delay execution by 2.5 seconds
imm.setTimeout(startTest, 2500);

// Async sleep for 1 second
await imm.sleepAsync(1000);

Note: The imm object in ImMobile contains os and std in QuickJS-NG documentation.

By default ImMobile JSRuntime will load this part before your script

import * as std from "std";
import * as os from "os";
imm.std = std;
imm.os = os;

imm.setTimeout = function(fun, delay) {
    return imm.os.setTimeout(fun, delay);
}

imm.clearTimeout = function(id) {
    return imm.os.clearTimeout(id);
}

imm.sleepAsync = async function(ms) {
    return await imm.os.sleepAsync(ms);
}

you don't have to do this it happens normally,

as you can see I shorten the way for timeout and sleep like imm.sleepAsync instead of imm.os.sleepAsync


πŸ“˜ QuickJS-NG

Using imm.os or imm.std you can access to the functions that integrated with QuickJS-NG runtime

πŸ”„ Reset Runtime

It's very recommeneded to reset the runtime for your script before start using this code

imm.resetRuntime();

Check JS Demos for more examples

🧰 Exceptions

ImMobile Runtime may not always throw exceptions for the script, so you mostly may not see error in the console

to catch the exact issue always ensure to use try/catch for the part you need to track

var handle = null;
try {
    handle = imm.os.open(filename, imm.os.O_RDONLY);
} catch (e) {
    console.error(e);
}

🧩 Constant Substitutions

JSRuntime supports special string constants that are auto-replaced with paths to relevant folders:

Constant Description
$exts Extensions folder
$runs Runtime scripts folder
$updates Updates folder
$startup Startup scripts folder
$cfgs Configuration folder
$fonts Fonts folder
$temp Temporary files directory
$local Local app data folder
$music Music folder (ImMobile scoped)
$pics Pictures folder (ImMobile scoped)
$vids Videos folder (ImMobile scoped)
$data Root working data folder
$backups Backups folder
$downloads Downloads folder (ImMobile scoped)
$textures Cached textures
$tmpfiles Temporary files
$osbuild System build
$immver ImMobile version

Script-Specific Constants

Constant Description
$jsID Unique ID for the script
$jsIndex Index of the script in execution stack
$jsTime Timestamp of when the script started

πŸ“Ÿ Console Output

You can use console.log(...) or similar functions, and output will appear in the script-specific console in ImMobile.


πŸ“˜ API Reference (imm object)

Below is a categorized list of available API functions accessible through imm.


πŸ”” Notifications & Dialogs

  • imm.toast(title, message)
    Display a system notification.

  • imm.notify(message, type)
    Show an ImMobile in-app notification.
    type: "info", "success", "warn", "error"

  • imm.noticeDialog(title, text, onClose)
    Show an info dialog.

  • imm.confirmDialog(title, message, callback)
    Confirmation dialog with callback(confirmed) returning true/false.

  • imm.inputDialog(title, text, onClose)
    Prompt input dialog.


🌐 Network & GitHub Tools

  • imm.openURI(url)
    Open a URL in the default browser.

  • imm.quickDownload(url, dest, isfull_dest, notify)

    Remarks (quickDownload)

    Download a file quickly to dest,

    note that this function generate unique files, doesn't replace

    by default dest expected as file name/sub path not a full path, file will be at downloads folder by default

    if you want to provide full path then set isfull_dest to true

    notify will turn on/off notificiations, helpful for silence download

  • imm.getOnlineFileName(url, default)
    Get filename from a remote resource, it may return the string before '?' if fail, ensure to use your own way to cover fail case.

  • imm.getResponse(url, notify_error)
    Fetch a remote response as string, return the response or undefined if fail.

    notify_error can be true or false

  • imm.downloadResponse(url, dest, notify)

    Remarks (downloadResponse)

    Download response to a file, unlike quickDownload, this doesn't generate unique files.

    dest expected as full path, notify can be true or false.

  • imm.gitHubContent(user, repo, sub, callback)
    Get GitHub content as json-string, sub can be empty.

    callback(output) required, output handle the results

  • imm.gitHubLatestRelease(user, repo, callback)
    Get latest release as json-string, callback(output) required same above.

  • imm.showGitHubReadMeUI(url, token)
    Show UI to browse a GitHub README.

  • imm.showGitHubReleasesUI(url, token)
    Easy to use UI for browsing and downloading GitHub releases.

    token can be empty if repo is public

  • imm.showGitHubFilesUI(url, token)
    Easy to use UI for browsing and downloading repository content.

    token can be empty if repo is public

  • imm.isOnline()
    Returns true or false based on network availability.


πŸ“ File System

Note that you can check std QuickJS-NG Docs for more functions

  • imm.createFolder(parent, name, replace, skip_ifexists)

    Remarks (createFolder)

    Create a folder under a given path, return the full path for folder or undefined if fail.

    skip_ifexists helpful to avoid collision cases

    example (ensure folder exists) imm.createFolder("$temp", "collections", false, true)

  • storageCopy(src, dest) Copy folder/file from src to dest

    for file.. add file name to dest

  • storageMove(src, dest) Move folder/file from src to dest

    for file.. add file name to dest

  • storageRename(src, new) Rename folder/file, both full path

  • storageDelete(src) Delete folder/file

  • storageExists(src) Check if folder/file exists

  • storageSize(src) Get folder/file size in bytes

    folder size may subject to ImMobile settings if folder size off

  • storageIsDir(src) Check if given path is dir

  • imm.filePutContents(path, content)
    Write text to a file.

  • imm.fileGetContents(path)
    Read the content of a file, return file content or undefined if fail.

  • imm.openFile(path)
    Open file with the default OS app.

  • imm.openFolder(path)
    Reveal folder in OS file explorer.

  • imm.unZip(file, dest, callback)
    Unzip archive with callback -> callback(state, output).

  • imm.zipFolder(folder, dest, callback, store)
    Zip folder with callback -> callback(state, output).

    set store to true to ignore compression, better and faster for low-end devices

Example

As example on how to use std library to make your own functions,

function isFileExists(filePath) {
	var handle = null;
	try {
		// Check if file already exists
		handle = imm.os.open(filePath, imm.os.O_RDONLY);
		console.log(handle);
	} catch (e) {
		console.error(e);
	}

	if (handle < 0) {
		return false;
	}

        imm.os.close(handle);
	return true;
}

same goes for example to make copy function

function copyFile(sourcePath, destinationPath) {
	const { open, close, read, write, O_RDONLY, O_WRONLY, O_CREAT, O_TRUNC } = imm.os;

	const BUFFER_SIZE = 1024;
	const rawBuffer = new ArrayBuffer(BUFFER_SIZE);

	const sourceFd = open(sourcePath, O_RDONLY);
	if (sourceFd < 0) {
		throw new Error(`Failed to open source file: ${sourcePath}`);
	}

	const destFd = open(destinationPath, O_WRONLY | O_CREAT | O_TRUNC);
	if (destFd < 0) {
		close(sourceFd);
		throw new Error(`Failed to open/create destination file: ${destinationPath}`);
	}

	try {
		let bytesRead;
		while ((bytesRead = read(sourceFd, rawBuffer, 0, BUFFER_SIZE)) > 0) {
			write(destFd, rawBuffer, 0, bytesRead);
		}
	} finally {
		close(sourceFd);
		close(destFd);
	}

	console.log('File copied successfully.');
}

std functions are internally resolved with UWP wrappers so you can use them to any folder granted by the user


πŸ“¦ Package Management

  • imm.installPackage(path, direct)
    Install .appx, .msix, or similar package.

    direct helpful to avoid confirmation dialog

  • imm.registerPackage(path, direct)
    Register a package via its manifest.

direct helpful to avoid confirmation dialog

  • imm.removePackage(id)
    Remove installed package by id or fullname.

🧩 Extensions

  • imm.loadExten(path, window, confirm)
    Load an ImMobile extension.

  • imm.unloadExten(path)
    Unload an ImMobile extension.

  • imm.extenToggleGUI(path)
    Toggle extension’s UI visibility.

  • imm.isExtenLoaded(path)
    Check if an extension is currently loaded.


πŸ“‚ Pickers

  • imm.chooseFile(callback)
    File picker, callback(path).

  • imm.saveFile(callback)
    Save-as file dialog, callback(path).

  • imm.chooseFolder(callback)
    Folder picker, callback(path).


πŸ“‹ Clipboard & UI

  • imm.setClipboard(text)
    Set system clipboard text.

  • imm.getClipboard()
    Get current clipboard text.

  • imm.showKeyboard(state)
    Show or hide on-screen keyboard.

  • imm.changeBackground(path)
    Change ImMobile background.

    I forgot to apply constants replacement on path at this function so ensure to use proper full path


πŸ› οΈ Special

  • runCMD(command, output, detached) Run cmd command with user level, require root access

    output: (true/false), if enabled return result

    or false if failed (logs usually can help),

    otherwise return true or false


πŸ“š See Also


Clone this wiki locally