Ownership model
Every responsibility in a BeeUI screen belongs to exactly one owner: BeeUI owns component behavior, semantic tokens and the provider/overlay runtime; your application owns routing, data, domain state and product policy.
Prerequisites: read Foundations first — this page assumes the contract-stack framing it establishes.
Why the concept exists
Section titled “Why the concept exists”Almost every hard bug people hit with a UI system is an ownership bug rather than a rendering bug: two safe-area layers both claiming the top inset, a second global toast store mirroring BeeUI’s, an application state machine fighting a component’s internal open state. None of those produce a clean error. They produce a screen that is slightly wrong, on one platform, sometimes.
Drawing the boundary once, explicitly, turns those into questions with an answer.
The boundary
Section titled “The boundary” ┌─────────────────────────────────────────┐ application owns ──► │ router · navigation IA · data fetching │ │ auth · analytics · business policy │ │ domain state · persistence · validation │ │ which shell surface claims which inset │ └──────────────────┬──────────────────────┘ │ props, callbacks, children ┌──────────────────▼──────────────────────┐ BeeUI owns ──► │ component behavior + variants │ │ accessibility semantics per contract │ │ semantic tokens, theme, density │ │ provider/overlay/toast runtime │ │ reusable screen composition patterns │ └─────────────────────────────────────────┘The interface between the two halves is ordinary React: props in, callbacks out, children for composition. There is no hidden channel, no global store you must adopt, and no BeeUI-specific data layer.
BeeUI owns
Section titled “BeeUI owns”| Responsibility | What that means concretely |
|---|---|
| Component behavior | Press, focus, selection, dismissal, keyboard interaction and the accessibility semantics each component’s contract states. |
| Semantic tokens and themes | Color roles, typography scale, spacing, radius, density metrics, breakpoint constants — see Theming. |
| Provider and overlay infrastructure | Safe-area measurement, the anchored-overlay runtime and host, dismissal arbitration, the toast runtime and viewport. |
| Reusable screen composition | The pattern library — real composed screens you copy and adapt. |
Your application owns
Section titled “Your application owns”| Responsibility | Why BeeUI stays out |
|---|---|
| Routing and navigation IA | A router is an architectural commitment with real lock-in; BeeUI components work under any of them. |
| Data, backend and persistence | BeeUI never fetches, caches or stores your data. |
| Domain state and business logic | Including most component state — see State model. |
| Validation rules | BeeUI renders invalid state; it does not decide what invalid means. See Forms model. |
| Auth, analytics, policy | Product decisions, not presentation decisions. |
| Safe-area edge assignment | Only your shell knows which surface touches which system edge. |
Rules and invariants
Section titled “Rules and invariants”- One owner per system edge. Exactly one
SafeAreaclaimstop; exactly one claimsbottom.SafeAreadefaults to all edges, so an unqualified nestedSafeAreais how doubled insets happen. - One
BeeUIProviderat the application root, mounted above the router. Nested providers are for documented provider-scoped behavior, never for layout or styling scope. - Do not mirror runtime state. BeeUI’s toast runtime already owns the queue; a parallel application-global toast store produces two sources of truth and a viewport that disagrees with your state.
- State that has business meaning is yours. If losing the value on unmount would be a bug, it belongs in your state, passed in as a controlled prop.
- Layout composition is application work.
Screen,AppHeader,BottomActionBarandSafeAreaare unopinionated surfaces; they add no implicit system inset padding of their own so your shell stays predictable.
Consequences for application code
Section titled “Consequences for application code”A correctly owned shell reads like this — BeeUI surfaces, application decisions:
import * as React from 'react';import { AppHeader, BeeUIProvider, BottomActionBar, Button, SafeArea, Screen,} from '@beemvp/beeui-ui';
type AppShellProps = { children: React.ReactNode; onSave: () => void; title: string;};
export function AppShell({ children, onSave, title }: AppShellProps) { return ( <BeeUIProvider> <Screen> <SafeArea edges={['top', 'left', 'right']}> {/* `title` comes from your router — BeeUI never reads route state */} <AppHeader title={title} /> </SafeArea>
<SafeArea className="flex-1" edges={['left', 'right']}> {children} </SafeArea>
<SafeArea edges={['bottom', 'left', 'right']}> <BottomActionBar> {/* `onSave` is your domain logic; BeeUI only owns the press contract */} <Button onPress={onSave}>Save</Button> </BottomActionBar> </SafeArea> </Screen> </BeeUIProvider> );}Three surfaces, three different edge claims, and every product decision arriving as a prop.
Common misconception
Section titled “Common misconception”“The library should just handle safe area for me.”
It cannot, and the reason is structural: only your shell knows whether the header, a full-screen map, a native sheet or the router’s own container is the thing touching the notch on this route. A library that applied insets implicitly would be right on the simplest screen and wrong on every screen with a custom presentation — and the failure is silent on Web, because browsers report no system insets. That bug then appears on the first device run.
The related anti-pattern is the blanket wrapper: one SafeArea around the entire application. It looks tidy, and it breaks the moment header, body and footer need different ownership.
Where to go next
Section titled “Where to go next”- Provider & safe area — the executable version of these rules, with the failure table.
- Overlays & runtime ownership — provider-tree ownership in detail.
- State model — where component state should live.
- Patterns — composed screens that already respect this boundary.
- Reference app and the running demo — the boundary at production scale.
- Troubleshooting — when a boundary has already been crossed.
Source authority
Section titled “Source authority”packages/ui/src/components/safe-area.tsx—BeeUIProviderandSafeArea.docs/architecture.md— the boundary contract.docs/responsive-layout.md— shell and layout responsibilities.