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

@beta-gamer/react-native

v0.1.39

Published

React Native SDK for Beta Gamer GaaS — composable game components

Downloads

532

Readme

@beta-gamer/react-native

Beta Gamer React Native SDK Version License Downloads

React Native SDK for Beta Gamer — embed multiplayer games into your mobile app as native components.

You control the layout; we handle matchmaking, game logic, and real-time sync.

🚀 Quick Start📖 Documentation🎮 Games🔧 API Reference💡 Examples


✨ Features

  • 📱 Native Mobile Components — Fully native game components, no WebViews
  • 🔄 Real-time Sync — Automatic state synchronization across players
  • 🤖 Bot Support — Built-in AI opponents with configurable difficulty
  • 🎨 Customizable Styling — Full control over colors, fonts, and layouts
  • 📐 Responsive Design — Adapts to all screen sizes and orientations
  • 🔐 Secure Sessions — JWT-based authentication with your backend
  • TypeScript Ready — Full type safety and IntelliSense support
  • 📦 Expo Compatible — Works with both Expo and bare React Native

📦 Installation

npm install @beta-gamer/react-native

Optional Dependencies

# Only required for Subway Runner game (uses WebView)
npx expo install react-native-webview          # Expo projects
npm install react-native-webview && cd ios && pod install  # Bare React Native

Requirements


🚀 Quick Start

1. Create a Session (Backend)

Never call the Beta Gamer API directly from your mobile app. Create sessions from your backend:

// Your server — Express, Next.js API route, Cloudflare Worker, etc.
app.post('/api/game/start', async (req, res) => {
  const { userId, userName, game, matchType } = req.body;
  
  const response = await fetch('https://api.beta-gamer.com/v1/sessions', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer bg_live_your_api_key_here',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      game,
      matchType,
      players: [{ id: userId, displayName: userName }],
    }),
  });
  
  const { sessionId, sessionToken } = await response.json();
  res.json({ sessionToken });
});

2. Render the Game (Mobile App)

import React from 'react';
import { View } from 'react-native';
import { BetaGamerProvider, ChessBoard } from '@beta-gamer/react-native';

export default function GameScreen({ sessionToken }: { sessionToken: string }) {
  return (
    <BetaGamerProvider token={sessionToken}>
      <View style={{ flex: 1, padding: 16 }}>
        <ChessBoard style={{ flex: 1 }} />
      </View>
    </BetaGamerProvider>
  );
}

That's it! Your users can now play chess with real-time multiplayer, matchmaking, and bot opponents on mobile.


🎮 Supported Games

| Game | Component | Description | Native | |------|-----------|-------------|--------| | ♟️ Chess | ChessBoard | Full-featured chess with move validation | ✅ | | ⬤ Checkers | CheckersBoard | Classic checkers with king promotion | ✅ | | 🔴 Connect 4 | Connect4Board | Drop pieces to get four in a row | ✅ | | ❌ Tic-tac-toe | TictactoeBoard | Simple 3x3 grid game | ✅ | | 🃏 Chkobe | ChkobeBoard | Strategic card game | ✅ | | 🏃 Subway Runner | SubwayRunnerGame | Endless runner game | 🌐 WebView |

Game-Specific Packages

For advanced customization, install individual game packages:

npm install @beta-gamer/react-native-chess
npm install @beta-gamer/react-native-checkers
npm install @beta-gamer/react-native-connect4
npm install @beta-gamer/react-native-tictactoe
npm install @beta-gamer/react-native-chkobe

📖 Documentation

Architecture Overview

┌─────────────────────────────────────────────────────────────┐
│                 Your React Native App                       │
├─────────────────────────────────────────────────────────────┤
│  BetaGamerProvider (Session Management + Socket.IO)        │
│  ├── useSession() - Session data & player info             │
│  ├── useSocket() - Raw socket for custom events            │
│  ├── useGameState() - Current game state                   │
│  └── useTheme() - Theming tokens                           │
├─────────────────────────────────────────────────────────────┤
│  Native Game Components (ChessBoard, etc.)                 │
│  ├── Game Logic & State Management                         │
│  ├── Move Validation & Turn Management                     │
│  └── Native UI Rendering & Touch Handling                  │
├─────────────────────────────────────────────────────────────┤
│  Beta Gamer Backend                                         │
│  ├── Matchmaking & Room Management                         │
│  ├── Game Engine & Move Processing                         │
│  ├── Bot AI & Difficulty Scaling                           │
│  └── Real-time Event Broadcasting                          │
└─────────────────────────────────────────────────────────────┘

Session Flow

sequenceDiagram
    participant MobileApp
    participant YourBackend
    participant BetaGamer
    participant SDK

    MobileApp->>YourBackend: Request game session
    YourBackend->>BetaGamer: POST /v1/sessions
    BetaGamer-->>YourBackend: sessionId + sessionToken (JWT)
    YourBackend-->>MobileApp: sessionToken
    MobileApp->>SDK: <BetaGamerProvider token={sessionToken}>
    SDK->>BetaGamer: Connect via Socket.IO
    BetaGamer-->>SDK: Real-time game events

BetaGamerProvider

The BetaGamerProvider is the root component that manages session state and Socket.IO connections:

<BetaGamerProvider
  token={sessionToken}           // Required: JWT session token
  serverUrl="https://api.beta-gamer.com"  // Optional: API server URL
  socketPath="/socket.io"        // Optional: Socket.IO path
  connectSocket={true}           // Optional: Auto-connect socket
>
  {/* Your game components */}
</BetaGamerProvider>

Hooks

useSession()

Access decoded session data:

import { useSession } from '@beta-gamer/react-native';
import { View, Text } from 'react-native';

function GameInfo() {
  const session = useSession();
  
  return (
    <View>
      <Text style={{ fontSize: 18, fontWeight: 'bold' }}>
        Game: {session.game}
      </Text>
      <Text>Mode: {session.mode}</Text>
      <Text>Match Type: {session.matchType}</Text>
      <Text>
        Players: {session.players.map(p => p.displayName).join(', ')}
      </Text>
    </View>
  );
}

useSocket()

Access raw Socket.IO instance for custom events:

import { useEffect } from 'react';
import { useSocket } from '@beta-gamer/react-native';
import { View, TouchableOpacity, Text } from 'react-native';

function CustomGameLogic() {
  const socket = useSocket();
  
  useEffect(() => {
    if (!socket) return;
    
    socket.on('custom:event', (data) => {
      console.log('Custom event received:', data);
    });
    
    return () => socket.off('custom:event');
  }, [socket]);
  
  const sendCustomEvent = () => {
    socket?.emit('custom:action', { data: 'example' });
  };
  
  return (
    <TouchableOpacity onPress={sendCustomEvent}>
      <Text>Send Custom Event</Text>
    </TouchableOpacity>
  );
}

useGameState()

Access current game state:

import { useGameState } from '@beta-gamer/react-native';
import { View, Text } from 'react-native';

function GameStatus() {
  const gameState = useGameState();
  
  return (
    <View>
      <Text>Status: {gameState.status}</Text>
      {gameState.status === 'ended' && (
        <Text>Winner: {gameState.winner || 'Draw'}</Text>
      )}
    </View>
  );
}

💡 Examples

Basic Chess Game

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { BetaGamerProvider, ChessBoard } from '@beta-gamer/react-native';

export default function ChessGame({ sessionToken }: { sessionToken: string }) {
  return (
    <View style={styles.container}>
      <BetaGamerProvider token={sessionToken}>
        <Text style={styles.title}>Chess Game</Text>
        <ChessBoard 
          style={styles.board}
          showCoords={true}
          showLastMove={true}
        />
      </BetaGamerProvider>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#1a1a1a',
    padding: 16,
  },
  title: {
    color: 'white',
    fontSize: 24,
    fontWeight: 'bold',
    textAlign: 'center',
    marginBottom: 16,
  },
  board: {
    flex: 1,
  },
});

Bot Game with Difficulty Selection

import React, { useState } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import { BetaGamerProvider, TictactoeBoard } from '@beta-gamer/react-native';

export default function BotGame() {
  const [sessionToken, setSessionToken] = useState<string | null>(null);
  const [difficulty, setDifficulty] = useState<'easy' | 'medium' | 'hard'>('medium');
  
  const startBotGame = async () => {
    const response = await fetch('/api/create-session', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        game: 'tictactoe',
        matchType: 'bot',
        botDifficulty: difficulty,
        players: [{ id: 'user_123', displayName: 'Player' }],
      }),
    });
    
    const { sessionToken } = await response.json();
    setSessionToken(sessionToken);
  };
  
  if (!sessionToken) {
    return (
      <View style={styles.lobbyContainer}>
        <Text style={styles.title}>Tic-tac-toe vs Bot</Text>
        
        <View style={styles.difficultyContainer}>
          {(['easy', 'medium', 'hard'] as const).map(level => (
            <TouchableOpacity
              key={level}
              onPress={() => setDifficulty(level)}
              style={[
                styles.difficultyButton,
                difficulty === level && styles.difficultyButtonActive
              ]}
            >
              <Text style={[
                styles.difficultyText,
                difficulty === level && styles.difficultyTextActive
              ]}>
                {level}
              </Text>
            </TouchableOpacity>
          ))}
        </View>
        
        <TouchableOpacity onPress={startBotGame} style={styles.startButton}>
          <Text style={styles.startButtonText}>Start Game</Text>
        </TouchableOpacity>
      </View>
    );
  }
  
  return (
    <BetaGamerProvider token={sessionToken}>
      <View style={styles.gameContainer}>
        <TictactoeBoard style={styles.gameBoard} />
      </View>
    </BetaGamerProvider>
  );
}

const styles = StyleSheet.create({
  lobbyContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
    backgroundColor: '#f5f5f5',
  },
  gameContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 30,
    textAlign: 'center',
  },
  difficultyContainer: {
    flexDirection: 'row',
    marginBottom: 30,
  },
  difficultyButton: {
    paddingHorizontal: 20,
    paddingVertical: 10,
    marginHorizontal: 5,
    backgroundColor: '#e0e0e0',
    borderRadius: 8,
  },
  difficultyButtonActive: {
    backgroundColor: '#3b82f6',
  },
  difficultyText: {
    fontSize: 16,
    textTransform: 'capitalize',
  },
  difficultyTextActive: {
    color: 'white',
  },
  startButton: {
    backgroundColor: '#10b981',
    paddingHorizontal: 30,
    paddingVertical: 15,
    borderRadius: 8,
  },
  startButtonText: {
    color: 'white',
    fontSize: 18,
    fontWeight: 'bold',
  },
  gameBoard: {
    width: 300,
    height: 300,
  },
});

🔧 API Reference

Components

BetaGamerProvider

Root provider component that manages session and socket state.

Props:

  • token: string - Required. JWT session token from your backend
  • serverUrl?: string - API server URL (default: https://api.beta-gamer.com)
  • socketPath?: string - Socket.IO path (default: /socket.io)
  • connectSocket?: boolean - Auto-connect socket (default: true)
  • children: React.ReactNode - Child components

Game Components

All game components accept these common props:

  • style?: ViewStyle - React Native style object
  • onGameOver?: (result: GameResult) => void - Game over callback

Chess: ChessBoard

  • showCoords?: boolean - Show board coordinates (default: false)
  • showLastMove?: boolean - Highlight last move (default: true)
  • showCaptured?: boolean - Show captured pieces (default: false)

Checkers: CheckersBoard

  • showLastMove?: boolean - Highlight last move (default: true)
  • orientation?: 'red' | 'black' - Board orientation (default: player color)

Connect 4: Connect4Board

  • showLastMove?: boolean - Highlight last move (default: true)

Tic-tac-toe: TictactoeBoard

  • showLastMove?: boolean - Highlight last move (default: true)

Chkobe: ChkobeBoard

  • theme?: ChkobeTheme - Custom theme object

🎨 Styling & Theming

StyleSheet Integration

All components work with React Native's StyleSheet:

import { StyleSheet } from 'react-native';

const styles = StyleSheet.create({
  gameBoard: {
    flex: 1,
    backgroundColor: '#f0f0f0',
    borderRadius: 8,
    margin: 16,
  },
});

<ChessBoard style={styles.gameBoard} />

Responsive Design

Components automatically adapt to screen size:

import { Dimensions } from 'react-native';

const { width, height } = Dimensions.get('window');
const boardSize = Math.min(width, height) * 0.8;

<ChessBoard style={{ width: boardSize, height: boardSize }} />

🔍 Troubleshooting

Common Issues

❌ "useBetaGamer must be used inside "

Make sure all game components are wrapped in BetaGamerProvider:

// ❌ Wrong
<ChessBoard />

// ✅ Correct
<BetaGamerProvider token={sessionToken}>
  <ChessBoard />
</BetaGamerProvider>

❌ Metro bundler errors with Socket.IO

Add to your metro.config.js:

const { getDefaultConfig } = require('expo/metro-config');

const config = getDefaultConfig(__dirname);

config.resolver.assetExts.push('cjs');

module.exports = config;

❌ Android network security issues

Add to android/app/src/main/res/xml/network_security_config.xml:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">api.beta-gamer.com</domain>
    </domain-config>
</network-security-config>

📚 FAQ

Q: Does this work with Expo? A: Yes! The SDK is fully compatible with Expo managed workflow.

Q: Can I customize the game UI? A: Yes! Use the style prop and React Native styling to customize appearance.

Q: How do I handle different screen sizes? A: Components are responsive by default. Use Dimensions API for custom layouts.

Q: Can I use this offline? A: No, games require an internet connection for real-time multiplayer.

Q: How do I test on device? A: Use Expo Go or build a development build. Socket.IO works on real devices.


📄 License

MIT © Beta Gamer


Made with ❤️ by the Beta Gamer team

WebsiteDocumentationDiscordTwitter