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

@sagepilot-ai/react-native-sdk

v0.3.6

Published

Sagepilot AI React Native chat SDK

Readme

@sagepilot-ai/react-native-sdk

Official React Native SDK for adding Sagepilot chat to iOS and Android apps.

The SDK opens the Sagepilot-hosted chat experience inside a React Native WebView and provides APIs for setup, identity, unread count, attachments, and app-owned launchers.

For full integration docs, see React Native SDK docs.

Requirements

  • React 18+
  • React Native 0.72+
  • react-native-webview 13+
  • A Sagepilot workspace ID and chat channel ID
  • Secure token storage for production apps

Install

npm install @sagepilot-ai/react-native-sdk@latest react-native-webview

For secure persisted sessions, install one storage library:

npm install react-native-keychain

Expo apps can use expo-secure-store instead:

npx expo install expo-secure-store

The SDK key is public routing config in the format workspace_id:channel_id. Do not ship server API keys, signing secrets, or private workspace secrets in a React Native app.

Basic Setup

Configure Sagepilot once when your app starts, then mount SagepilotChatProvider near the top of the app.

import * as Keychain from "react-native-keychain";
import { useEffect, type ReactNode } from "react";
import {
  SagepilotChat,
  SagepilotChatProvider,
  createKeychainTokenStorage
} from "@sagepilot-ai/react-native-sdk";

const tokenStorage = createKeychainTokenStorage(Keychain);

export function SagepilotProvider({ children }: { children: ReactNode }) {
  useEffect(() => {
    let cancelled = false;

    async function setupSagepilot() {
      await SagepilotChat.configure({
        key: "workspace_id:channel_id",
        tokenStorage,
        presentation: {
          style: "sheet",
          mobile: true
        },
        behavior: {
          preloadWebView: true,
          enableUnreadPolling: true,
          waitForIdentifyBeforeComposer: true
        }
      });

      if (!cancelled) {
        await SagepilotChat.identify({
          userId: "user_123",
          email: "[email protected]",
          name: "Customer Name"
        });
      }
    }

    void setupSagepilot().catch(console.warn);

    return () => {
      cancelled = true;
      SagepilotChat.destroy();
    };
  }, []);

  return <SagepilotChatProvider>{children}</SagepilotChatProvider>;
}
export function App() {
  return (
    <SagepilotProvider>
      <RootNavigator />
    </SagepilotProvider>
  );
}

More setup details: Configuration.

Opening Chat

Use the hook for app-owned launchers:

import { Pressable, Text } from "react-native";
import { useSagepilotChat } from "@sagepilot-ai/react-native-sdk";

export function SupportButton() {
  const { configured, unreadCount, presentMessages } = useSagepilotChat();

  return (
    <Pressable disabled={!configured} onPress={presentMessages}>
      <Text>
        Support{unreadCount > 0 ? ` (${unreadCount})` : ""}
      </Text>
    </Pressable>
  );
}

You can also call the public methods directly:

import { SagepilotChat } from "@sagepilot-ai/react-native-sdk";

SagepilotChat.present();
SagepilotChat.presentMessages();
await SagepilotChat.presentMessageComposer("I need help with my order");
await SagepilotChat.presentMessageComposer("I need help with my order", { mode: "auto" });
await SagepilotChat.presentMessageComposer("Start a new request", { mode: "new" });
await SagepilotChat.presentMessageComposer("I need help with this order", { chatId: savedChatId });

presentMessageComposer(message) uses { mode: "auto" } by default. It pre-fills the composer and lets Sagepilot reuse an existing conversation when one is available. Use { mode: "new" } only when a workflow should always start a fresh conversation.

presentMessageComposer() returns boolean by default. If behavior.waitForIdentifyBeforeComposer is true and identify() is already in flight, it returns Promise<boolean> and waits up to 60 seconds for identity to finish before opening. You can await it in both cases.

More examples: Opening chat.

Identity

Call identify() after configure() when you know the signed-in customer.

await SagepilotChat.identify({
  userId: "user_123",
  email: "[email protected]",
  name: "Customer Name",
  phone: "+15551234567"
});

Use waitForIdentifyBeforeComposer: true for authenticated support flows where the composer should wait for an in-flight identity request before opening.

const opened = await SagepilotChat.presentMessageComposer("I need help with my order");

When the app user signs out, clear Sagepilot identity/session state:

await SagepilotChat.logout();
// Optional: only call destroy() when your app is tearing down Sagepilot entirely.
SagepilotChat.destroy();

logout() clears hosted WebView identity, removes the persisted customer session, and rotates the SDK onto a fresh anonymous session. The next signed-in user can call identify() without reusing the previous user's conversation context.

More details: Identity.

Attachments

The base package supports custom native file-picker adapters. Apps that want Sagepilot's Android in-app CameraX picker can install the optional addon:

npm install @sagepilot-ai/react-native-camera-addon@latest

The base chat SDK does not bundle CameraX. The optional addon adds these Android dependencies through its own Gradle file:

  • androidx.camera:camera-core
  • androidx.camera:camera-camera2
  • androidx.camera:camera-lifecycle
  • androidx.camera:camera-view
  • androidx.exifinterface:exifinterface
  • androidx.activity:activity

By default, the addon uses CameraX 1.5.3, ExifInterface 1.4.2, and AndroidX Activity 1.10.1. Apps can override them from the root Gradle project with sagepilotCameraXVersion, sagepilotExifInterfaceVersion, and sagepilotActivityVersion.

import { SagepilotChat } from "@sagepilot-ai/react-native-sdk";
import { createSagepilotCameraXFilePicker } from "@sagepilot-ai/react-native-camera-addon";

await SagepilotChat.configure({
  key: "workspace_id:channel_id",
  filePicker: createSagepilotCameraXFilePicker()
});

Run a fresh native Android build after installing the addon so React Native autolinking can register the native module.

More details: Native file picker.

Method Return Behavior

| Method | Return behavior | |---|---| | SagepilotChat.configure(config) | Promise<SagepilotMobileConfigureResult> | | SagepilotChat.identify(identity) | Promise<SagepilotIdentifyResult> | | SagepilotChat.logout() | Promise<SagepilotLogoutResponse> | | SagepilotChat.getSession() | Promise<SagepilotSessionState> | | SagepilotChat.getUnreadCount() | Promise<number> | | SagepilotChat.presentMessageComposer(message?, options?) | boolean or Promise<boolean> when waitForIdentifyBeforeComposer is enabled and identity is pending | | SagepilotChat.present() | boolean | | SagepilotChat.presentMessages() | boolean | | SagepilotChat.dismiss() / hide() / toggle() | boolean | | SagepilotChat.isPresented() | boolean | | SagepilotChat.getIdentityState() / getSessionState() / getChannel() | synchronous state | | SagepilotChat.onIdentify(...) / onConversationCreated(...) / lifecycle subscriptions | unsubscribe function | | SagepilotChat.destroy() | void |

Full API reference: SDK API reference.

Useful Links

License

MIT