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

@parlr/react-native

v0.6.0

Published

Official Parlr live chat SDK for React Native

Downloads

698

Readme


Features

| Feature | Description | |---|---| | One-line drop-in | <ParlrLauncher workspaceId="..."> — floating bubble + chat modal, zero navigation setup | | Real-time messaging | WebSocket with automatic reconnection and exponential backoff | | Optimistic UI | Messages appear instantly, sync in the background (dedup by clientId + server id) | | Typing indicators & read receipts | Agent typing events; delivery status sending → sent → read | | Pre-built UI | <ParlrLauncher>, <ParlrChat>, <ParlrConversationList> — or build your own with hooks | | Pre-chat forms & CSAT | Collect visitor info before the first message; satisfaction rating after resolution | | File attachments & rich messages | Images/documents; cards, carousels, quick replies rendered natively | | Push notifications | FCM (Android) / APNs (iOS) via useParlr().registerPushToken(...) | | Offline queue | Failed messages are queued and replayed on reconnection | | Speech-to-text | Voice dictation with live volume and accumulated transcription | | Theming & dark mode | Branding loaded from your dashboard; automatic system dark mode + full overrides | | User identification & HMAC | email / name / externalId; server-side HMAC to prevent impersonation | | TypeScript-first | Complete type definitions ship with the package (your editor autocompletes them) |

Works with Expo (managed & bare) and bare React Native. The SDK handles session management, WebSocket connections, message delivery, branding and reconnection for you.


Installation

npm install @parlr/react-native
# or: yarn add @parlr/react-native

Required peer dependency

npm install react-native-reanimated

Mobile reality: “one line” refers to one line of code. Installing a native SDK still requires npm install + a native rebuild (CocoaPods / EAS / dev client).

Optional dependencies

npm install expo-secure-store        # encrypted session persistence (recommended)
npm install react-native-svg         # vector icons (emoji fallback without it)
npm install expo-image-picker expo-document-picker   # file & image attachments
npm install expo-speech-recognition  # voice dictation

Without expo-secure-store, sessions are kept in memory and don't persist across app restarts (users get a new session each launch).

Compatibility

| Package | Min version | Required | |---|---|---| | react | 18.0.0 | Yes | | react-native | 0.72.0 | Yes | | react-native-reanimated | 3.0.0 | Yes | | expo-secure-store / react-native-svg / expo-image-picker / expo-document-picker / expo-speech-recognition | see npm | No |


Quick Start

Recommended — one line with ParlrLauncher

A drop-in floating chat bubble + chat modal. No navigation setup required. Only workspaceId is needed; colors, greeting and placeholder come from your dashboard.

import { ParlrLauncher } from '@parlr/react-native';

export default function App() {
  return (
    <>
      <Navigation />
      <ParlrLauncher workspaceId="your-workspace-id" />
    </>
  );
}

Use ParlrLauncher OR the advanced ParlrProvider setup below — not both nested.

Advanced — controlled integration

For your own navigation, support button and screen, wrap your app with the provider and render <ParlrChat> where you want; drive it with the hooks.

import { ParlrProvider, ParlrChat, useParlr } from '@parlr/react-native';

export default function App() {
  return (
    <ParlrProvider workspaceId="your-workspace-id">
      <Navigation />
    </ParlrProvider>
  );
}

// In your support screen:
function SupportScreen({ navigation }) {
  return (
    <ParlrChat
      user={{ email: '[email protected]', name: 'Alice' }}
      onBack={() => navigation.goBack()}
    />
  );
}

// Show an unread badge anywhere inside the provider:
function SupportButton() {
  const { unreadCount } = useParlr();
  return <Badge count={unreadCount} />;
}

Components

<ParlrLauncher>

All-in-one drop-in: instantiates its own ParlrProvider, renders a floating bubble and opens the chat in a native modal. workspaceId is the only required prop.

| Prop | Type | Default | Description | |---|---|---|---| | workspaceId | string | — | Required. | | user | ParlrUser | — | Identify the user on mount. | | position | 'left' \| 'right' | 'right' | Bubble corner. | | accentColor | string | backend theme | Bubble + chat accent color. | | hidden | boolean | false | Hide the bubble programmatically. | | offset | number | 0 | Extra inset (px) from screen edges (safe area). | | headerTitle, placeholder, locale, theme, identityToken, onError | — | — | Same as ParlrProvider / ParlrChat. |

<ParlrProvider>

Root provider for the advanced integration: bootstraps the session, connects the WebSocket, fetches branding, and exposes everything through the hooks.

| Prop | Type | Default | Description | |---|---|---|---| | workspaceId | string | — | Required. | | apiBaseUrl | string | https://api.parlr.chat/api/v1/widget | REST base URL (self-hosted override). | | wsUrl | string | wss://ws.parlr.chat/widget-ws | WebSocket endpoint. Pass "" to disable real-time. | | locale | string | "fr" | BCP-47 locale. | | theme | Partial<ParlrTheme> | backend | Theme overrides (see Theming). | | identityToken | string | — | HMAC identity token (see Identity Verification). | | debug | boolean | false | Verbose logging. | | onError | (error: ParlrError) => void | — | Global error callback (e.g. Sentry). |

<ParlrChat>

The full chat screen. No required props — user and onBack are recommended.

Key props: user, conversationId, onBack, headerTitle, placeholder, accentColor, showHeader (default true), showPreChatForm (default false), preChatFields (default ['name','email']), showSatisfactionSurvey (default true), safeAreaBottom, allowSpeechToText (default true), onConversationClosed.

<ParlrConversationList>

A list of the contact's conversations with unread badges and last-message previews. Pair it with <ParlrChat conversationId={...}> for an inbox-style UI. Lower-level building blocks (ChatBubble, TypingIndicator, EmptyState, PreChatForm, SatisfactionSurvey, AttachmentPicker, RichMessage, SpeechButton) are exported for custom UIs.


Hooks

useParlr()

Access SDK state and actions from any component inside <ParlrProvider> (or <ParlrLauncher>).

const {
  isReady,              // true once the SDK has bootstrapped
  isConnected,          // true when the WebSocket is connected
  session,              // { token, contactId, workspaceId }
  conversations,        // all conversations for this contact
  unreadCount,          // total unread across conversations
  identify,             // (user: ParlrUser) => Promise<void>
  refreshConversations, // force-refresh the conversation list
  theme,                // resolved theme (light/dark + overrides)
  widgetConfig,         // backend branding/greeting/team (null until loaded)
  trackEvent,           // (type, url, props?) => track a behavioral event
  registerPushToken,    // (token, 'ios' | 'android') => register for push
  unregisterPushToken,  // (token) => unregister (e.g. on logout)
} = useParlr();

await identify({ email: '[email protected]', name: 'Alice Martin', company: 'Acme' });

useChat(conversationId?)

Manage a single conversation with real-time, optimistic updates.

const {
  messages,            // ordered oldest-first
  isLoading, hasError,
  conversation,
  agentTyping,         // auto-clears after 5s
  sendMessage,         // optimistic: appears instantly, then 'sent' on confirm
  retryMessage,        // (clientId) => retry a failed message
  notifyTyping,        // (isTyping) => debounced typing indicator
  loadMore, hasMore,   // pagination of older messages
  closeConversation, reopenConversation,
} = useChat(conversationId);

await sendMessage('Hello, I need help with my order');

Optimistic send: the message is inserted locally (sending), sent over REST and WebSocket, then marked sent (or failed, retryable 3× with backoff). Duplicates are removed by both clientId and server id. Omitting conversationId creates a new conversation on the first send.

useSpeechRecognition(options?)

Low-level voice-dictation hook (used internally by <ParlrChat>, exported for custom inputs). Returns { isRecording, isAvailable, transcript, volumeLevel, error, startRecording, stopRecording, toggleRecording, clearTranscript }. Options: locale, onResult, onStart, onStop, onError. The transcript accumulates across final segments; gracefully no-ops if expo-speech-recognition isn't installed.


User Identification

Identify users through the ParlrUser shape — all fields optional except you'll usually pass at least an email:

interface ParlrUser {
  email?: string;
  name?: string;          // auto-split into firstName/lastName if those aren't set
  firstName?: string;
  lastName?: string;
  externalId?: string;    // your internal user id
  phone?: string;         // E.164
  company?: string;
  customAttributes?: Record<string, unknown>;
}
// Simple — let the SDK split the name:
await identify({ email: '[email protected]', name: 'Alice Martin' });

// Explicit + custom attributes:
await identify({
  email: '[email protected]',
  firstName: 'Alice',
  lastName: 'Martin',
  company: 'Acme Inc',
  customAttributes: { plan: 'pro', mrr: 299 },
});

You can also pass user directly to <ParlrLauncher> / <ParlrChat> to identify on mount.


Theming

Branding (colors, greeting, placeholder) is loaded from your dashboard automatically — your theme overrides always win. Dark/light mode is detected from the system.

// Brand color only (most common):
<ParlrProvider workspaceId="..." theme={{ colors: { primary: '#E91E63' } }}>

// Programmatic access:
import { useParlr, defaultLightTheme, defaultDarkTheme, mergeTheme } from '@parlr/react-native';
const { theme } = useParlr();
const custom = mergeTheme(defaultDarkTheme, { colors: { primary: '#FF6B00' } });

ParlrTheme covers colors (primary, background, surface, text, agent/contact bubbles…), borderRadius, spacing and typography. The full type ships with the package — your editor will autocomplete every field.


Push Notifications

Register the device token via the useParlr() hook (it uses the SDK's authenticated client internally — you never handle it):

import { useParlr } from '@parlr/react-native';
import { useEffect } from 'react';
import { Platform } from 'react-native';
import messaging from '@react-native-firebase/messaging';

function PushRegistration() {
  const { registerPushToken, unregisterPushToken } = useParlr();

  useEffect(() => {
    messaging()
      .getToken()
      .then((token) => registerPushToken(token, Platform.OS as 'ios' | 'android'));
    // On logout: unregisterPushToken(deviceToken);
  }, [registerPushToken]);

  return null;
}

Must be rendered inside ParlrProvider (or ParlrLauncher).


Behavioral Tracking

Track screen views and custom events for automated triggers configured in the dashboard:

const { trackEvent } = useParlr();
await trackEvent('SCREEN_VIEW', 'checkout');

Identity Verification (HMAC)

For production, prevent contact impersonation by signing the user identity server-side.

// Server-side (Node.js) — signs with your workspace secret:
const hmac = require('crypto').createHmac('sha256', WORKSPACE_SECRET);
hmac.update(user.email);
const identityToken = hmac.digest('hex');
<ParlrProvider workspaceId="..." identityToken={identityTokenFromYourBackend}>

The token is sent as X-Identity-Token on every request and validated server-side.


Error Handling

All SDK errors extend ParlrError: ParlrNetworkError, ParlrAuthError, ParlrValidationError, ParlrConnectionError. Use the provider's onError callback for global monitoring:

<ParlrProvider workspaceId="..." onError={(e) => Sentry.captureException(e)}>

Self-hosted / development

Point the SDK at your own backend via the advanced provider (these aren't exposed on ParlrLauncher, which targets production defaults):

<ParlrProvider
  workspaceId="..."
  apiBaseUrl="https://your-host/api/v1/widget"
  wsUrl="wss://your-host/widget-ws"
  debug={__DEV__}
>

Changelog

0.6.0

  • <ParlrLauncher> — one-line drop-in. A single component that instantiates its own ParlrProvider, renders a floating chat bubble and opens the chat in a native modal. No navigation setup required. The advanced ParlrProvider + ParlrChat + hooks integration is unchanged. Use one or the other, not both nested.
  • Push via useParlr(). registerPushToken(token, platform) and unregisterPushToken(token) are now exposed on the hook (which uses the SDK's authenticated client internally). The previous low-level registerPushToken(api, ...) top-level exports — which leaked the internal API client — have been removed; migrate to the hook.
  • Launcher bubble contrast. The bubble icon color is derived from theme.colors.primaryText instead of a hardcoded white, so it stays visible on light brand colors.

0.5.0

  • Security: WebSocket token via subprotocol — the session token is carried by the bearer WebSocket subprotocol (new WebSocket(url, ['bearer', token])) and read server-side before the upgrade, instead of a ?token= query parameter (which leaks into logs, Referer, and history).
  • Real-time enabled by defaultwsUrl defaults to wss://ws.parlr.chat/widget-ws. Pass wsUrl="" to opt out.

0.4.0

  • Offline queue integrated into the send flow (failed messages queue and replay on reconnect, bounded to 100 messages / 24h TTL).
  • Error boundary in ParlrChat, agent avatar images, redacted WebSocket logs, themed colors (no hardcoded hex), and accessibility labels on status indicators.

Older releases (0.1.x–0.3.x) are listed in CHANGELOG.md.


License

MIT © Parlr