Respectlytics Respect lytics
Menu
React Native Level complete Privacy-first

How to track level-complete events in React Native games without personal data

Level complete is the central progression event in mobile games and the place game analytics SDKs default to building per-player skill graphs (level number, time-to-complete, attempts, score, items used). Respectlytics helps developers avoid collecting personal data in the first place: in React Native, level complete is one named event per level, with the level encoded into the event name. Below: how to keep your level taxonomy bounded, why time-to-complete becomes a server-side derivation, and what stays in your game backend.

Fire on level-completion success — after the win-state animation begins, before any post-level dialog. Encode the level into the event name (level_complete_1, level_complete_2). Don't pass score, attempts, or duration.

Install the React Native SDK

bash Respectlytics
npm install @respectlytics/react-native
# or
yarn add @respectlytics/react-native

JavaScript-only — no native modules, no auto-linking, no New Architecture migration concerns. Bundle size: ~14KB minified+gzipped. Works in any Expo project (managed or bare) without expo prebuild.

Initialize Respectlytics in React Native

js Respectlytics
// App.tsx (or App.js)
import { useEffect } from 'react';
import Respectlytics from '@respectlytics/react-native';

export default function App() {
  useEffect(() => {
    Respectlytics.configure({ appKey: '<YOUR_APP_KEY>' });
  }, []);
  return <YourApp />;
}

Initialize once in your top-level component. No native config; no Info.plist or AndroidManifest changes. The SDK is Hermes- and JSC-compatible.

Track the event in React Native

js Respectlytics
import Respectlytics from '@respectlytics/react-native';

export function reportLevelComplete(levelNumber) {
  if (levelNumber <= 50) {
    Respectlytics.track(`level_complete_${levelNumber}`);
  } else {
    const bucket = Math.floor((levelNumber - 1) / 50) * 50 + 1;
    Respectlytics.track(`level_complete_${bucket}_${bucket + 49}`);
  }
}

If your game has chapter-based progression instead of linear levels, encode chapter+level into the name: level_complete_chapter_3_level_2.

Privacy & implementation notes

Per-player progression — score curves, leaderboard positions, skill ratings, items inventory — lives in your game backend. That's where it has authority and where the gameplay logic reads from. Mirroring it into product analytics duplicates a system of record without adding signal you can't get from the game backend's own reporting.

Most game-product decisions are about rate ("is this level a difficulty wall for new players?") rather than skill ("how quickly does this player progress?"). The rate question is session-grouped. The skill question is per-player and lives in your game backend.

The React Native SDK is JavaScript-only — no Objective-C/Swift bridging on iOS, no Java/Kotlin bridging on Android. Side effects: no react-native link, no auto-linking, no New Architecture migration concerns, no platform-channel exception surfaces. Trade-off: no access to platform-only metadata (which we don't want to collect anyway).

Works in Expo managed workflow without expo prebuild. No config plugin is required. EAS Build users: nothing to configure. This is the smoothest integration path on RN — most analytics SDKs require ejecting from managed.

How this compares to other analytics SDKs

Level complete eventFirebase AnalyticsMixpanelGameAnalyticsRespectlytics
Level number as parameterYesYesYesUse distinct event_name
Score storedRecommendedRecommendedYesOut of scope (game backend)
Attempts to completeRecommendedRecommendedYesOut of scope (game backend)
Time-to-completeRecommendedRecommendedYesServer-side derivation
Per-player progression curveYesYesYesOut of scope (game backend)

Frequently asked questions

Won't we run out of distinct event names if we have 1000 levels?

For high-level-count games, bucket: level_complete_1_50, level_complete_51_100, etc. The Respectlytics aggregation handles either shape. Per-level granular progression is a game-backend signal — your leaderboards and skill-rating system already have it.

How do we measure difficulty without per-player attempts?

Per-session. The rate of sessions where level_complete_N follows level_complete_N-1 is your level-N completion rate. Country-bucketed and device-platform-bucketed shows where the difficulty cliff sits.

What about retries?

Distinct event name: level_failed_N. The rate of level_failed_N to level_complete_N over a session is your level-N retry signal.

Should we instrument every level individually?

If you have under 50 levels, yes — distinct event names per level. Past that, bucket. The principle is to keep your event-name taxonomy navigable; 1000 distinct level event names is functionally a parameter.

Related guides

Track what matters. Collect nothing you don't.

Five-field event schema, RAM-only event queue, no IDFA, no AAID, no persistent user IDs. Helps developers avoid collecting personal data in the first place.