Prox OS Docs
Architecture

App Contract View

The app contract defines how apps are described, launched, permissioned, and hosted inside the OS Shell.

Purpose

The app contract defines how apps are described, launched, permissioned, and hosted inside the OS Shell.

This is the foundation for future local apps, route apps, isolated apps, and community apps.

Initial App Types

Local App

A React component bundled into apps/os-shell.

Use for first-party early apps.

OS Package App

A reusable official app exported from packages/os-apps and imported by apps/os-shell.

Use when an app no longer needs deep access to shell internals but should still run as part of the browser OS bundle.

Iframe App

A local developer tool or external surface hosted in an iframe.

Use for development-only tools such as docs, UI workshop, API explorer, or project graph surfaces before deeper integration exists.

Route App

An app represented by a route or external deployment under the same product domain.

Use for larger apps that deserve independent routing or deployment.

Isolated App Future

An app loaded with stronger isolation boundaries.

Use for community or third-party apps.

Initial Manifest Shape

export type OsAppManifest = {
  id: string
  title: string
  shortTitle: string
  icon: string
  description: string
  category: 'workspace' | 'data' | 'ops' | 'shell' | 'system' | 'developer'
  routeGroup: 'app' | 'app-user' | 'app-shell' | 'app-dev' | 'app-iframe' | 'app-os'
  routePath: string
  runtime:
    | { kind: 'local-module'; module: string }
    | { kind: 'os-package'; packageName: '@prox-os/os-apps'; exportName: string }
    | { kind: 'iframe'; iframeUrl: string; fallbackCommand: string; healthCheckUrl?: string }
    | { kind: 'route-app'; routePath: string }
    | { kind: 'isolated-app'; sourceUrl?: string }
  window: DefaultWindow
  permissions: AppPermission[]
}

Responsibilities

packages/app-contract owns:

  • Manifest types
  • Window contract types
  • Permission names
  • Data scope names
  • Runtime context shape for OS app exports, including narrow window actions and readonly window snapshots
  • App-facing shell settings and keyboard shortcut contracts

apps/os-shell owns:

  • Rendering windows
  • Opening apps
  • Managing active window state
  • Shell-coupled apps that remain under /app-shell
  • Adapting shell-local window store state into the app runtime context
  • Adapting public settings and keyboard contracts to the shell's local state implementation

packages/os-apps owns:

  • Reusable official OS apps that can be imported by the shell
  • App folders shaped around index.ts, manifest.ts, App.tsx, README.md, optional routes.tsx, components, hooks, api, store.ts, and types.ts

Current package app exports:

  • Most non-core OS apps now export both component and manifest from @prox-os/os-apps.
  • Each migrated manifest uses runtime.kind: "os-package" and sourcePackage: "@prox-os/os-apps".
  • The shell adapts package apps through apps/os-shell/src/apps/registry.ts and apps/os-shell/src/apps/localAppComponents.tsx.
  • Shell-coupled control apps such as Display options and Keyboard shortcuts remain local modules until their contracts are stable enough to extract.

apps/api-worker may later validate:

  • Permissions
  • App installation state
  • Data access scopes
  • AppRuntimeContext.links: optional openLinkChoiceAt(href, x, y) — opens the shell managed-link menu (Open in OS / new tab / copy). Use real <a href> in OS apps when possible; the desktop scene captures left-click on OS-resolvable targets.
  • AppRuntimeContext.session: optional requestSignIn() — opens the existing sign-in overlay (placeholder auth). Used by the Hola welcome app.
  • Platform hosts (packages/app-registry/src/platformHosts.ts): docs.prox-os.com → docs iframe app, ui.prox-os.com → UI workshop, api.prox-os.com → Scalar API explorer. Dev shells use /app-dev/* routes instead. These hostnames are deployment origins, not app primary keys. For deployment and Access boundaries, see cloudflare-deploy-and-access.md and app-namespace-and-domain-strategy.md.
  • Iframe guests: today use ProxOsIframeGuestLinkMessage (postMessage) to request the same menu; future work is to align guest links with resolveManagedLink rules centrally.

Future identity vs launch targets (roadmap)

Current: shell id / appId in the composed registry is the stable in-OS key. routePath, iframeUrl, and platform hostnames are launch targets.

Candidate (not final): server-backed registry with namespace + slug, public paths such as /user/:handle/app/:appSlug, and optional runtime isolation subdomains separate from canonical URLs. Stable appId must survive slug renames (aliases + redirects). Do not use a new second-level subdomain per app by default.

Seed manifest shape and Moments / API / system-app notes: app-namespace-and-domain-strategy.md.

Routing Boundary

  • Shell navigation: browser URL, route groups, website-mode variants, /spaces/:spaceId, window open/focus/close. Implemented with TanStack Router in apps/os-shell; this is OS-level only.
  • App navigation: entirely inside the window body. The contract exposes only generic hints (AppRuntimeContext.navigation), never a Router type from any library. First-party os-apps usually mount their own TanStack Router (often memory-based). Third-party stacks keep their router behind an adapter; iframe apps are always isolated.

Design Rule

The OS Shell should not hardcode every app forever.

It should gradually move toward manifest-driven app registration.

App ids should use kebab-case without dots or other punctuation. For example, the Architecture app uses developer-architecture.

On this page