---
title: "Expo"
description: "Use Blyp in Expo apps with createExpoLogger(), expo-network, queued retries, and an absolute ingestion URL."
canonical_url: "https://www.blyp.dev/docs/integrations/expo"
markdown_url: "https://www.blyp.dev/docs/integrations/expo.md"
last_updated: "2018-10-20"
x_farming_labs_generated_preamble: true
agent:
  task: "Configure the Expo client logger with queued delivery to an absolute Blyp ingestion URL."
  outcome: "Offline records queue and later reach the server ingestion handler when connectivity resumes."
  appliesTo:
    framework:
      - "expo"
    package:
      - "@blyp/core"
      - "expo-network"
  prerequisites:
    - "A reachable server-side Blyp ingestion handler is deployed or running on the LAN."
  files:
    - "app.json"
    - "src/lib/logger.ts"
  commands:
    - "pnpm add @blyp/core"
    - "pnpm exec expo install expo-network"
  sideEffects:
    - "Client logs can be queued locally and sent over the network."
  verification:
    - "Emit a unique Expo record"
    - "restore connectivity if needed"
    - "and confirm server ingestion receives it."
  rollback:
    - "Remove the Expo logger and restore the previous client logging path."
  failureModes:
    - symptom: "Delivery works on web but not on a device or simulator."
      resolution: "Replace localhost with an absolute host reachable from that device and verify the ingestion route."
---

# Expo
URL: /docs/integrations/expo
LLM index: /llms.txt
Description: Use Blyp in Expo apps with createExpoLogger(), expo-network, queued retries, and an absolute ingestion URL.
Related: /docs/integrations/client, /docs/configuration, /docs/connectors

<!-- farming-labs:agent-contract:start -->
## Agent Contract

Task: Configure the Expo client logger with queued delivery to an absolute Blyp ingestion URL.
Outcome: Offline records queue and later reach the server ingestion handler when connectivity resumes.

### Applies To

- Framework: `expo`
- Package: `@blyp/core`, `expo-network`

### Prerequisites

- A reachable server-side Blyp ingestion handler is deployed or running on the LAN.

### Files

- `app.json`
- `src/lib/logger.ts`

### Commands

- `pnpm add @blyp/core`
- `pnpm exec expo install expo-network`

### Side Effects

- Client logs can be queued locally and sent over the network.

### Verification

- Emit a unique Expo record
- restore connectivity if needed
- and confirm server ingestion receives it.

### Rollback

- Remove the Expo logger and restore the previous client logging path.

### Failure Modes

- Delivery works on web but not on a device or simulator. — Recovery: Replace localhost with an absolute host reachable from that device and verify the ingestion route.
<!-- farming-labs:agent-contract:end -->

# Expo

Install `expo-network`, configure an absolute ingestion URL reachable from the simulator or device,
and test a unique record through the server handler. `localhost` points at the device itself in many
setups. If delivery stays queued, verify network state and reachability before adjusting retry limits.

Expo is a mobile/client integration rather than a server adapter. Use it when you want Blyp logs from an Expo app to sync directly to your backend.

## Install

Install the package and the Expo network module:

```bash
bun add @blyp/core
```

```bash
npx expo install expo-network
```

## Basic setup

```ts
import { createExpoLogger } from "@blyp/core/expo";

const logger = createExpoLogger({
  endpoint: "https://api.example.com/inngest",
  metadata: () => ({
    app: "mobile",
  }),
  delivery: {
    maxRetries: 3,
    retryDelayMs: 5000,
  },
});

logger.info("mounted", { screen: "home" });
logger.error(new Error("Failed to load profile"));
logger.child({ feature: "checkout" }).warn("Validation failed");
```

## Important Expo-specific behavior

- `endpoint` is required
- `endpoint` must be an absolute `http://` or `https://` URL
- remote delivery uses runtime `fetch`
- connectivity metadata comes from `expo-network`
- failed delivery is queued in memory
- retryable failures are retried by default `3` times at `5000ms`
- the default queue limit is `100`
- if `expo-network` is missing, Blyp warns once and skips remote sync
- if the endpoint is not absolute, Blyp warns once and skips remote sync

Retryable Expo failures include:

- offline connectivity state
- network errors
- HTTP `429`
- HTTP `5xx`

When Expo connectivity returns, Blyp resumes queued delivery through the `expo-network` state listener.

## Local console vs remote sync

```ts
const logger = createExpoLogger({
  endpoint: "https://api.example.com/inngest",
  localConsole: true,
  remoteSync: true,
});
```

`localConsole` defaults to `true` and `remoteSync` defaults to `true`.

## Connector forwarding requests

Expo can request server-side forwarding into PostHog, Sentry, or a named OTLP target:

```ts
const logger = createExpoLogger({
  endpoint: "https://api.example.com/inngest",
  connector: "posthog",
});
```

```ts
const logger = createExpoLogger({
  endpoint: "https://api.example.com/inngest",
  connector: "sentry",
});
```

```ts
const logger = createExpoLogger({
  endpoint: "https://api.example.com/inngest",
  connector: { type: "otlp", name: "grafana" },
});
```

Expo still posts to Blyp first. Blyp forwards only when the matching server connector is configured and ready.

## Delivery hooks

Expo supports the same delivery lifecycle callbacks as the browser logger:

```ts
const logger = createExpoLogger({
  endpoint: "https://api.example.com/inngest",
  delivery: {
    onRetry: (ctx) => {
      console.log("retry", ctx.attempt, ctx.reason);
    },
    onSuccess: (ctx) => {
      console.log("success", ctx.transport);
    },
    onFailure: (ctx) => {
      console.log("failure", ctx.reason);
    },
    onDrop: (ctx) => {
      console.log("dropped", ctx.droppedEvent.message);
    },
  },
});
```

These hooks are useful when you want to monitor mobile delivery health, surface diagnostics in development builds, or measure how often events are being queued and replayed.

## Payload shape

Expo emits a client log payload with the same base structure as `@blyp/core/client`, but includes Expo-specific device data:

```ts
{
  type: "client_log",
  source: "client",
  device: {
    runtime: "expo",
    network: {
      type: "WIFI",
      isConnected: true,
      isInternetReachable: true,
    },
  },
}
```

Child loggers share the same in-memory dispatcher and queue, so `.child()` keeps delivery behavior consistent across screens and features.

## Relevant types

```ts
import type {
  ExpoLogger,
  ExpoLoggerConfig,
  ClientConnectorRequest,
  ClientLogEvent,
  ClientLogLevel,
  ClientLogDeviceContext,
  RemoteDeliveryConfig,
  RemoteDeliveryRetryContext,
  RemoteDeliverySuccessContext,
  RemoteDeliveryFailureContext,
  RemoteDeliveryDropContext,
} from "@blyp/core/expo";
```

Use [Connectors](/docs/connectors) for the corresponding server-side PostHog, Sentry, and OTLP setup.

## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
Docs-scoped sitemap: [/docs/sitemap.md](/docs/sitemap.md).
Well-known sitemap: [/.well-known/sitemap.md](/.well-known/sitemap.md).
