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

@experiaapp/webchat-react-native

v2.0.7

Published

Experia App live-chat SDK for React Native — drop a real-time support channel (chat, media & video calls) into your app so your customers can reach you with ease.

Readme

@experiaapp/webchat-react-native

A drop-in React Native webchat SDK — real-time chat, media attachments (images, documents, voice notes), and 1:1 video calls — that you embed in your app with a single component. Theming, language (English/Arabic), and behavior are driven by your channel configuration.

  • Real-time messaging (text, quick replies, message status, unread tracking)
  • Attachments — photos, PDF documents, and recorded voice notes
  • In-app video calls (optional)
  • Server-driven theming + a customizable launcher
  • English / Arabic with full RTL
  • Works in Expo and bare React Native

Requirements

  • React Native >= 0.85, React >= 19 (New Architecture)
  • Node.js >= 20.19.4 to build — the Expo SDK 56 / RN 0.85 minimum (Expo SDK 56 changelog: "React Native 0.85 drops support for Node.js versions before v20.19.4")
  • An Expo-managed / dev-client app, or a bare RN app with Expo Modules (see Bare React Native)
  • A channel and connection details from your Experia account

Tested against: React Native 0.85.x, Expo SDK 56, React 19.2. The peer ranges (react-native >=0.85, expo-* >=56, react >=19) leave newer versions open so installs don't break when you bump RN/Expo, but only the matrix above is verified — if you hit an issue on a newer release, pin back to it.


Installation

# the SDK
npm install @experiaapp/webchat-react-native

# required peers (Expo apps)
npx expo install \
  react-native-safe-area-context \
  react-native-localize \
  @react-native-async-storage/async-storage

Bare React Native (RN CLI)? Do the Bare React Native (RN CLI, no Expo) setup first — it installs the Expo Modules runtime, which is what makes npx expo install and expo/metro-config available in a bare app.

Optional peers (each enables a feature when installed)

Install the peers for the features you want. A missing peer degrades gracefully at runtime, but not all in the same way: UI-backed features hide their control (attachment and video-call buttons, SVG icons), while behavioral ones fall back to a safe no-op — audio routing uses the default route, screen-capture protection is skipped, and connectivity-aware reconnect is disabled. Use npx expo install so versions match your Expo SDK:

| Feature | Install | | --- | --- | | Photo / document attachments | npx expo install expo-image-picker expo-document-picker expo-file-system | | Crisp vector icons | npx expo install react-native-svg | | Connectivity-aware reconnect | npx expo install @react-native-community/netinfo | | Screen-capture protection (secureScreen) | npx expo install expo-screen-capture | | Video calls | npx expo install react-native-webrtc react-native-incall-manager (managed apps also need the config plugin — see Expo config plugin) |

Voice notes use expo-audio, which ships as a direct dependency of the SDK — it's installed automatically; there's nothing to add. (Like expo-font/expo-video, its native side still needs the Expo Modules runtime — see Bare React Native.)

Skipping any optional peer? Metro resolves every require() at build time, and some SDK imports are static (e.g. react-native-webrtc via the video tile), so omitting a peer fails the bundle (Unable to resolve module …) unless you add the Metro helper. This applies to both bare RN CLI and Expo-managed apps — the only case where you can skip the helper is if you install every optional peer. See Bare React Native (RN CLI, no Expo) for the one-line withExperiaOptionalDeps wrapper (it's a harmless no-op when all peers are present).

Expo config plugin

Add the plugin to your app.json / app.config.js so the required iOS/Android permissions (camera, microphone, photo library) are injected at build time:

{
  "expo": {
    "plugins": [
      "@experiaapp/webchat-react-native",
      "@config-plugins/react-native-webrtc"   // only if you use video calls
    ]
  }
}

@config-plugins/react-native-webrtc is a separate build-time plugin — install it (only if you use video calls) so expo prebuild can configure WebRTC's native side:

npx expo install @config-plugins/react-native-webrtc

Video calls need a development buildreact-native-webrtc is a third-party native module that isn't included in Expo Go. The other features (chat, photo/document attachments via ImagePicker, voice notes via expo-audio, screen-capture protection) use modules that ship in Expo Go, so they run there — but a development build (eas build, or expo prebuild && expo run:ios|run:android) is still recommended for full, production-configured behavior (your app.json permissions and native config only apply to a build, not Expo Go).

Bare React Native (RN CLI, no Expo)

The media, icon, and video features build on Expo Modules + native peers. In a bare React Native CLI app do the following once, in order, then rebuild:

1. Install the Expo Modules runtime. Required so any expo-* module — including the built-in expo-audio / expo-font / expo-video dependencies — can load its native side. It also makes npx expo install and expo/metro-config available in your app:

npx install-expo-modules@latest

2. Install the required peers (SDK-compatible versions). These are not optional — don't rely on your package manager to add peer dependencies for you:

npx expo install react-native-safe-area-context react-native-localize @react-native-async-storage/async-storage

3. Install the peers for the features you want with npx expo install (it picks SDK-compatible versions — Expo docs). Install only what you need; skip the rest:

npx expo install expo-image-picker expo-document-picker expo-file-system   # photo / document attachments
npx expo install react-native-svg                                          # crisp vector icons
npx expo install @react-native-community/netinfo                           # connectivity-aware reconnect
npx expo install expo-screen-capture                                       # screen-capture protection
npx expo install react-native-webrtc react-native-incall-manager           # video calls

4. Extend expo/metro-config and wrap it with the SDK helper. Since Expo Modules are in use, extend expo/metro-config (not @react-native/metro-configExpo docs). The helper is what lets you safely skip peers in step 3: Metro resolves every require() at build time, so a missing peer would otherwise fail the bundle with Unable to resolve module …. It stubs any uninstalled optional peer, and that feature degrades (its UI hides, or it becomes a no-op):

// metro.config.js
const { getDefaultConfig } = require("expo/metro-config");
const { withExperiaOptionalDeps } = require("@experiaapp/webchat-react-native/metro");

module.exports = withExperiaOptionalDeps(getDefaultConfig(__dirname));

Add the wrapper whenever you skip any peer. If you installed all of them it's a harmless no-op (installed peers resolve normally). The helper needs Metro 0.68+ (RN 0.68+) for resolveRequest; this SDK itself targets RN ≥ 0.85 (Expo SDK 56).

5. Add the native permissions manually. The Expo config plugin only runs during expo prebuild, so a bare app must add the permissions itself — for the features it uses:

ios/<YourApp>/Info.plist:

<key>NSCameraUsageDescription</key>     <string>Used for photo attachments and video calls.</string>
<key>NSMicrophoneUsageDescription</key> <string>Used for voice notes and video calls.</string>
<key>NSPhotoLibraryUsageDescription</key><string>Used to attach photos and documents.</string>

android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<!-- ONLY if you implement a background-call foreground service (the plugin's `backgroundCall` option): -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />

This mirrors exactly what the Expo config plugin injects. READ_EXTERNAL_STORAGE is capped at maxSdkVersion="32" (API 33+ uses READ_MEDIA_*). The two FOREGROUND_SERVICE* lines are not added by default — only when you opt into a background-call foreground service — so omit them unless you've built that.

6. Rebuild the native app — native modules need a fresh build, not just a Metro reload:

cd ios && pod install && cd ..   # iOS only
npx react-native run-ios         # or: npx react-native run-android

Quick start

import React from "react";
import { SafeAreaProvider } from "react-native-safe-area-context";
import { WebChat } from "@experiaapp/webchat-react-native";

const CONFIG = {
  channelId: "YOUR_CHANNEL_ID",
  connectionUrl: "YOUR_SOCKET_HOST",
  configUrl: "YOUR_CONFIG_HOST",
  language: "en", // "en" | "ar"
};

export default function App() {
  return (
    <SafeAreaProvider>
      <WebChat config={CONFIG} />
    </SafeAreaProvider>
  );
}

That's the whole integration: a floating launcher button appears, and tapping it opens the chat. Branding, title, avatar, and theme come from your channel configuration (fetched via configUrl), so you usually only provide the connection details above.

channelId, connectionUrl, and configUrl identify and connect your channel — you receive these with your Experia account.


Configuration

The config prop carries your connection details. Everything else — video calls, attachments, the pre-chat form, branding, title, avatar, and colors — is configured in your Experia channel and fetched at runtime via configUrl. In most apps you only pass the connection details (plus, optionally, the language):

<WebChat
  config={{
    channelId: "YOUR_CHANNEL_ID",
    connectionUrl: "YOUR_SOCKET_HOST",
    configUrl: "YOUR_CONFIG_HOST",
    language: "en", // "en" | "ar" — drives RTL (optional)
  }}
/>

Managed in your Experia channel (no app changes)

Controlled from your channel configuration and applied automatically — you don't set these in code:

  • Features: video calls, image / document / voice attachments, emoji picker, typing indicator, "powered by" badge
  • Launcher & chrome: default launcher visibility, close button, online/offline status, connecting text
  • Branding: theme & colors, header title/subtitle, agent avatar, launcher image
  • Pre-chat form: enabled, fields (text / email / phone / dropdown), labels, headline, submit label
  • Behavior: history-persistence window, welcome message

Advanced — overriding the channel config

Precedence is prop → channel → default, so you can override any setting per build by passing it on config. This is an escape hatch, not the usual path — e.g. force a pre-chat form or turn video off regardless of the channel:

<WebChat
  config={{
    channelId: "YOUR_CHANNEL_ID",
    connectionUrl: "YOUR_SOCKET_HOST",
    configUrl: "YOUR_CONFIG_HOST",
    makeVideoCall: false, // override the channel
    prechatForm: {
      enabled: true,
      fields: [{ key: "name", type: "text", label: { en: "Name", ar: "الاسم" }, required: true }],
    },
  }}
/>

Host-side props

These live on the component, not the channel config:

| Prop | Type | Description | | --- | --- | --- | | config | object | Connection details (+ optional overrides). Required. | | open | boolean | Open the surface on mount. | | title | string | Override the channel's header title. | | renderLauncher | ({ open }) => ReactNode | Render your own launcher (see below). | | prechatValues | Record<string, string> | Pre-fill the greeting with known user data. | | disabledInput | boolean | Lock the composer. | | secureScreen | boolean | Block screen capture while the chat is open (best-effort). |

Callbacks: onOpen, onClose, onMessageReceived(message), onConnected, onDisconnected, onError(error), onUnreadChange(count).


Controlling the chat (imperative API)

Attach a ref to open/close the chat or manage the session from anywhere in your app:

import { useRef } from "react";
import { WebChat, type WebChatHandle } from "@experiaapp/webchat-react-native";

const chat = useRef<WebChatHandle>(null);

<WebChat ref={chat} config={CONFIG} />;

// elsewhere:
chat.current?.open();
chat.current?.close();
chat.current?.sendMessage("Hello");
chat.current?.getUnreadCount();   // number
chat.current?.clearHistory();     // drop messages, keep the session
chat.current?.resetSession();     // start a new session + clear history

clearHistory() / resetSession() erase the locally stored conversation — call one on user logout.


Customizing the launcher

The default is a round floating button. You can change it four ways:

1. Your own launcher (any shape):

<WebChat
  config={CONFIG}
  renderLauncher={({ open }) => (
    <Pressable onPress={open} style={{ /* a pill, bar, avatar, anything */ }}>
      <Text>Chat with us</Text>
    </Pressable>
  )}
/>

2. Trigger from your own UI — hide the built-in button and open via the ref:

<WebChat ref={chat} config={{ ...CONFIG, showButtonChat: false }} />
// <YourButton onPress={() => chat.current?.open()} />

3. Reshape the default via channel theme tokens (size, color, corner radius).

4. Use a branded image via the openLauncherImage channel config.


Media & video

  • Attachments: images (PNG/JPEG), PDF documents, and voice notes. Picking is gated by the uploadMedia / upload* flags; selected files are validated against the channel's allow-list before sending.
  • Video calls: set makeVideoCall: true to show the call button (a call can also start automatically when your channel triggers it). Video requires the react-native-webrtc + react-native-incall-manager peers, the @config-plugins/react-native-webrtc Expo plugin (managed apps), and a development build.

Notifications: the SDK does not integrate push. Use the onMessageReceived callback to fire your own local notification.


TypeScript

The package ships full type declarations. Import types alongside values:

import { WebChat, type WebChatHandle } from "@experiaapp/webchat-react-native";

Lower-level building blocks (the theme helpers, media utilities, individual UI pieces, and the video-call primitives) are also exported if you need to compose a custom surface.


Troubleshooting

  • Native feature does nothing / picker won't open in Expo Go — Expo Go can't load the native modules; use a development build (eas build / expo prebuild).
  • Icons render as plain glyphs — install react-native-svg.
  • Video-call button missing — set makeVideoCall: true, install the WebRTC peers + plugin, and ensure your channel enables it.
  • The same conversation keeps resuming — that's storage: "localStorage" (the default). Use "sessionStorage" to start fresh each launch, or call resetSession().

License

MIT © Experia App — see LICENSE.