SDK

Architecture

Canonical doc

Boot sequence, runtime model, and package ownership for the Meteorack module platform.

Runtime model

Meteorack is organized around four runtime layers:

  1. runtime-core Portable contracts, registries, client/runtime APIs, and runtime-agnostic test helpers.
  2. runtime-wp The current WordPress host runtime used by the Hub plugin.
  3. runtime-testbed A neutral proving host used to validate contracts and module boot outside WordPress.
  4. runtime-meteorack The first-party non-WordPress host runtime for the long-term platform.

Adapters live inside runtimes. Modules consume contracts from runtime-core and should not import WordPress or infrastructure primitives directly.

Because the platform is not live yet, avoidable compatibility duplication should be minimized:

  • prefer hard cutover over long-lived aliases when there are no external consumers
  • keep PHP host/runtime bridges only where WordPress actually needs them
  • treat re-export shims and compatibility barrels as short-lived migration aids, not permanent architecture

Boot sequence today

At a high level, the current WordPress host runtime works like this:

  1. The plugin entrypoint loads the SDK/runtime autoloaders.
  2. The Hub constructs a hub-scoped compatibility context through SdkContextFactory.
  3. ModuleRuntimeLoader discovers module.json files from wp-content/meteorack/modules.
  4. Each module boots inside crash isolation.
  5. The host injects parsed module metadata and host-owned services.
  6. The module receives a slug-scoped compatibility context through onSdkReady().
  7. The Hub registers routes, assets, and admin surfaces after boot.

This is the current compatibility path, not the final permanent architecture.

Context scoping

SdkContextFactory currently splits services into two categories:

  • shared singletons such as auth, http, license, design tokens, and channels
  • slug-scoped services such as logger, cache, settings, events, scheduler, storage, and secrets

That shape remains useful for the WordPress host runtime, but the long-term portable contract surface lives in runtime-core, not in SdkContext itself.

Module discovery

The current WordPress host runtime supports both flat and categorized discovery paths:

  • wp-content/meteorack/modules/{slug}
  • wp-content/meteorack/modules/core/{slug}
  • wp-content/meteorack/modules/adapters/{slug}
  • wp-content/meteorack/modules/dev/{slug}

Modules are sorted by priority before boot.

Package and workspace boundaries

meteorack-sdk is responsible for:

  • durable @meteorack/modules-sdk-* packages
  • runtime-testbed
  • SDK docs, schemas, examples, conformance tests, and the standalone module-author workflow

meteorack-suite remains responsible for:

  • runtime-wp
  • Hub plugin packaging and install surface
  • current WordPress scaffold/bootstrap glue
  • WordPress-host runtime code and scaffold/bootstrap glue that still belongs to the host

meteorack-platform remains responsible for:

  • runtime-meteorack
  • shared platform infra packages such as auth, db, logger, and ui
  • first-party modules under meteorack-platform/modules/
  • product apps and platform runtime consumers

Module and integration boundaries

  • domain products such as cms and commerce are modules, not runtimes
  • integration modules may live next to other first-party modules
  • low-level host connectors stay inside the relevant runtime
  • for example, WooCommerce business logic can live in a module, while direct WordPress/WooCommerce glue stays inside runtime-wp

Shell system

The UI shell should be treated as one system, not as a long list of unrelated shell names.

The public model is:

  • AppShell is the main shell API
  • shells are configured by surface, regions, slots, and tokens
  • modules usually render inside the shell, not define a brand-new shell for every feature

Simple example:

  • admin area uses AppShell with an admin surface
  • customer account area uses AppShell with an account surface
  • storefront uses AppShell with a storefront surface

So the outside API stays simple, while the inside implementation can still stay clean.

Why this matters

If every surface gets a separate public shell name, the system becomes noisy very quickly:

  • AdminShell
  • AccountShell
  • StorefrontShell
  • CartShell
  • MobileShell

That is not the direction we want.

Instead, we want:

  • one shell system
  • reusable shell parts
  • surface-specific presets behind the scenes

Public rule

Public SDK docs should describe:

  • one public AppShell
  • shared shell regions
  • shared shell tokens
  • shared shell composition rules

Not a long public catalog of shell variants.

Internal rule

Internally, runtimes or themes may still compose surface-specific presets.

Simple example:

  • runtime-wp may compose an admin-flavored shell preset
  • a customer portal may compose an account-flavored shell preset

But that should remain an implementation detail, not the main public mental model.

Shell regions and slots

The shell should be extensible through stable regions.

The initial region model is:

  • header
  • sidebar
  • content
  • rightRail
  • bottomNav
  • overlay
  • footer

Simple example:

  • a storefront can use rightRail for a cart rail
  • mobile can use bottomNav for app-style navigation
  • admin can use overlay for command palette or search drawer

This lets the shell grow without inventing a brand-new shell name every time we add one more rail, bar, or overlay.

What modules should depend on

Most modules should not own the shell.

Most modules should depend on:

  • shared UI primitives such as Button, Card, Input, Table
  • page-level composition pieces such as PageHeader
  • shell slots/regions exposed by the host
  • design tokens

Simple example:

  • the search module should render its page and controls
  • the host shell decides whether that page appears inside an admin shell, account shell, or another surface

This keeps modules portable.

Themes and shell styling

Themes should change:

  • tokens
  • spacing
  • colors
  • typography
  • shell presentation

Themes should not need to rewrite module internals just to restyle the experience.

Simple example:

  • one admin theme can feel minimal and flat
  • another can feel darker and more layered
  • the same module page should still work in both because it consumes shared tokens and shared UI primitives

Developer-surface rules

The portable SDK surface should optimize for both human developers and AI-assisted workflows:

  • public boundaries are schema-first on the TypeScript side and should emit machine-readable artifacts such as JSON Schema or OpenAPI for the durable public contracts
  • transport and runtime results use discriminated unions instead of ok: boolean
  • public errors use a typed hierarchy rooted in SdkError and carry code, message, requestId, param, docUrl, suggestions, retryable, and details when relevant
  • branded identifier types are used selectively for easy-to-mix values such as module slugs, event names, route paths, capability keys, and session/user identifiers
  • public functions with multiple inputs prefer a single options object
  • module-author APIs should offer builders such as defineRoute() and defineModuleManifest() rather than forcing raw object assembly everywhere
  • every public export should ship with TSDoc and runnable @example blocks
  • SDK docs should also publish AI-friendly indexes such as llms.txt and llms-full.txt
  • the primary standalone developer workflow should come through the module-author CLI plus runtime-testbed, not through WordPress scaffold templates

Current execution status

  • runtime-wp is the active production host today
  • runtime-testbed exists to prove portability outside WordPress
  • runtime-meteorack is the long-term host runtime target
  • legacy @meteorack/sdk-* barrels are gone; new work should use the durable @meteorack/modules-sdk-* package family directly

Related docs