Applets (Architecture)
Applets are React (Vite) applications that run inside IOTA SDK, backed by a Go “applet runtime”. The runtime is designed to keep applets tightly integrated (auth, styling, navigation) while staying loosely coupled (explicit boundaries, small surface area).
Components
Go runtime
- Registration: each module provides an
applet.Appletimplementation (typicallymodules/<name>/applet.go). - Shell rendering:
- Embedded: the applet is rendered inside the authenticated IOTA layout.
- Standalone: the applet is rendered as a standalone HTML page (useful for local dev / debugging).
- Assets:
- Production: serve embedded build artifacts (Vite output + manifest) from an
fs.FS. - Development: reverse-proxy
/<basePath>/assets/*to the Vite dev server (same-origin HMR). - SSR mode: applet page requests can be proxied to Bun runtime when
frontend.type="ssr".
- Production: serve embedded build artifacts (Vite output + manifest) from an
- RPC bridge:
- Global HTTP endpoint (
/rpc) for applet → Go capability calls. - Public methods can execute on Go handlers or Bun runtime targets per applet/method metadata.
- Unix socket transport exposes the full registry (
public + server-only) for Bun. - Permission checks are enforced server-side.
- Global HTTP endpoint (
Frontend runtime (SDK)
- Custom element host:
defineReactAppletElementmounts React into a shadow root and optionally syncs dark mode. - Context:
AppletProviderreadsInitialContextfromwindow[WindowGlobal]. - RPC client:
createAppletRPCClientcalls the applet RPC endpoint and (optionally) emits dev events. - Devtools overlay: opt-in overlay showing runtime config + route + RPC calls.
Request flows
Embedded (production)
Embedded (development / HMR)
RPC (applet → Go)
Security & boundaries
- No direct DB access from JS: applets call Go capabilities (RPC/GraphQL/REST); Go owns tenant isolation and authorization.
- Same-origin protection: applet RPC defaults to blocking cross-origin browser requests (based on
OriginvsHost) on global/rpc. - Permission checks: procedures can declare required permissions; enforcement happens server-side.
- Translation payload: applets can scope injected translations by key prefix to keep
InitialContextsmall.
Bun runtime pilot (Slice 1)
- Per-applet runtime mode is configured in
.applets/config.toml:
version = 2
[applets.bichat]
base_path = "/bi-chat"
[applets.bichat.engine]
runtime = "bun" # off|bun- Browser-facing applet methods still execute in Go handlers.
- Bun runtime is started lazily for BiChat and uses Unix sockets:
IOTA_ENGINE_SOCKETfor Bun -> engine server-only RPC callsIOTA_APPLET_SOCKETfor Go health/probe calls into Bun
- Slice 1 server-only capability methods are in-memory stubs:
bichat.kv.get|set|del|mgetbichat.db.get|query|insert|patch|replace|delete
Extension points (future)
The asset subsystem is structured so additional asset providers can be introduced later (e.g. Next.js SSR) without rewriting the controller. The current shipping default is Vite SPA (static + dev server).
Related docs
- Developer guide:
/development/applets
Last updated on