Capabilities
A capability is a runtime behaviour your Surface can opt into: fetching data, routing between Surfaces, persisting client state, running form validation, or wiring blocks into a per-World entity model. Capabilities ship inside the first-party pwpacks — alongside blocks — and resolve per World at runtime; there is no global capability table.
Surface = Blocks + Capabilities. Blocks are the visual primitives; capabilities are the runtime behaviours that animate them.
The canonical 4
As of 2026-04-23 the registry contains exactly 4 canonical capabilities.
All other names you may see in older docs (auth, data, state, seo,
i18n, analytics, forms, behaviors) have since been retired.
| ID | Responsibility |
|---|---|
platform/persistence | Data fetch + cache; owns dataSources and initialState in binding config. |
platform/entities | Tenant data model, CRUD, lifecycle. |
platform/navigation | Client-side routing between Surfaces. |
platform/interaction | Event-driven rules — attach triggers/actions to Surface events. |
platform/appearanceis not a capability. Visual appearance ships as a dedicated atom kind (ui-appearance), through the same publish pipeline as blocks and capabilities.
Pack bundle model
Capabilities are not toggled individually. They follow the World’s plan bundle — the set of pwpacks installed at plan activation.
Plan activation
→ resolve plan.pack_bundle
→ install each pack
→ record one capability entitlement per capability atom
→ entitlement check: capability marked active?Installed = entitled. Plan upgrade installs additional packs; downgrade soft-uninstalls; re-upgrade reactivates the existing rows.
Default plan bundles
| Plan | Bundle |
|---|---|
| Basic | @pwpack/phiwebs/ui · persistence · entities |
| Pro | + navigation · interaction |
| Team | Pro bundle + extended pwpacks |
| Enterprise | Pro + custom enterprise packs |
Bundles are versioned with the plan; activating or downgrading a plan syncs the World’s pack set automatically.
Runtime resolution
The kernel registry starts empty per World. The first time a Surface references a capability:
- The runtime resolves a per-World capability lookup function with the
signature
(capabilityId, worldId) => Capability | null. - The lookup reads the World’s active capability atoms.
- The bundle URL is dynamically imported on first use; the exported
defineCapabilitybuilder runs. - The resolved capability is cached per World (5-minute LRU).
This means installing a new pwpack reflects in the live World within five minutes without redeploying anything.
Authoring a capability
Capabilities use the same pwpack pipeline as blocks. The canonical
builder is defineCapability(...) in @phimajor-solutions/pwfabric-sdk — see the
defineCapability() SDK reference
for the full API.
See also
defineCapability()SDK reference — author a custom capability- Composition — how blocks + capabilities combine into a Surface
- How it works — how capabilities fit into the surface pipeline