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

@tubinex/expo-game-services

v0.0.4

Published

Expo Game Center and Google Play Games Services integration.

Readme

@tubinex/expo-game-services

Expo native module for Apple Game Center and Google Play Games Services v2. It provides platform authentication, server identity proofs, achievements, leaderboards, and native provider UI.

NPM Version License

This package supports iOS and Android.

Install

npm install @tubinex/expo-game-services

Add the config plugin to app.json or app.config.js:

{
    "expo": {
        "plugins": [
            [
                "@tubinex/expo-game-services",
                {
                    "ios": {
                        "enabled": true
                    },
                    "android": {
                        "enabled": true,
                        "playGamesAppId": "123456789012"
                    }
                }
            ]
        ]
    }
}

playGamesAppId is the numeric Play Games Services application ID, not an OAuth client ID. The plugin adds no secrets.

Build a new development, EAS, or store binary after installing or upgrading this package. Game Center and Play Games cannot run in Expo Go. The package is import-safe when the native module is absent, and promise APIs reject with a typed native-module-unavailable error.

Usage

import { gameServices, GameServicesError } from '@tubinex/expo-game-services';

async function connect() {
    try {
        const state = await gameServices.authentication.signIn();
        if (state.status !== 'authenticated') return;

        await gameServices.achievements.unlock('first_win');
        await gameServices.leaderboards.submitScore('high_scores', 4200);
    } catch (error) {
        if (error instanceof GameServicesError && error.code === 'native-module-unavailable') return;
        throw error;
    }
}

Use the native provider dashboards when a custom screen is unnecessary:

await gameServices.achievements.showUI();
await gameServices.leaderboards.showUI({ leaderboardId: 'high_scores' });

Backend identity exchange

Successful platform authentication is not an application session. Request proof only immediately before sending it to your authenticated backend over TLS:

const proof = await gameServices.authentication.requestServerIdentityProof({
    serverClientId: process.env.EXPO_PUBLIC_GOOGLE_SERVER_CLIENT_ID,
});
  • On iOS, the result is a Game Center identity-verification signature bundle. Before fetching its public key, require HTTPS, allow only Apple's documented public-key host and path, disable redirects, and reject private, loopback, link-local, and other non-public address resolution. Then verify the signature, timestamp freshness, app identity, and replay protection on your server.
  • On Android, the result is a one-time Play Games server auth code. Exchange it only on your server using server-held OAuth credentials.

Do not send either proof to an existing Apple or Google OAuth ID-token endpoint, persist it in analytics, or log it.

Console prerequisites

Apple

  1. Enable Game Center for the app identifier and App Store Connect app.
  2. Create achievements and leaderboards in App Store Connect.
  3. Regenerate provisioning profiles if the new entitlement requires it.

Google

  1. Create and link a Play Games Services project to the Android package.
  2. Register the SHA-1 certificates used by development, EAS, upload, and Play App Signing builds.
  3. Create achievements and leaderboards, add testers, and publish the Play Games configuration to the testing track.

Platform differences

  • Game Center supports percentage-based achievement progress. Play Games needs console-defined incremental achievements for step progress, use increment for those and unlock for binary achievements.
  • Platform leaderboard time scopes are provider-defined. They do not automatically model application-specific daily boards.
  • Platform player IDs are not a cross-platform account identifier. Link them to application accounts only through explicit, server-verified flows.
  • Platform sign-out is controlled by the operating system and provider, this package does not offer a universal sign-out method.

API

  • gameServices.authentication.getState()
  • gameServices.authentication.signIn()
  • gameServices.authentication.addStateListener(listener)
  • gameServices.authentication.requestServerIdentityProof(options)
  • gameServices.capabilities.get()
  • gameServices.achievements.load()
  • gameServices.achievements.reportProgress(id, percentComplete)
  • gameServices.achievements.unlock(id)
  • gameServices.achievements.increment(id, steps)
  • gameServices.achievements.showUI()
  • gameServices.leaderboards.loadMetadata(ids?)
  • gameServices.leaderboards.loadScores(request)
  • gameServices.leaderboards.loadCurrentPlayerScore(request)
  • gameServices.leaderboards.submitScore(id, score, context?)
  • gameServices.leaderboards.showUI(options?)

Check gameServices.capabilities.get() before using optional provider behavior.