Prox OS Docs
Architecture

State Model

Philosophy and anti-patterns: [core-architecture-thinking.md](./core-architecture-thinking.md). This file lists **concrete stores, keys, and files**.

Philosophy and anti-patterns: core-architecture-thinking.md. This file lists concrete stores, keys, and files.

Rule Of Thumb

  • Zustand: browser OS local state.
  • TanStack Query: server state and cache. Planned / not implemented yet in shell runtime.
  • localStorage: persisted user preferences and local-only layout hints.
  • React local state: temporary UI state for panels, dialogs, menus, animations, and previews.
  • Browser localStorage: Shell React surfaces should use useLocalStorage from usehooks-ts. Zustand and other non-React writers use browser-local/browserLocalStore.ts. All Próx-managed keys are listed in browser-local/proxOsLocalStorageKeys.ts (also used by Developer Tool “clear managed storage”).

Zustand

Store: apps/os-shell/src/window-manager/store.ts

Main fields:

FieldMeaningPrimary readers/writers
windowsActive WindowInstance[].useDesktopShellController, WindowLayer, Active Apps panel.
spacesOrdered desktop and fullscreen Spaces.useDesktopShellController, WindowLayer, Mission Control.
activeSpaceIdCurrent virtual desktop or fullscreen Space.WindowLayer, keyboard shortcuts, route sync.
previousSpaceIdPrevious Space used for transition context.Window manager actions.
missionControlModenone, spaces, or windows.Global shortcuts, Mission Control overlay, App Expose transforms.
spaceTransitionDirectionHorizontal Space-switch animation hint.WindowLayer.
activeWindowIdCurrent focused window id.TopBar, WindowLayer, AppSwitcherOverlay, Active Apps panel.
commandOpenCommand surface visibility.DesktopScene, GlobalShortcuts, Shellbar command button.
commandQueryCommand search text.CommandSurface, useCommandModel.
utilityTrayOpenDeveloper tool drawer visibility.Dock, GlobalShortcuts.
activeAppsOpenActive Apps drawer visibility.Dock, Shellbar active apps button.

The store owns durable local OS mechanics: open, close, focus, minimize, desktop zoom, fullscreen Space entry/exit, Space switching, layout hydration, and command/drawer visibility.

localStorage

Settings hook: apps/os-shell/src/shell/settings/useShellSettingsState.ts

Current keys:

  • prox-os.os.density
  • prox-os.os.theme
  • prox-os.os.shellbar-placement
  • prox-os.os.cursor
  • prox-os.os.shellbar-layout
  • prox-os.os.overlay-placement-mode
  • prox-os.os.panel-side
  • prox-os.os.toast-corner
  • prox-os.os.screensaver
  • prox-os.os.screensaver-time
  • prox-os.os.desktop-background
  • prox-os.os.view-mode
  • prox-os.os.language-preference
  • prox-os.os.recent-apps
  • prox-os.os.window-sizes

These preferences are local-first and can later be backed by profile sync without changing presentation components.

React Local State

Controller: apps/os-shell/src/shell/useDesktopShellController.ts

Examples:

  • notifications
  • systemToast
  • aiAssistantOpen
  • aboutOsOpen
  • exitOsOpen
  • snapPreview
  • spaceDropPreview
  • animatedWindowId
  • minimizeAnimation
  • activeAppsPulse

These are view-session states. They should not be stored in Zustand unless other independent subsystems need to observe them. Mission Control is the exception: it lives in Zustand because keyboard handling, Space routing, window transforms, and the overlay all need one shared source of truth.

Small visual affordances inside Mission Control, such as the hover preview for the pinned + control, stay CSS-only inside MissionControlOverlay.tsx. Drag/drop placement feedback uses spaceDropPreview in the shell controller because it depends on the active drag pointer and must be cleared atomically when a window is moved into an existing or newly inserted desktop Space.

TanStack Query

apps/os-shell now mounts QueryClientProvider through apps/os-shell/src/providers.

Current files:

  • apps/os-shell/src/providers/queryClient.ts
  • apps/os-shell/src/providers/QueryProvider.tsx
  • apps/os-shell/src/providers/AppProviders.tsx

React Query Devtools are mounted only in development with initialIsOpen={false}.

No useQuery server data cache is currently used by shell apps yet.

Planned use:

  • app registry fetched from /api/apps
  • synced settings from /api/settings
  • session from /api/user/session
  • server-backed notification, visitor, asset, and project read models

Remote server data should go through TanStack Query, not Zustand.

API / Mock State

Current app data is mostly static local mock data:

  • packages/os-apps/src/shared/mock-data.ts
  • per-app local arrays inside app components

No formal API client is currently used in apps/os-shell.

On this page