xprem Documentation

repository·main·Indexed 18 days ago

https://github.com/axelmarciano/expo-open-ota

xprem (formerly Expo Open OTA) is a self-hosted, open-source alternative to EAS Update for Expo and React Native apps. It implements the official Expo Updates protocol to provide a control plane for managing OTA updates, progressive rollouts, A/B testing, and observability. Key components include the @xprem/control-center for branch surfing, the eoas CLI for publishing updates, and a dashboard for managing branches and channels.

Tokens
27.9K
Snippets
87
Records
120
Agent score
64%

What's inside xprem

  1. Overview of xprem

    main

    xprem (formerly Expo Open OTA) is a self-hosted control plane for serving Over-The-Air (OTA) updates to Expo and React Native apps. It implements the official Expo Updates protocol, allowing you to use the standard expo-updates runtime without modifications.

    Key capabilities include:

    • Update Management: Publish, roll back, and republish updates via the eoas CLI or a dashboard.
    • Control Plane: Manage branches, channels, and progressive rollouts.
    • Observability: Track native/JS crashes, adoption, and performance metrics (bundle load, render times) tied to specific updates.
    • Infrastructure Ownership: You own the storage (S3, GCS, R2, etc.) and the delivery (CloudFront, signed URLs, etc.).
  2. Understand the Enterprise Edition (ee/) licensing model

    main

    The ee/ directories (e.g., ee/ or apps/dashboard/src/ee/) contain the source code for xprem Enterprise Edition. Unlike the rest of the repository which is MIT licensed, code within ee/ directories is governed by a commercial license.

    Key usage rules:

    • You may read, copy, or modify ee/ code for development and testing purposes.
    • Using ee/ code in production requires a valid Enterprise license key.
  3. Observability and Telemetry with xprem

    main

    xprem provides deep observability by tying every metric, crash, and log to the exact update that produced it.

    Supported Data Types

    • Crashes: Both Native and JS crashes, including device counts per update.
    • Performance Metrics: Breakdown by device model, OS, region, app version, and screen (via react-navigation). Includes bundle load, time to first render, time to interactive, and cold launch percentiles.
    • Custom Events & Logs: Ship structured events and logs from your app to be viewed alongside delivery data.

    Data Ownership

    All telemetry data is stored in your own ClickHouse database. This allows you to use your own tools like Grafana, PostHog, or Datadog, or query it directly. Hermes source maps are supported for Sentry or PostHog integration.

  4. Choose between expo-router and React Navigation trees

    main

    The app supports two different navigation integrations for expo-observe to record per-screen metrics (cold_ttr, warm_ttr, and tti). Because they cannot both run at once, you must choose which navigation tree to bundle at build time using specific scripts. The choice is inlined by Metro via EXPO_PUBLIC_NAV and cannot be changed at runtime.

    • expo-router tree: Routes live in the app/ directory. Use yarn start.
    • React Navigation tree: Routes are defined in the navigation/ directory. Use yarn start:react-navigation.

    This pattern applies to other scripts as well, such as yarn release_staging:react-navigation for publishing updates using the React Navigation tree. When using React Navigation, the environment variable EXPO_ROUTER_DISABLE_RN_NAVIGATION_CHECK=1 is required.

    yarn start                     # expo-router tree, routes live in app/
    yarn start:react-navigation    # @react-navigation tree, defined in navigation/
    yarn release_staging:react-navigation # publish an update running the React Navigation tree
  5. How OTA updates, channels, and rollouts work

    main

    xprem uses the Expo Updates protocol to manage how devices receive code updates.

    Core Concepts

    • Channels: Each app build has a channel baked in. You point a channel at a specific branch to determine which updates those builds receive. This allows you to remap channels to different branches for rollouts or rollbacks without rebuilding the app or submitting to stores.
    • Branches: Used to group updates. You can point channels at branches to control deployment.
    • Progressive Rollouts: You can serve an update to a specific percentage of a branch. The split is deterministic and requires no per-device state.
    • A/B Testing: A single channel can serve two different branches simultaneously, with devices split deterministically between them.

    Workflow

    1. Publish: Use the eoas CLI to export bundles and upload assets to your storage.
    2. Deploy: Point a channel to a branch containing the new update.
    3. Monitor: Watch health data (crashes, metrics) as the rollout progresses.
    4. Adjust: Raise the rollout percentage or revert/roll back if regressions are detected.
  6. How Enterprise feature gating and activation works

    main

    Enterprise features are compiled directly into the standard server binary but remain dormant until a valid license key is activated.

    Activation Mechanism:

    • License Issuance: Licenses are issued via Keygen using the ED25519_SIGN scheme.
    • Verification: Verification is performed fully offline by the ee/licensing module against the account's embedded Ed25519 verify key. The system does not make network calls or 'phone home' to verify status.
    • Runtime Check: You can check the activation state in code using licensing.IsEnterprise().
    // Example of checking enterprise status
    if licensing.IsEnterprise() {
        // Execute enterprise-only logic
    }
  7. Using the xprem MCP server

    main

    xprem includes a Model Context Protocol (MCP) server that allows AI agents (like Cursor, VS Code, or Claude Code) to interact with your xprem deployment.

    Capabilities

    Agents can perform the same operations as a dashboard user via OAuth:

    • List branches, channels, and updates.
    • Check rollout status.
    • Perform rollbacks and republishes.
    • Query telemetry (metrics, events, and logs) using plain language.

    Security

    Agents sign in using OAuth with the same per-user, per-app permissions used in the dashboard. No API keys are required.

  8. How branch surfing works and how to manage it

    main

    Behavior

    • Activation: At launch, the component checks the server to see if branch surfing is allowed for the current channel. If allowed, a blue marker appears. If not, the component renders null and registers nothing.
    • Visibility: You can enable or disable the panel for an entire channel via the xprem dashboard. Enabling it makes the marker appear on the next launch of any build on that channel without requiring a new build.
    • Branch Selection: The panel shows the current branch and a list of other branches compatible with the current binary's runtime version. Branches that require different native code are automatically excluded to prevent dead ends.

    Troubleshooting Stuck Builds

    If a branch crashes on launch, expo-updates will roll back to the embedded bundle. If a device becomes stuck on a specific branch, follow these steps in order:

    1. Publish a fix to the branch being tested.
    2. Turn branch surfing off for the channel in the dashboard (this forces all devices to revert).
    3. Reinstall the app to clear the stored branch choice.
  9. Understand the xprem license model

    main

    The project follows an open-core model.

    MIT Licensed (Free for production):

    • Publishing, branches, channels, and rollbacks.
    • All storage backends and CDN integrations.
    • The dashboard and Prometheus metrics.

    Commercial License Required (Enterprise Edition): These features reside in the ee/ directories and are verified offline. They include:

    • RBAC: Role-based access control for granular permissions.
    • SSO: Single Sign-On via Microsoft Entra ID, Okta, Google Workspace, Keycloak, or OpenID Connect.
    • Branch protection: Restricting which API keys can publish to specific branches (e.g., protecting production).
    • Custom device attributes: Attaching custom metadata to logs, metrics, and events for advanced slicing.
  10. Configure eslint-plugin-react for React projects

    main

    To use React-specific linting rules, install eslint-plugin-react and update your eslint.config.js. You must specify the React version in the settings object and include both the recommended rules and the jsx-runtime rules to avoid conflicts with the modern JSX transform.

    // eslint.config.js
    import react from 'eslint-plugin-react'
    
    export default tseslint.config({
      // Set the react version
      settings: { react: { version: '18.3' } },
      plugins: {
        // Add the react plugin
        react,
      },
      rules: {
        // other rules...
        // Enable its recommended rules
        ...react.configs.recommended.rules,
        ...react.configs['jsx-runtime'].rules,
      },
    })
  11. Add xprem documentation to Claude Code via MCP

    main

    You can use the xprem documentation as a source for your AI assistant by adding the provided MCP server URL. This allows tools like Claude Code to answer questions about the project using the official docs.

    claude mcp add --transport http xprem-docs https://mercure-technologies.gitbook.io/xprem/~gitbook/mcp
  12. Deploying xprem

    main

    xprem is a single Go process designed to be stateless and horizontally scalable. You can run multiple replicas behind a load balancer.

    Deployment Options

    • Docker image
    • Helm chart
    • Single static Go binary (e.g., under systemd)

    Operational Modes

    • Stateless Mode: Runs without any database. Use this if you only want to ship updates from your own bucket.
    • Full Control Plane: Requires PostgreSQL to enable the multi-app dashboard, rollouts, and advanced control plane features.