Skip to main content
An app opened in Arg is a file in the workspace - an .html page, or a .tsx / .jsx component - rendered in an isolated preview. Inside that preview, @arg-ai/sdk resolves without a package install: HTML hosts inject an import map, and the React preview compiler resolves the modules locally. Your source never receives an API key and never chooses which workspace it talks to. The host does, and the viewer decides what it may touch. The earlier @arg/sdk spelling remains an alias for saved apps.
import { arg } from "@arg-ai/sdk" gives you every namespace on one object plus arg.ready, a promise that settles once the host has delivered the app’s context. Named imports are lazy, so awaiting arg.ready is only required before reading arg.context (the workspace id, the app’s path and its folder).
Static imports of workspace files are bundled when a React preview builds, and a changed file restarts the app. Read data that changes at runtime through fs, and subscribe with fs.watch, so the app keeps its state.

Permissions

Every preview starts with Workspace access off. The viewer switches it on from the preview’s Permissions menu (on iOS and Android, from the file menu), and picks two things: Arg reads the app’s source and suggests the grant it appears to need, so a viewer sees a matching prompt on first open. The prompt is informational only; the bridge enforces every call, whatever the scan said. A refused call rejects with:
  • permission_denied when the path or the namespace is outside the granted scope,
  • read_only when the grant is read-only and the call would change something,
  • disabled when the call needs the Actions switch and it is off.
The grant can be remembered for the file. Revoking it, or a change of account, restarts the preview so nothing in memory survives a permission the viewer took back.

Files, folders and ids

Relative paths resolve beside the app file; / is the workspace root. Under This folder scope a path that escapes the folder is refused, and fs.list and fs.glob are clamped to it. Cloud workspaces give every file a stable id: fs.getId(path) and fs.resolveId(id) convert between the two, and each read method has a ById twin for links that must survive a rename. The files guide covers every method. fs.assetUrl(path) returns a signed URL you can put in an <img> or <video> tag. It expires; do not store it as a share link. fs.open(path) asks Arg to open the file in its own editor.

Embedded SQLite

db runs SQL against a .sqlite or .db file in the workspace, inside the preview:
The file is the database. There is no managed multi-user database behind it: two viewers editing the same file at once last-write-win, and db.exec needs Read and write. Servers and agent scripts do not serve db; it is an embedded capability only.

Identity and team

auth.principal() is the signed-in viewer. users.list() returns the workspace’s members with their role, so an app can assign work or show avatars without its own directory.

Chats and Actions

With Workspace scope and Actions on, an app can run Actions, start agent runs and open chats as the viewer:
openPanel: true reveals the conversation beside the app: the docked chat panel on web and desktop, the native chat on iOS and Android. See chats and Actions and agents.

App chrome and navigation

ui registers the toolbar, inspector and bottom-bar descriptors an app may contribute to the surface around it, the same contract as @arg/ui without the React components:
host.open(path) opens a workspace file in Arg’s editor. Both are host capabilities: outside an Arg application host they report unsupported_capability, and ui.available is false.

Where it works

Web, the desktop app, iOS and Android all provide this bridge for HTML and React apps, with the same permissions menu. A folder the desktop app has opened straight from disk is a local workspace: fs reads the disk, stable ids and db are unavailable, and the only chats are the desktop’s own Claude Code and Codex sessions. The desktop harness section explains that case. Existing apps written against window.arg keep working unchanged; the two are the same objects. window.arg.chat and window.arg.workspace are new on every platform, so an HTML app can adopt them without switching to imports.