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

@zyphr-dev/inbox-react-native

v0.1.4

Published

React Native components for Zyphr notification inbox

Readme

@zyphr-dev/inbox-react-native

Native React Native components for Zyphr notification inbox with real-time updates, preference management, and theme support.

Looking for the web version? See @zyphr-dev/inbox-react for React DOM components.

Installation

npm install @zyphr-dev/inbox-react-native
# or
yarn add @zyphr-dev/inbox-react-native

Peer Dependencies

  • react >= 17.0.0
  • react-native >= 0.64.0

Quick Start

1. Generate a Subscriber Token (Server-Side)

// Express example
app.get('/api/inbox-token', async (req, res) => {
  const response = await fetch('https://api.zyphr.dev/v1/subscriber-inbox/token', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.ZYPHR_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ external_id: req.user.id }),
  });
  const { data } = await response.json();
  res.json({ token: data.token });
});

2. Add the Provider and Components

import {
  ZyphrProvider,
  InboxBell,
  InboxPopover,
} from '@zyphr-dev/inbox-react-native';

function App() {
  const [token, setToken] = useState('');

  useEffect(() => {
    fetch('/api/inbox-token')
      .then(r => r.json())
      .then(d => setToken(d.token));
  }, []);

  if (!token) return null;

  return (
    <ZyphrProvider subscriberToken={token}>
      <YourApp />
    </ZyphrProvider>
  );
}

function Header() {
  return (
    <View style={{ flexDirection: 'row', alignItems: 'center' }}>
      <Text>My App</Text>
      <InboxPopover />
    </View>
  );
}

Provider Configuration

<ZyphrProvider
  subscriberToken={token}              // Required
  apiUrl="https://api.zyphr.dev"       // Default
  wsUrl="wss://ws.api.zyphr.dev"       // Default
  realtime={true}                      // WebSocket updates (default: true)
  theme="system"                       // 'light' | 'dark' | 'system' (default: 'system')
  locale="en"                          // Date formatting locale (default: 'en')
  demo={false}                         // Demo mode with mock data (default: false)
>
  {children}
</ZyphrProvider>

| Prop | Type | Default | Description | |------|------|---------|-------------| | subscriberToken | string | -- | Required. Subscriber JWT | | apiUrl | string | https://api.zyphr.dev | API endpoint | | wsUrl | string | wss://ws.api.zyphr.dev | WebSocket endpoint | | realtime | boolean | true | Enable real-time updates | | theme | 'light' \| 'dark' \| 'system' | 'system' | Color scheme (uses Appearance API) | | locale | string | 'en' | Locale for date formatting | | demo | boolean | false | Render with mock data |

Theme Detection

Unlike the web version, 'system' theme uses React Native's Appearance API, which works natively on both iOS and Android.

Components

InboxBell

Bell icon button with unread count badge.

import { InboxBell } from '@zyphr-dev/inbox-react-native';

<InboxBell onPress={() => navigation.navigate('Inbox')} />
<InboxBell dot />
<InboxBell size={48} maxCount={50} />

| Prop | Type | Default | Description | |------|------|---------|-------------| | onPress | () => void | -- | Press handler | | style | ViewStyle | -- | Container style | | dot | boolean | false | Show dot instead of count | | maxCount | number | 99 | Max display count | | bellIcon | ReactNode | -- | Custom bell icon | | size | number | 40 | Button size |

InboxPopover

Modal-based notification feed triggered by a bell button.

import { InboxPopover } from '@zyphr-dev/inbox-react-native';

<InboxPopover />
<InboxPopover animationType="fade" />
<InboxPopover
  visible={isOpen}
  onVisibilityChange={setIsOpen}
  trigger={<CustomButton />}
/>

| Prop | Type | Default | Description | |------|------|---------|-------------| | visible | boolean | -- | Controlled visibility | | onVisibilityChange | (visible: boolean) => void | -- | Visibility callback | | style | ViewStyle | -- | Modal content style | | categories | string[] | -- | Filter by categories | | trigger | ReactNode | -- | Custom trigger element | | animationType | 'slide' \| 'fade' \| 'none' | 'slide' | Modal animation | | presentationStyle | string | 'pageSheet' | iOS modal presentation |

InboxFeed

Full notification list with tabs, pull-to-refresh, and infinite scroll via FlatList.

import { InboxFeed } from '@zyphr-dev/inbox-react-native';

<InboxFeed />
<InboxFeed categories={['alerts']} showArchived />

| Prop | Type | Default | Description | |------|------|---------|-------------| | categories | string[] | -- | Filter by categories | | style | ViewStyle | -- | Container style | | showArchived | boolean | false | Include archived | | emptyState | ReactNode | -- | Custom empty component | | renderItem | (notification, actions) => ReactNode | -- | Custom renderer |

NotificationItem

Single notification with priority styling, relative timestamps, and action buttons.

import { NotificationItem } from '@zyphr-dev/inbox-react-native';

<NotificationItem
  notification={notification}
  onPress={() => handlePress(notification)}
/>

PreferencesPanel

ScrollView-based notification preference management with Switch toggles.

import { PreferencesPanel } from '@zyphr-dev/inbox-react-native';

<PreferencesPanel onSave={() => Alert.alert('Saved!')} />

| Prop | Type | Default | Description | |------|------|---------|-------------| | style | ViewStyle | -- | Container style | | showGlobalPreferences | boolean | true | Show global toggles | | channelLabels | Record<string, string> | -- | Custom labels | | onSave | () => void | -- | Save callback | | onError | (error: Error) => void | -- | Error callback | | saveButtonText | string | 'Save Preferences' | Button text | | channels | NotificationChannel[] | -- | Filter channels |

Hooks

All hooks work identically to the web version.

useInbox

import { useInbox } from '@zyphr-dev/inbox-react-native';

function NotificationScreen() {
  const {
    notifications, unreadCount, isLoading, hasMore, error,
    markAsRead, markAllAsRead, archive, delete: remove, loadMore, refresh,
  } = useInbox();

  return (
    <FlatList
      data={notifications}
      renderItem={({ item }) => (
        <Pressable onPress={() => markAsRead(item.id)}>
          <Text style={{ fontWeight: item.read_at ? 'normal' : 'bold' }}>
            {item.title}
          </Text>
        </Pressable>
      )}
      onEndReached={() => hasMore && loadMore()}
      onRefresh={refresh}
      refreshing={isLoading}
    />
  );
}

useUnreadCount

import { useUnreadCount } from '@zyphr-dev/inbox-react-native';

function TabBadge() {
  const { count } = useUnreadCount();
  if (count === 0) return null;
  return <View style={styles.badge}><Text>{count}</Text></View>;
}

useRealTime

import { useRealTime } from '@zyphr-dev/inbox-react-native';

function ConnectionDot() {
  const { connected } = useRealTime();
  return <View style={{ backgroundColor: connected ? 'green' : 'red', width: 8, height: 8, borderRadius: 4 }} />;
}

usePreferences

import { usePreferences } from '@zyphr-dev/inbox-react-native';

function CustomPreferences() {
  const { preferences, updatePreference, savePreferences, hasChanges } = usePreferences();
  // Build your own UI with the preference data
}

Theming

The package includes a complete light/dark theme system using React context.

Using the Theme

import { useZyphrTheme } from '@zyphr-dev/inbox-react-native';

function CustomComponent() {
  const theme = useZyphrTheme();

  return (
    <View style={{ backgroundColor: theme.colors.background }}>
      <Text style={{ color: theme.colors.text, fontSize: theme.fontSize.md }}>
        Styled with Zyphr theme
      </Text>
    </View>
  );
}

Theme Structure

interface ZyphrTheme {
  colors: {
    primary, primaryHover, primarySubtle,
    background, backgroundSecondary, backgroundHover,
    text, textSecondary, textMuted,
    border, borderSubtle,
    danger, dangerHover, success, warning, urgent, unreadDot,
    skeletonBase, skeletonShine,
  };
  spacing: { xs: 4, sm: 8, md: 12, lg: 16, xl: 24 };
  borderRadius: { sm: 6, md: 10, lg: 14 };
  fontSize: { xs: 11, sm: 13, md: 15, lg: 17, xl: 20 };
}

Custom Colors

Override the theme by importing the color palettes:

import { LIGHT_COLORS, DARK_COLORS } from '@zyphr-dev/inbox-react-native';

// Use as reference for your own theme

Differences from Web Version

| Feature | Web (inbox-react) | React Native (inbox-react-native) | |---------|--------------------|------------------------------------| | Styling | CSS + CSS variables | StyleSheet + theme context | | Popover | Positioned div + backdrop | Modal component | | Infinite scroll | IntersectionObserver | FlatList.onEndReached | | Pull to refresh | Not built-in | FlatList.onRefresh | | Links | window.open() | Linking.openURL() | | Theme detection | window.matchMedia() | Appearance API | | Toggles | Custom CSS checkbox | Native Switch | | Focus trap | DOM focus management | N/A (native modal handles it) | | Icons | Inline SVG | Unicode text (customizable via props) |

TypeScript

Full TypeScript support with exported types:

import type {
  Notification,
  ZyphrConfig,
  ZyphrTheme,
  ZyphrThemeColors,
  UseInboxReturn,
} from '@zyphr-dev/inbox-react-native';

Requirements

  • React Native 0.64+ (for Intl.RelativeTimeFormat support)
  • Expo SDK 52+ (if using Expo)
  • iOS 13+ / Android API 24+

License

MIT