SDK Architecture

The xiboplayer SDK is a modular JavaScript library organized as a pnpm monorepo. Each package handles one concern — combine them to build a full player, or use individual packages in your own projects.

Package dependency graph

@xiboplayer/crypto
  └── @xiboplayer/utils (logger, EventEmitter, config, fetchWithRetry)
        ├── @xiboplayer/schedule (campaigns, dayparting, timeline)
        │     └── @xiboplayer/renderer (XLF rendering, transitions, LayoutPool)
        ├── @xiboplayer/cache (offline storage, chunked downloads)
        │     └── @xiboplayer/sw (Service Worker)
        ├── @xiboplayer/xmds (SOAP + REST CMS client)
        ├── @xiboplayer/xmr (WebSocket push commands)
        ├── @xiboplayer/settings (display settings from CMS)
        ├── @xiboplayer/stats (proof of play, log reporting)
        ├── @xiboplayer/sync (multi-display video walls)
        └── @xiboplayer/proxy (Express CORS proxy + PWA server)

@xiboplayer/core (orchestration — peerDeps on cache, renderer, schedule, xmds)
@xiboplayer/pwa (TypeScript platform layer for browsers)

Data flow

CMS Server
  ↓ XMDS (SOAP/REST)
@xiboplayer/xmds → RegisterDisplay, RequiredFiles, Schedule, GetResource
  ↓
@xiboplayer/core (PlayerCore)
  ├── Parses schedule → @xiboplayer/schedule
  ├── Downloads media → @xiboplayer/cache + DownloadManager
  ├── Renders layouts → @xiboplayer/renderer (RendererLite)
  ├── Reports stats → @xiboplayer/stats
  └── Listens for push → @xiboplayer/xmr (XMR WebSocket)
  ↓
Platform Layer (PWA / Electron / Chromium / Android / webOS)
  → Displays content on screen

Key design decisions

Peer dependencies for core

@xiboplayer/core uses peerDependencies for its heavy modules (cache, renderer, schedule, xmds). This means the platform layer — not core — controls which versions are wired together. It prevents version conflicts and allows the same core to work across different platform setups.

Dual CMS transport

The @xiboplayer/xmds package supports both SOAP (traditional Xibo protocol) and REST (lighter JSON transport). A ProtocolDetector probes the CMS at startup and auto-selects the best transport. Both expose the same method names.

Offline-first architecture

The @xiboplayer/cache package stores all media and schedule data locally. The player can continue operating indefinitely when the CMS is unreachable, replaying the last-known schedule from its local cache.

Event-driven orchestration

PlayerCore communicates with the platform layer entirely through events. It never manipulates the DOM or makes platform-specific calls. Events include collection-start, layout-ready, download-request, layout-blacklisted, and more. This makes it reusable across PWA, Electron, Chromium, Android, and webOS.

Platform wrappers

Each platform wrapper provides:

  1. A way to serve the PWA (Express server for Electron/Chromium, asset loader for Android, Luna service for webOS)
  2. CORS proxying for CMS API calls
  3. Platform-specific features (GPU acceleration, power management, kiosk mode)
PlatformServerPortSpecial features
PWABrowser (Service Worker)Offline via SW, works in any browser
ElectronExpress via @xiboplayer/proxy8765GPU detection, IPC, auto-launch, tray
ChromiumExpress via @xiboplayer/proxy8766Bash launcher, system Chromium
AndroidWebViewAssetLoaderDPM kiosk, foreground service
webOSLuna native service8765ActivityManager keep-alive

Testing

The SDK has 1744 unit tests across 54 test suites (Vitest + jsdom). Integration tests run nightly against a dev CMS instance. The PWA has Playwright e2e tests with a mock CMS.

pnpm test              # unit tests
pnpm lint              # Biome linter
pnpm test:coverage     # with thresholds (50% lines, 40% branches)