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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@social.dev/rn-sdk

v0.0.1-alpha.66

Published

React Native SDK for Social.dev with reusable UI components

Readme

@social.dev/rn-sdk

React Native SDK and UI Kit for Social.dev - A comprehensive toolkit for building social media applications with React Native and Expo.

Overview

The @social.dev/rn-sdk package provides:

  • 🎨 Pre-built UI Components - Complete set of customizable social media components
  • 🔄 Component Override System - Replace any component with your own implementation
  • 🎯 Navigation Setup - Pre-configured navigation with React Navigation
  • 🔐 Authentication - Built-in auth flows with OIDC support
  • 💬 Chat System - Real-time messaging components
  • 📱 Mobile-First - Optimized for React Native with Expo support
  • 🎭 Theming - Comprehensive theming system with dark mode support

Installation

# Using pnpm (recommended)
pnpm add @social.dev/rn-sdk @social.dev/js-sdk

# Using npm
npm install @social.dev/rn-sdk @social.dev/js-sdk

# Using yarn
yarn add @social.dev/rn-sdk @social.dev/js-sdk

Peer Dependencies

Make sure you have the following peer dependencies installed:

# Required Expo modules
npx expo install expo-audio expo-auth-session expo-crypto expo-linking expo-secure-store expo-web-browser

# Required React Navigation
pnpm add @react-navigation/native @react-navigation/native-stack @react-navigation/bottom-tabs @react-navigation/drawer

# Required for React Navigation
npx expo install react-native-screens react-native-safe-area-context

# Required for gestures and animations
npx expo install react-native-gesture-handler react-native-reanimated

# Required for bottom sheets
pnpm add @gorhom/bottom-sheet

Quick Start

Basic Setup

import React from 'react';
import { SocialDevProvider, SocialDevApp } from '@social.dev/rn-sdk';
import { Platform } from 'react-native';

export default function App() {
  return (
    <SocialDevProvider
      apiBaseUrl={
        Platform.OS === 'web' ? '/api' : 'https://your-server.social.dev/api/'
      }
    >
      <SocialDevApp />
    </SocialDevProvider>
  );
}

Advanced Setup with Component Overrides

import React from 'react';
import {
  SocialDevProvider,
  SocialDevApp,
  ComponentLibrary,
  DefaultComponents,
} from '@social.dev/rn-sdk';
import { defaultRouterConfig } from '@social.dev/rn-sdk/navigation/AppNavigator';
import { Platform, Text, View } from 'react-native';

// Custom components
import CustomAvatar from './components/CustomAvatar';
import CustomHomeScreen from './screens/CustomHomeScreen';

export default function App() {
  // Custom navigation configuration
  const navConfig = {
    screens: {
      ...defaultRouterConfig?.screens,
      Home: { path: 'home', alias: ['homepage'] },
      Profile: { path: 'profile/:id' },
    },
  };

  // Override specific components
  const components: Partial<ComponentLibrary> = {
    // Override a single component
    Avatar: CustomAvatar,

    // Override nested components
    Post: {
      Post: CustomPost,
      PostToolbar: CustomPostToolbar,
    },

    // Override screens
    Screens: {
      ...DefaultComponents.Screens,
      HomeScreen: CustomHomeScreen,
      NotificationScreen: () => (
        <View>
          <Text>Custom Notification Screen</Text>
        </View>
      ),
    },
  };

  return (
    <SocialDevProvider
      apiBaseUrl={
        Platform.OS === 'web' ? '/api' : 'https://demo.social.dev/api/'
      }
      components={components}
      sdkConfig={{
        feed: {
          chatMode: true, // Enable chat mode for feeds
        },
      }}
    >
      <SocialDevApp navigationConfig={navConfig} />
    </SocialDevProvider>
  );
}

Component Override System

The SDK uses a powerful component override system that allows you to replace any component with your own implementation while maintaining the rest of the SDK functionality.

Available Component Categories

interface ComponentLibrary {
  // Core UI Components
  Avatar: React.ComponentType;
  Button: React.ComponentType;
  Core: {
    Button: React.ComponentType;
    Icon: React.ComponentType;
    Pressable: React.ComponentType;
    TextInput: React.ComponentType;
  };

  // Authentication Components
  Auth: {
    AuthForm: React.ComponentType;
    OidcProvidersList: React.ComponentType;
  };

  // Chat Components
  Chat: {
    ChatConversationList: React.ComponentType;
    ChatConversationPanel: React.ComponentType;
    ChatCreate: React.ComponentType;
    ChatMessage: React.ComponentType;
  };

  // Community Components
  Community: {
    CommunityFeed: React.ComponentType;
    CommunityJoinButton: React.ComponentType;
    CommunityMembersList: React.ComponentType;
  };

  // Post Creation Components
  CreatePost: {
    CreatePost: React.ComponentType;
    CreatePostInline: React.ComponentType;
    CreatePostButton: React.ComponentType;
    ReplyToPostButton: React.ComponentType;
    CreatePostFab: React.ComponentType;
  };

  // Feed Components
  Feed: {
    Feed: React.ComponentType;
  };

  // Post Components
  Post: {
    Post: React.ComponentType;
    PostToolbar: React.ComponentType;
  };

  // User Components
  User: {
    UserListItem: React.ComponentType;
  };

  // Screen Components
  Screens: {
    AuthScreen: React.ComponentType;
    ChatScreen: React.ComponentType;
    ChatCreateScreen: React.ComponentType;
    CommunityCreateScreen: React.ComponentType;
    CommunityListScreen: React.ComponentType;
    CommunityProfileScreen: React.ComponentType;
    HomeScreen: React.ComponentType;
    NotificationScreen: React.ComponentType;
    PostViewScreen: React.ComponentType;
    ProfileScreen: React.ComponentType;
  };

  // Audio Components
  AudioPlayer: {
    AudioPlayer: React.ComponentType;
  };

  AudioVisualizer: {
    AudioVisualizer: React.ComponentType;
  };

  // Voice Recording
  VoiceRecorder: {
    VoiceRecorder: React.ComponentType;
    VoiceRecorderModal: React.ComponentType;
  };

  // Layout
  Layout: React.ComponentType;
}

Override Examples

Example 1: Custom Avatar Component

// components/CustomAvatar.tsx
import React from 'react';
import { View, Image, Text, StyleSheet } from 'react-native';

export default function CustomAvatar({ user, size = 40, onPress }) {
  return (
    <View style={[styles.container, { width: size, height: size }]}>
      {user?.avatar ? (
        <Image source={{ uri: user.avatar }} style={styles.image} />
      ) : (
        <Text style={styles.initial}>
          {user?.name?.[0]?.toUpperCase() || '?'}
        </Text>
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    borderRadius: 999,
    backgroundColor: '#007AFF',
    alignItems: 'center',
    justifyContent: 'center',
  },
  image: {
    width: '100%',
    height: '100%',
    borderRadius: 999,
  },
  initial: {
    color: 'white',
    fontWeight: 'bold',
  },
});

Example 2: Custom Post Component

// components/CustomPost.tsx
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { useComponentLibrary } from '@social.dev/rn-sdk';

export default function CustomPost({ post }) {
  const components = useComponentLibrary();
  const Avatar = components.Avatar;
  const PostToolbar = components.Post.PostToolbar;

  return (
    <View style={styles.container}>
      <View style={styles.header}>
        <Avatar user={post.author} size={32} />
        <Text style={styles.authorName}>{post.author.name}</Text>
      </View>
      <Text style={styles.content}>{post.content}</Text>
      <PostToolbar post={post} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 16,
    backgroundColor: 'white',
    marginBottom: 8,
  },
  header: {
    flexDirection: 'row',
    alignItems: 'center',
    marginBottom: 12,
  },
  authorName: {
    marginLeft: 8,
    fontWeight: '600',
  },
  content: {
    fontSize: 14,
    marginBottom: 12,
  },
});

Example 3: Partial Screen Override

// App.tsx
const components: Partial<ComponentLibrary> = {
  Screens: {
    // Keep all default screens
    ...DefaultComponents.Screens,
    // Override only the HomeScreen
    HomeScreen: () => {
      const { user } = useConfig();
      return (
        <View style={{ flex: 1, padding: 20 }}>
          <Text>Welcome {user?.name || 'Guest'}!</Text>
          <Feed />
        </View>
      );
    },
  },
};

Hooks

useApi

Access the API client for making authenticated requests:

import { useApi } from '@social.dev/rn-sdk';

function MyComponent() {
  const api = useApi();

  const { data, error, isLoading } = api.useQuery(
    'get',
    '/posts',
    { params: { limit: 10 } }
  );

  const createPost = api.useMutation('post', '/posts');

  const handleSubmit = async (content: string) => {
    await createPost.mutateAsync({
      body: { content }
    });
  };

  return (
    // Your component JSX
  );
}

useConfig

Access server configuration and user authentication state:

import { useConfig } from '@social.dev/rn-sdk';

function MyComponent() {
  const { server, user, isLoggedIn, sdk, refetch } = useConfig();

  if (!isLoggedIn) {
    return <LoginPrompt />;
  }

  return (
    <View>
      <Text>Welcome {user.name}!</Text>
      <Text>Server: {server.title}</Text>
      <Button onPress={refetch} title="Refresh Config" />
    </View>
  );
}

useComponentLibrary

Access the component library to use SDK components in your custom components:

import { useComponentLibrary } from '@social.dev/rn-sdk';

function CustomFeed() {
  const components = useComponentLibrary();
  const { Feed, Post, Avatar } = components;

  return (
    <View>
      <Feed
        renderItem={({ item }) => (
          <View>
            <Avatar user={item.author} />
            <Post post={item} />
          </View>
        )}
      />
    </View>
  );
}

useOpenChat

Navigate to or create a chat conversation:

import { useOpenChat } from '@social.dev/rn-sdk';

function UserProfile({ userId }) {
  const { openChat, mutation } = useOpenChat({ userId });

  return (
    <Button onPress={openChat} title="Message" loading={mutation.isLoading} />
  );
}

useTheme

Access the theme system:

import { useTheme } from '@social.dev/rn-sdk';

function ThemedComponent() {
  const { colors, fonts, spacing } = useTheme();

  return (
    <View
      style={{
        backgroundColor: colors.background,
        padding: spacing.md,
      }}
    >
      <Text
        style={{
          color: colors.text,
          fontSize: fonts.sizes.body,
        }}
      >
        Themed content
      </Text>
    </View>
  );
}

SDK Configuration

Configure the SDK behavior through the sdkConfig prop:

<SocialDevProvider
  sdkConfig={{
    feed: {
      chatMode: true, // Reverse feed direction for chat-like experience
    },
  }}
>
  {/* Your app */}
</SocialDevProvider>

Push Notifications

Setup push notifications with Expo:

import * as Notifications from 'expo-notifications';
import * as Device from 'expo-device';

async function registerForPushNotificationsAsync() {
  if (!Device.isDevice) return;

  const { status } = await Notifications.requestPermissionsAsync();
  if (status !== 'granted') return;

  const token = await Notifications.getExpoPushTokenAsync();
  return token.data;
}

export default function App() {
  const [pushToken, setPushToken] = useState<string>();

  useEffect(() => {
    registerForPushNotificationsAsync().then((token) => setPushToken(token));
  }, []);

  return (
    <SocialDevProvider
      pushNotificationToken={pushToken}
      // ... other props
    >
      <SocialDevApp />
    </SocialDevProvider>
  );
}

Navigation Configuration

Customize the navigation structure:

import { defaultRouterConfig } from '@social.dev/rn-sdk/navigation/AppNavigator';

const navConfig = {
  screens: {
    ...defaultRouterConfig?.screens,
    // Custom routes
    Home: { path: 'home', alias: ['homepage'] },
    Profile: { path: 'profile/:id' },
    Settings: { path: 'settings' },
  },
  // Deep linking configuration
  config: {
    initialRouteName: 'Home',
  },
};

<SocialDevApp navigationConfig={navConfig} />;

Testing

The SDK includes comprehensive test utilities and mocks:

# Run tests
pnpm test

# Run tests in watch mode
pnpm test:watch

# Generate coverage report
pnpm test --coverage

Writing Tests for Components Using the SDK

import { render } from '@testing-library/react-native';
import { SocialDevProvider } from '@social.dev/rn-sdk';

function renderWithProviders(component, options = {}) {
  return render(
    <SocialDevProvider apiBaseUrl="/api" {...options}>
      {component}
    </SocialDevProvider>
  );
}

test('my component renders', () => {
  const { getByText } = renderWithProviders(<MyComponent />);
  expect(getByText('Hello')).toBeTruthy();
});

Development

# Install dependencies
pnpm install

# Build the package
pnpm build

# Watch for changes during development
pnpm dev

# Run tests
pnpm test

# Type checking
pnpm typecheck

# Linting
pnpm lint

TypeScript Support

The SDK is written in TypeScript and provides full type definitions. Import types as needed:

import type {
  ComponentLibrary,
  SdkConfig,
  User,
  Post,
  ApiComponents,
  ApiPaths,
} from '@social.dev/rn-sdk';

Examples

Check out the apps/mobile directory for a complete implementation example using the SDK.

Contributing

Contributions are welcome! Please read our contributing guidelines before submitting PRs.

License

MIT

Support