Getting Started

Clone, run in the webview, and get a chat answering on a simulator.

The shortest path from clone to a running chat.

bash
git clone https://github.com/MervinPraison/PraisonAI
cd PraisonAI/src/praisonai-mobile
npm install && npm run check
Diagram

📦 Clone

⚙️ npm install

✅ npm run check

🪟 npm run build

📱 Simulator

Quick Start

  1. Install
    bash
    cd PraisonAI/src/praisonai-mobile
    npm install

    The package is private and needs Node >=22.18. Runtime dependencies load through adapters, so there is no runtime dependencies block.

  2. Run the gates
    bash
    npm run typecheck
    npm run test
    npm run check

    check chains typecheck, boundaries, and test.

  3. Build the webview bundle
    bash
    npm run build

Package Scripts

Every script the package ships, from package.json.

ScriptWhat it does
typechecktsc -p tsconfig.json.
testRuns the node --test suite across every layer.
boundariesFails the build if an import crosses a seam.
buildBuilds the webview bundle.
test:bundleRuns the bundle-gate’s own suite.
checktypecheck + boundaries + test.
check:upstreamChecks the real Agent still satisfies the port.
build:webviewSame as build.

Platform projects are already committed

The repo ships committed iOS and Android platform projects at src-tauri/gen/apple and src-tauri/gen/android, so nothing extra is needed to build the mobile apps — CI proves both build on every PR touching src/praisonai-mobile/**. See Platform Builds for the workflow and the local build commands.


Swap the Engine

Which engine answers is a setting, read at boot in app/src/main.ts. Change one value.

ts
import { appEngines, defaultEngineIdFor } from "praisonai-mobile/app/main";

const booted = await createApp({
  storage: platform.storage,
  secrets: platform.secrets,
  time: platform.time,
  shell: platform.shell,
  engines: (persistence, settings, onIgnored) =>
    appEngines({ settings, http: platform.http, persistence, onIgnored }),
  settingDefs: SETTING_DEFS,
  // The first-launch default when no engineId is persisted. Chosen by
  // platform kind: `praisonai-ts` on tauri (a device), `remote-http` on
  // web (see Engines). A persisted engineId always wins over this.
  engineId: defaultEngineIdFor(platform.kind),
  onPublish: publish,
  now: () => Date.now(),
  newChatId: () => globalThis.crypto.randomUUID(),
});

engineId is no longer a literal — defaultEngineIdFor(platform.kind) picks it by platform kind: "tauri" (a device, including desktop Tauri) defaults to the in-process praisonai-ts, "web" to remote-http (see Engines → First-Launch Default for why). A persisted engineId still wins over this default.

The in-process engine’s factory is supplied by appEngines, so praisonai-ts is on offer in real builds, and the picker (SETTING_DEFS.engineId.choices) now lists both remote-http and praisonai-ts. The shipping build can construct the in-process engine because its module ships as a lazy chunk fetched through import("praisonai/mobile") — so offering it in the picker is offering a choice the build can honour, not a brick.


First launch

The first screen tells a new user what the app is and that it needs a key — before any message is sent.

  1. Install and open

    On a fresh install, the chat screen shows the “Add an API key to start” panel, a one-sentence explanation of what the app does, and an “Open settings” button — not a blank screen and not a raw SDK error. See Empty Chat.

  2. Paste a key and return to Chat

    After pasting an OpenAI key in API Keys and returning to Chat, the panel switches to the welcome copy — “Ask something to begin.” and one line saying what the app does. The chat is ready.


Best Practices

Run npm run check before every commit

The bundle gate catches Node builtins and top-level process.env that pass in Node but blank the webview on device.

Use remote-http for the desktop dev flow

The first-launch default on a device is now the in-process engine (praisonai-ts). For iterating on a laptop, switch to remote-http in Settings: it speaks the full 11-event vocabulary against a running desktop engine, so you see tool rows and approvals while you work. The persisted choice wins, so the switch sticks.

Keep the engine choice in settings

engineId is read from settings at boot, so users switch runtimes without a rebuild.


Related

Next: Ready to ship to a store? See Shipping to iOS and Android for the CSP, WebView floor, and monotonic versioning story.