Appearance
Single app vs composition
Default: single app. Codenames, Chess, Tic-Tac-Toe, polls, whiteboards — all single apps. One synced-store schema with the right visibility tiers handles role-specific or hidden state without splitting.
Compose into multiple apps only when at least one holds:
- Sub-experiences must be private to a subset of the parent's users (e.g. a private Discord channel inside a server). Synced-store's per-user privacy is per-instance, so scoping the child as its own instance beats encoding per-channel ACLs in one giant schema.
- The sub-app is a reusable, independently-publishable piece (e.g. a "threaded chat" primitive multiple parents could embed).
- Lifecycles diverge sharply — parent persists across long timescales (server membership, tournament season) while children are created / used / archived independently (channels, individual matches). A March-Madness tournament parent that pairs players into independent chess matches is the canonical case: bracket / scheduling / leaderboard live in the parent, each match is its own
<poe-app>instance reusing an existing single-app game unchanged.
Not enough reasons: "cleaner architecture", different screens / modes / roles of the same experience, splitting lobby + game. Routes inside one app are simpler than cross-app coordination.
How composition works: the manager (platform-owned root) renders any creator app via <poe-app type-id="..." instance-id="...">. Any creator app can also embed children via the same element (registerPoeAppElement from poe-apps-sdk/v1/client.js). Each child gets its own synced-store instance scoped to the chosen instance-id.
<poe-app> resolves children by type-id, which only exists once the child has been published. When composing: publish each child first, capture type-id from app-platform apps list, wire into parent as constants, then republish the parent.
If the prompt is ambiguous, briefly describe the single-app vs composed plan and confirm before scaffolding.