Skip to main content
Version: 3.0

App Store

The App Store is the distribution and runtime layer for Operaide Apps. As a developer, it is how your code gets from npm publish to a running App Instance — and how other developers discover and build on your work.

The App Store is the package registry, deployment pipeline, and runtime host rolled into one. If you want to understand how your code is structured and executed, see Aktor Framework.

Architecture Overview

The App Store connects four key entities:

  • AppDefinition — the immutable package stored in the registry. One entry per packageName@version. Contains the TypeScript source files, package.json metadata, and integrity hashes.
  • App Instance — a named, per-organization installation of an AppDefinition. Multiple instances of the same package can coexist with different configurations.
  • Deployment — a configured, running instance of a single ReaktorDefinition. Each App Instance owns one Deployment per Reaktor registered by the App.
  • ReaktorDefinition — the async function your main.ts registers via registerReaktorDefinition().

Package Format

Every App is a standard npm package. The naming convention is mandatory:

operaide-app-<name>     # must match ^operaide-app-[a-z0-9-]+$

Minimal package.json:

{
"name": "operaide-app-my-workflow",
"version": "1.0.0",
"description": "My custom workflow",
"main": "src/main.ts",
"peerDependencies": {
"@operaide/aktor": "^0.5.7"
},
"operaide": {
"category": "custom",
"quality": "reference"
}
}

The peerDependencies on @operaide/aktor controls compatibility: the platform checks this semver range against its own version and blocks installation if they don't match.

The operaide field carries metadata for the App Store UI:

FieldValuesPurpose
categorycore, custom, ...Grouping in the UI
qualityreference, template, experimental, needs-review, uncatalogedSignals maturity level
notesfree textShown in the details drawer

Publishing

Two paths to get your App into the App Store:

Point your .npmrc at the Operaide registry and publish like any npm package:

# .npmrc
registry=https://your-operaide-instance/api/v1/registry
//your-operaide-instance/api/v1/registry/:_authToken=${OPERAIDE_DEPLOY_API_KEY}
npm publish

The API key must carry the NPM Registry Publisher role (or a role that implies it, such as App Developer). Keys without it get 403 Forbidden on publish. Issue a reader-only key with NPM Registry Reader for pull-only CI that runs npm install but never publishes.

The App appears in the App Store immediately after publishing.

Dependencies from external registries

If your App depends on libraries hosted on a private npm registry (e.g. shared operaide-* libraries on another Operaide instance, a Verdaccio server, or GitHub Packages), the Operaide instance must be configured to forward requests to that upstream. This is an administrator task — see Upstream NPM Registry for the required environment variables (NPM_UPSTREAM_REGISTRY_URL, NPM_UPSTREAM_REGISTRY_AUTH_TOKEN).

As a developer, you do not need to configure .npmrc for upstream resolution. When you npm publish your App, the platform resolves dependencies from the configured upstream at install time. If a dependency cannot be found, the App installation fails with a missing-package error — ask your administrator to verify the upstream registry configuration.

Via Direct Deploy

For faster iteration during development:

npm run deploy              # one-shot upload
npm run deploy-watch # watches for changes, re-deploys automatically

This sends your source files directly to POST /api/v1/deploy-reaktor, bypassing the npm packaging step. Useful during active development, but npm publish is the canonical distribution path.

Code Loading and Sandbox

When an App is installed, the platform automatically transpiles your TypeScript and runs it in an isolated sandbox. Only a fixed set of modules is available — you cannot add arbitrary npm packages beyond this list:

CategoryModules
@operaide/*aktor, ai, document, database, vector, mail
npm packagesai, axios, zod, pdf-lib, @libsql/client, fast-xml-parser, @modelcontextprotocol/sdk
Node.js builtinsnode:buffer, node:crypto, node:path, node:stream, node:url, node:util
Other operaide-*Any published operaide-* package (as library dependency)

Your registerReaktorDefinition() calls are intercepted and prefixed with the App ID to avoid naming collisions across Apps.

App Settings

You can expose configuration to the person installing your App via registerAppSettings() with a Zod schema. These settings are editable per App Instance and available at runtime through getAppInstanceSettingsForReaktor().

App Instance Lifecycle

Installation

From the App Store UI, clicking Install opens a three-step wizard:

  1. Select App — version, instance name (URL-safe, unique per org), optional display label
  2. App Settings — form generated from your registerAppSettings() schema
  3. Deploy — creates the App Instance and all Deployments

Runtime

Each Reaktor in an App Instance is exposed via REST:

GET|POST /api/v2/orgs/{orgId}/apps/{instanceName}/reaktors/{reaktorName}

App Instance status transitions: deployingactive (or error). Instances can be stopped and restarted.

Updating

methodUpdateInstanceVersion handles version upgrades by diffing old vs. new ReaktorDefinitions: it adds new Reaktors, removes deleted ones, and updates existing Deployments in place.

Uninstalling

Removes all Deployments, their settings, and the App Instance document. The AppDefinition in the registry remains untouched — other organizations or future installs can still use it.

Multiple Instances

You can install the same App multiple times with different names and configurations. This is useful for running the same workflow against different AI providers, datasets, or customer-facing configurations.

Core Apps vs. Custom Apps

Every Operaide installation ships with Core Apps (op-core-*) — reference implementations like Basic Chat, Knowledge Chat, and Web Search. These are automatically published to the registry on startup from the bundled operaide-packages/ directory.

As a developer, Core Apps serve as working examples. You can open any Core App in Studio (via the Open in Studio action) to read the source, understand patterns, and use them as a starting point for your own Apps.

Quick Reference

WhatWhere
App Store UIBottom menu → "App-Store"
App Instances listBottom menu → "App Instances"
Package namingoperaide-app-<name> (lowercase, hyphens only)
Runtime API/api/v2/orgs/{orgId}/apps/{instanceName}/reaktors/{reaktorName}

For CI/tooling use:

WhatEndpoint
Publish to registryPUT /api/v1/registry/:name
Direct deployPOST /api/v1/deploy-reaktor
Download source (Studio)GET /api/v1/download-reaktor-code/:id