Agent module runs anywhere JavaScript runs — browsers, Electron renderers, Tauri webviews, and React Native — because its import graph has no Node.js builtins. praisonai-ts stays loadable in a mobile / browser webview from a dedicated entry point, and CI fails any pull request that breaks it.
Quick Start
1
Create an agent (runs identically in Node and a browser)
2
Import from the mobile entry (webview bundles)
3
Install
Import from
praisonai/mobile in a webview bundle — the package root (praisonai) re-exports the CLI, the MCP server, and the tool registry, which are not webview-safe by design.How It Works
A static Node-builtin import (e.g.import { readFile } from 'fs') is evaluated the moment a module loads, so in a webview it kills the whole bundle at import time — before any code runs, with no error boundary and a blank screen. CI bundles the mobile entry for the browser and fails if any forbidden builtin is imported statically.
CI now runs
npm run build before the gate, so the gate sees the compiled dist/esm/… artifacts too, not just the TypeScript sources. This closes a historic hole where the gate reported OK on an input that was not what actually shipped.Webview support contract
praisonai-ts is guaranteed by CI to remain loadable in a mobile / browser webview from one dedicated entry point.
Which entry is safe
Two entries are verified by CI to have no static Node-builtin imports: the mobile entry (praisonai/mobile) and the deep agent entry (praisonai/agent/simple). Use praisonai/mobile — it is the curated allowlist of everything that runs in a browser.
The mobile entry also re-exports
randomUUID and getEnv, browser-safe replacements for the Node originals you would otherwise reach for.Supported browsers
CI builds forsafari16 and chrome108. These are the floors — newer runtimes are fine.
What CI guarantees absent from your bundle
The Agent graph is guaranteed to have no static import of any of these Node builtins.Forbidden Node builtins (static imports)
Forbidden Node builtins (static imports)
assert, buffer, child_process, cluster, crypto, dgram, dns, events, fs, http, http2, https, module, net, os, path, perf_hooks, process, querystring, readline, repl, stream, string_decoder, timers, tls, tty, url, util, v8, vm, worker_threads, zlib.Static vs dynamic — the carve-out
A staticimport { x } from 'fs' kills a webview bundle at import time — that is what the gate blocks. A dynamic await import('readline') inside a function only fails if that function is called. readline is reached only from the CLI approval prompt, which a phone never calls, so it is allowed. Build your own path that calls it in a webview and that is on you — the gate cannot see it.
Which import to use
Reproducing the check locally
npm run build first so the gate checks what ships (dist/esm/…), not just the sources. Expected output:
On a fresh clone with no
dist/, the gate prints a note and checks the sources only — handy when auditing a PR before running the build. Run npm run build to also gate the built artifacts.Bundling & compatibility
The Agent import graph is free of Node.js builtins, so bundlers ship it as-is to any JS runtime.
Random IDs come from WebCrypto (
globalThis.crypto.randomUUID, with a getRandomValues fallback), and internal event dispatch uses a small in-tree emitter — the Agent module never imports Node’s crypto or events.
Configuration
Pass credentials per-agent so browsers never depend on environment variables.Best Practices
Import from praisonai/mobile in any webview bundle
Import from praisonai/mobile in any webview bundle
The package root re-exports the CLI, MCP server, and tool registry, which pull in Node builtins.
praisonai/mobile is the curated, CI-verified allowlist for browsers, Electron renderers, Tauri, and React Native.Pass credentials per-agent in browsers
Pass credentials per-agent in browsers
Browsers have no environment variables. Provide
apiKey (and baseURL if needed) directly on the agent instead of relying on process.env.Use the browser-safe helpers, not the Node originals
Use the browser-safe helpers, not the Node originals
The mobile entry exports
randomUUID and getEnv. Use them instead of crypto.randomUUID() or process.env, which are the kind of Node dependencies that would break a bundle.Understand where random IDs come from
Understand where random IDs come from
On modern browsers and Node ≥ 19, IDs come from
globalThis.crypto.randomUUID.
On older webviews without it, PraisonAI falls back to getRandomValues and still produces a valid RFC-4122 v4 UUID.
On the very oldest webviews without WebCrypto at all, IDs fall back to Math.random() — a weak source, but the Agent still constructs (no ReferenceError at import).No polyfills required
No polyfills required
Do not add
crypto or events shims to your bundler config — the Agent import graph does not reference them.Stay on or above the supported baseline
Stay on or above the supported baseline
CI targets Safari 16 and Chrome 108. Test against those floors; runtimes below them are unsupported and may fail for reasons the gate cannot catch.
Run build + check:webview before shipping a fork
Run build + check:webview before shipping a fork
If you patch
praisonai-ts in a fork, run npm run build && npm run check:webview so a stray static Node import surfaces on your PR, not on a device. Building first means the gate inspects the shipped dist/esm/… artifacts, not just the sources.Related
Agent
The core Agent class and its full configuration.
Approval
Human-in-the-loop tool approval
TypeScript Agents
Getting started with the TypeScript SDK.

