npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@nlite/logger-react-native

v1.0.2

Published

> Mobile observability for React Native apps — auto-captures JS errors, native crashes, network requests, resource usage, frame rate, slow promises, and app-lifecycle transitions. Ships with an offline-first transport backed by `AsyncStorage` so logs surv

Readme

@nlite/logger-react-native

Mobile observability for React Native apps — auto-captures JS errors, native crashes, network requests, resource usage, frame rate, slow promises, and app-lifecycle transitions. Ships with an offline-first transport backed by AsyncStorage so logs survive flaky networks.

Built on top of @nlite/logger-core. Designed to be ingested by @nlite/logger-server.


Table of Contents

  1. Why this SDK?
  2. Installation
  3. Quick Start
  4. Configuration
  5. React API (LoggerProvider, hooks, HOC)
  6. Standalone API
  7. Captured Signals
  8. Workflow & Lifecycle
  9. Architecture Diagrams
  10. Examples
  11. Optional Native Modules
  12. Privacy & Sampling
  13. Scripts
  14. Compatibility
  15. License & Author

Why this SDK?

Most mobile logging libraries give you breadcrumbs — NLite gives you telemetry:

  • Crash reporting for JS errors, promise rejections, and native crashes (when a compatible module is installed).
  • Network monitoring by instrumenting fetch and XMLHttpRequest.
  • Resource monitoring — memory, CPU, battery, network I/O.
  • Performance monitoring — frame rate, slow InteractionManager callbacks.
  • App lifecycle breadcrumbs — app_start, app_background, app_foreground, etc.
  • Offline queue — failed batches are persisted in AsyncStorage and flushed on reconnect.
  • Single React provider — <LoggerProvider> + useNLiteLogger().

Installation

# npm
npm install @nlite/logger-react-native @react-native-async-storage/async-storage

# pnpm
pnpm add @nlite/logger-react-native @react-native-async-storage/async-storage

# yarn
yarn add @nlite/logger-react-native @react-native-async-storage/async-storage

For iOS, run cd ios && pod install.

Requirements

| Tool | Version | |------|---------| | React Native | >=0.70.0 (peer) | | React | >=18.0.0 (peer) | | @react-native-async-storage/async-storage | ^1.21.0 | | Node.js (build only) | >=18.0.0 |


Quick Start

Wrap your app root:

import React from 'react';
import { LoggerProvider } from '@nlite/logger-react-native';

export default function App() {
  return (
    <LoggerProvider
      config={{
        apiKey: 'YOUR_API_KEY',
        endpoint: 'https://logs.example.com',
        appName: 'shop-mobile',
        appVersion: '2.4.1',
        environment: 'production',
        platform: 'react-native',
      }}
    >
      <RootNavigator />
    </LoggerProvider>
  );
}

Use it in any component:

import { useNLiteLogger } from '@nlite/logger-react-native';

export function CheckoutButton() {
  const logger = useNLiteLogger();

  const onPress = () => {
    logger.addBreadcrumb({
      type: 'ui',
      category: 'tap',
      message: 'Checkout tapped',
      level: 'info',
    });
    logger.info('Checkout started', { cartId: 'c_42' });
    // ...
  };

  return <Button title="Checkout" onPress={onPress} />;
}

Configuration

ReactNativeSdkConfig extends SdkConfig and adds:

| Field | Type | Default | Description | |-------|------|---------|-------------| | platform | 'react-native' \| 'android' \| 'ios' | — | Required. | | enableNativeCrashReporting | boolean | true | Wire to RNExceptionHandler / ReactNativeExceptionHandler / RNCrashReporter when available. | | enableNetworkMonitoring | boolean | true | Instrument fetch + XMLHttpRequest. | | enableConsoleCapture | boolean | true (in __DEV__) | Mirror console.* calls into logs. | | enableResourceMonitoring | boolean | true | Periodic memory / CPU / battery / network metrics. | | resourceMonitoringInterval | number | 30000 | Milliseconds between metric collections. | | enablePerformanceMonitoring | boolean | true | Frame rate + slow InteractionManager warnings. | | enableInteractionTracking | boolean | false | Track slow user interactions. | | offlineStorageMaxSizeMB | number | 10 | Max size of the persisted offline queue. | | resourceSampleRate | number (0-1) | 1.0 | Probability of collecting each resource sample. | | captureRequestResponseBodies | boolean | false | Capture fetch/XHR request/response bodies. | | maxBodyCaptureSize | number | 10000 | Bytes to keep before truncating captured bodies. |


React API (LoggerProvider, hooks, HOC)

<LoggerProvider config>

Wraps the app. Calls initLogger(config) on mount and destroyLogger() on unmount.

<LoggerProvider config={{ /* ... */ }}>
  {children}
</LoggerProvider>

useNLiteLogger(): LoggerSdk

Returns the logger from the closest provider. Throws if used outside a provider.

useLogger(): LoggerSdk

Returns the singleton logger. Throws if initLogger has not been called.

withLogger(Component, propName?)

Higher-order component for class components:

export default withLogger(ProfileScreen, 'logger');

Standalone API

You can also initialise without the provider:

import { initLogger, getLogger, destroyLogger, setUser, addBreadcrumb, flush } from '@nlite/logger-react-native';

export function bootstrap() {
  initLogger({
    apiKey: 'KEY',
    appName: 'shop-mobile',
    platform: 'react-native',
    endpoint: 'https://logs.example.com',
    enableResourceMonitoring: true,
    enableNetworkMonitoring: true,
  });

  setUser('user_42', { plan: 'pro' });
  addBreadcrumb({ type: 'navigation', category: 'screen', message: 'Home', level: 'info' });
}

// In your lifecycle code:
onAppShutdown(async () => {
  await flush();
  await destroyLogger();
});

logNetworkRequest(data) (manual)

For GraphQL clients, Axios, or libraries that bypass fetch:

logNetworkRequest({
  url: '/graphql',
  method: 'POST',
  statusCode: 200,
  durationMs: 84,
  requestBody: '{ query GetProducts }',
  responseBody: '{ data: { products: [...] } }',
});

collectResourceMetrics() (manual)

Force a sample outside the periodic timer (e.g. before a heavy operation):

collectResourceMetrics();
heavyOperation();
collectResourceMetrics();

Captured Signals

| Signal | How it's produced | Logged as | |--------|-------------------|-----------| | JS error | ErrorUtils.setGlobalHandler | error with type: 'js_error', fatal flag | | Promise rejection | global.onunhandledrejection | error with type: 'unhandled_promise_rejection' | | Native crash | Optional native module handler | error with type: 'native_crash', fatal | | Previous-session crash | Read @nlite_last_crash from AsyncStorage on startup | error with stored crash metadata | | console.error | Hooked console.error | error with full args | | Network request | Patched fetch + XMLHttpRequest | breadcrumb + info('network_request', …) | | App lifecycle | AppState listener | info('lifecycle_*', …) + breadcrumb | | Resource metrics | Periodic timer | breadcrumb + info('resource_metrics', …) | | Frame rate drop | requestAnimationFrame loop | warn when fps < 30 | | Slow interaction | Wrapped InteractionManager.runAfterInteractions | warn when > 100ms |


Workflow & Lifecycle

                  ┌──────────────────────────────────────────┐
                  │  LoggerProvider / initLogger(config)     │
                  └─────────────────────┬────────────────────┘
                                        │
            ┌───────────────────────────┼───────────────────────────┐
            ▼                           ▼                           ▼
   ReactNativeTransport          ResourceMonitor              NetworkMonitor
   - fetch + XHR transport      - memory / CPU / battery     - fetch / XHR hook
   - offline AsyncStorage        - frame rate (rAF loop)     - body capture
   - reconnect on AppState       - slow InteractionManager   - GraphQL helper
            │                           │                           │
            └─────────────┬─────────────┴─────────────┬─────────────┘
                          ▼                           ▼
                    CrashReporter                AppLifecycleTracker
                    - ErrorUtils hook            - app_start / background /
                    - unhandledrejection           foreground / inactive
                    - native module handler
                          │                           │
                          └─────────────┬─────────────┘
                                        ▼
                          ┌───────────────────────────┐
                          │  @nlite/logger-core       │
                          │  queue → batch → retry    │
                          └─────────────┬─────────────┘
                                        ▼
                          POST {endpoint}/api/logs/batch
                          @nlite/logger-server

Offline flow

   Network down                        Network up
        │                                  │
        ▼                                  ▼
   log() → transport.send() fails    AppState → 'active'
        │                                  │
        ▼                                  ▼
   push to offlineQueue            flushOfflineQueue()
   persist to AsyncStorage               │
                                        ▼
                                transport.send(batch)
                                        │
                                        ▼
                                success → drop from queue
                                failure → push back, retry

Session & lifecycle

  • A session is created on initLogger (UUID v4).
  • app_start / app_background / app_foreground / app_inactive are emitted as info('lifecycle_*', …) logs.
  • The AppLifecycleTracker records background duration and re-flushes the offline queue when the app returns to foreground.

Architecture Diagrams

Component view

                     ┌──────────────────────────────────────┐
                     │        React Native App              │
                     │  <LoggerProvider config={...}>       │
                     └────────────────┬─────────────────────┘
                                      │
                                      ▼
         ┌────────────────────────────────────────────────────────┐
         │  initLogger(config)                                    │
         │    ├─ ReactNativeTransport(endpoint, key)              │
         │    ├─ setupAutoCapture(logger, config)                 │
         │    ├─ resourceMonitor.start()                          │
         │    ├─ networkMonitor.start()                           │
         │    ├─ crashReporter.start()                            │
         │    └─ lifecycleTracker.start()                         │
         └────────────────────────┬───────────────────────────────┘
                                  │
                                  ▼
              ┌────────────────────────────────────────┐
              │  @nlite/logger-core (CoreLogger)       │
              │   queue → batch → retry/backoff        │
              └────────────────────┬───────────────────┘
                                   │
                                   ▼
                  POST {endpoint}/api/logs/batch
                  @nlite/logger-server (SQLite + Redis)

Sequence — JS error path

JS runtime    ErrorUtils   CrashReporter   CoreLogger   Transport   AsyncStorage   Server
     |             |             |             |             |              |          |
     | throw err   |             |             |             |              |          |
     |------------>|             |             |             |              |          |
     |             | handler     |             |             |              |          |
     |             |------------>|             |             |              |          |
     |             |             | logger.error|             |              |          |
     |             |             |------------>|             |              |          |
     |             |             |             | batch POST  |              |          |
     |             |             |             |------------>| 200 OK       |          |
     |             |             |             |             |<-------------|          |
     |             |             |             |             |              |          |

Sequence — offline path

App           Transport     AsyncStorage   Network
 |                |              |             |
 |  log()        |              |             |
 |--------------->|              |             |
 |  send() fail  |              |             |
 |  offline push |              |             |
 |--------------->|--------------->|             |
 |                |              |             |
 | (later) AppState 'active'    |             |
 |                |              |             |
 |                | flushOffline |             |
 |                |------------->|             |
 |                | batch        |             |
 |                |---------------------------->|
 |                |       200 OK |             |
 |<---------------|              |             |

Examples

Setting user + tags after login

import { setUser, setTags } from '@nlite/logger-react-native';

async function onLogin(user) {
  setUser(user.id, { email: user.email, plan: user.plan });
  setTags({ tenant: user.tenantId, appBuild: '2.4.1' });
}

Capturing non-fetch HTTP traffic (e.g. Axios)

import axios from 'axios';
import { logNetworkRequest } from '@nlite/logger-react-native';

const instance = axios.create();
instance.interceptors.response.use(
  (res) => {
    logNetworkRequest({
      url: res.config.url!,
      method: (res.config.method ?? 'get').toUpperCase(),
      statusCode: res.status,
      durationMs: res.config.metadata?.durationMs ?? 0,
      requestHeaders: res.config.headers as Record<string, string>,
      requestBody: JSON.stringify(res.config.data),
      responseBody: JSON.stringify(res.data),
    });
    return res;
  },
  (err) => {
    logNetworkRequest({
      url: err.config?.url ?? '',
      method: (err.config?.method ?? 'get').toUpperCase(),
      statusCode: err.response?.status ?? 0,
      durationMs: 0,
      error: err.message,
    });
    return Promise.reject(err);
  }
);

Disable sampling for high-volume flows

initLogger({
  /* ... */
  enableResourceMonitoring: true,
  resourceSampleRate: 0.1, // 10% of intervals
  enableInteractionTracking: false,
});

Optional Native Modules

The crash reporter and resource monitor rely on optional native bridges:

| Module | Used for | |--------|----------| | RNExceptionHandler / ReactNativeExceptionHandler | Native crash handling | | RNCrashReporter | Crash metadata | | RNDeviceInfo / DeviceInfo | Memory, CPU, battery, network I/O |

If none is installed the SDK silently falls back to JS-only metrics.


Privacy & Sampling

  • Use resourceSampleRate to throttle high-frequency telemetry.
  • Set captureRequestResponseBodies: false unless you really need payloads.
  • The default beforeSend (from @nlite/logger-core) lets you redact PII before transmission.
  • Offline queue is capped by offlineStorageMaxSizeMB (default 10 MB) and is wiped after a successful flush.

Scripts

| Script | Description | |--------|-------------| | npm run build | tsc to dist/. | | npm run dev | Watch-mode build. | | npm test | Vitest. | | npm run test:watch | Vitest watch. | | npm run lint | ESLint over src. | | npm run typecheck | tsc --noEmit. |


Compatibility

  • React Native 0.70 → 0.74+ (Hermes & JSC supported).
  • iOS >=12, Android minSdkVersion 21.
  • TypeScript 5.3+.

License & Author

MIT — © Debanjan Dasgupta. See the root README.