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

@codeimplants/analytics

v0.2.0

Published

Shared analytics SDK for all **CodeImplants** mobile apps (React Native).

Readme

@codeimplants/analytics

Shared analytics SDK for all CodeImplants mobile apps (React Native).

Built on top of @react-native-firebase/analytics (GA4), this package provides a safe, centralized, and governed analytics layer — ensuring your app never crashes due to analytics, events are always valid, and data is always clean.


Table of Contents


Features

  • Never crashes the app — every analytics call is wrapped in a try/catch
  • Clean GA4 data — only pre-approved event names can be tracked
  • Environment separation — analytics is disabled in local environments automatically
  • Double-init protection — calling init more than once is a no-op
  • Rate-limiting guard — rapid duplicate events are throttled (min 300ms apart)
  • Payload sanitization — max 25 params, max 100 chars per value, type-safe
  • GA4 DebugView — automatically enabled for non-production environments
  • User identity managementsetUser / clearUser

Prerequisites

This package requires @react-native-firebase/analytics to be installed and configured in your host app.

  • React Native >=0.72
  • @react-native-firebase/app configured
  • @react-native-firebase/analytics installed

Install Firebase in your app

# npm
npm install @react-native-firebase/app @react-native-firebase/analytics

# yarn
yarn add @react-native-firebase/app @react-native-firebase/analytics

For platform-specific Firebase setup (google-services.json / GoogleService-Info.plist), follow the React Native Firebase documentation.


Installation

From npm (public package)

npm install @codeimplants/analytics

From a monorepo (workspace)

If your app is in the same monorepo, add the workspace reference in your app's package.json:

{
  "dependencies": {
    "@codeimplants/analytics": "*"
  }
}

Setup: React Native (Firebase)

Ensure your Firebase project is connected:

  1. Create a Firebase project at https://console.firebase.google.com
  2. Register your Android and iOS apps
  3. Download google-services.json → place under android/app/
  4. Download GoogleService-Info.plist → place under ios/<AppName>/
  5. Follow the native setup steps from rnfirebase.io

Initialization

Call Analytics.init once at the very start of your app — before any screen renders or events fire.

import { Analytics } from "@codeimplants/analytics";

Analytics.init({
  appName: "my-app",
  environment: "prod", // "dev" | "qa" | "preprod" | "prod"
  appVersion: "1.0.0",
  enableAnalytics: true,
});

⚠️ Init is idempotent — calling it more than once is safely ignored. Only the first call takes effect.

⚠️ Analytics is disabled in local environment — events will be silently dropped even if enableAnalytics: true.


API Reference

Analytics.init

Analytics.init(config: AnalyticsConfig): void

Initializes the analytics SDK with your app's configuration and sets up the GA4 adapter.

| Parameter | Type | Required | Description | | ----------------- | ---------------------- | -------- | ------------------------------------------- | | appName | string | ✅ | Name of the app (used as an event property) | | environment | AnalyticsEnvironment | ✅ | One of dev, qa, preprod, prod | | appVersion | string | ✅ | App version string (e.g. "2.1.0") | | enableAnalytics | boolean | ✅ | Master kill-switch for all analytics |


Analytics.track

Analytics.track(
  eventName: AnalyticsEventName,
  payload?: AnalyticsEventPayload
): Promise<void>

Tracks a custom event. Only events from AnalyticsEvents are accepted.

Automatic enrichment — every event payload is automatically extended with:

  • environment — the configured environment
  • app_name — the configured app name
  • app_version — the configured app version

Payload sanitization rules:

  • Maximum 25 parameters per event (extras are dropped)
  • String values are truncated to 100 characters
  • Only string, number, boolean values are allowed (nulls are filtered)
import { Analytics, AnalyticsEvents } from "@codeimplants/analytics";

await Analytics.track(AnalyticsEvents.LOGIN_SUCCESS, {
  method: "email",
  user_type: "premium",
});

Analytics.screen

Analytics.screen(screenName: string): Promise<void>

Logs a screen view event to Firebase Analytics via logScreenView. Sets both screen_name and screen_class to the provided value.

await Analytics.screen("HomeScreen");

Analytics.setUser

Analytics.setUser(userId: string): Promise<void>

Associates all subsequent events with the given user ID (calls Firebase setUserId).

await Analytics.setUser("user_abc123");

Analytics.clearUser

Analytics.clearUser(): Promise<void>

Removes the user ID association. Call this on logout.

await Analytics.clearUser();

Available Events

All valid event names are defined in AnalyticsEvents. Do not use raw strings — always import and use this constant.

import { AnalyticsEvents } from "@codeimplants/analytics";

| Constant | Event Name | Category | | ------------------------- | ------------------------- | --------------------- | | SCREEN_VIEW | screen_view | Navigation | | LOGIN_SUCCESS | login_success | Auth | | LOGIN_FAILURE | login_failure | Auth | | LOGOUT | logout | Auth | | API_FAILURE | api_failure | Network / Reliability | | RETRY_ATTEMPT | retry_attempt | Network / Reliability | | OFFLINE_DETECTED | offline_detected | Network / Reliability | | APP_OPEN | app_open | App Lifecycle | | APP_BACKGROUND | app_background | App Lifecycle | | SUPPORT_CONTACTED | support_contacted | Support | | APP_UPDATE_PROMPT_SHOWN | app_update_prompt_shown | Updates |

🚫 Any event name not in this list will be silently dropped at the validator level.


Types

import type {
  AnalyticsConfig,
  AnalyticsEnvironment,
  AnalyticsEventPayload,
} from "@codeimplants/analytics";

AnalyticsEnvironment

type AnalyticsEnvironment = "dev" | "qa" | "preprod" | "prod";

AnalyticsConfig

type AnalyticsConfig = {
  appName: string;
  environment: AnalyticsEnvironment;
  appVersion: string;
  enableAnalytics: boolean;
};

AnalyticsEventPayload

type AnalyticsEventPayload = Record<string, string | number | boolean | null>;

AnalyticsEventName

// Derived automatically — union of all values in AnalyticsEvents
type AnalyticsEventName = "screen_view" | "login_success" | "login_failure" | ...;

Integration Patterns

React Native App (Expo / Bare)

Initialize analytics in your root App.tsx or index.js:

// App.tsx
import React, { useEffect } from "react";
import { Analytics, AnalyticsEvents } from "@codeimplants/analytics";

const APP_ENV = process.env.APP_ENV ?? "local"; // "local" | "dev" | "qa" | "prod"

Analytics.init({
  appName: "my-app",
  environment: APP_ENV as any,
  appVersion: "1.0.0",
  enableAnalytics: APP_ENV !== "local",
});

export default function App() {
  useEffect(() => {
    Analytics.track(AnalyticsEvents.APP_OPEN);
  }, []);

  return <RootNavigator />;
}

Navigation Screen Tracking

Automatically log screen views with React Navigation:

import { NavigationContainer } from "@react-navigation/native";
import { Analytics } from "@codeimplants/analytics";

export default function RootNavigator() {
  return (
    <NavigationContainer
      onStateChange={(state) => {
        const currentRoute = state?.routes[state.index];
        if (currentRoute?.name) {
          Analytics.screen(currentRoute.name);
        }
      }}
    >
      {/* your navigators */}
    </NavigationContainer>
  );
}

Authentication Events

import { Analytics, AnalyticsEvents } from "@codeimplants/analytics";

// On successful login
async function handleLoginSuccess(userId: string) {
  await Analytics.setUser(userId);
  await Analytics.track(AnalyticsEvents.LOGIN_SUCCESS, { method: "email" });
}

// On login failure
async function handleLoginFailure(reason: string) {
  await Analytics.track(AnalyticsEvents.LOGIN_FAILURE, { reason });
}

// On logout
async function handleLogout() {
  await Analytics.track(AnalyticsEvents.LOGOUT);
  await Analytics.clearUser();
}

App Lifecycle Events

import { useEffect } from "react";
import { AppState } from "react-native";
import { Analytics, AnalyticsEvents } from "@codeimplants/analytics";

export function useAppLifecycleTracking() {
  useEffect(() => {
    const subscription = AppState.addEventListener("change", (nextState) => {
      if (nextState === "background" || nextState === "inactive") {
        Analytics.track(AnalyticsEvents.APP_BACKGROUND);
      }
    });

    return () => subscription.remove();
  }, []);
}

Network / Reliability Events

import { Analytics, AnalyticsEvents } from "@codeimplants/analytics";

// Track API failure
async function fetchData(endpoint: string) {
  try {
    const res = await fetch(endpoint);
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return await res.json();
  } catch (error) {
    await Analytics.track(AnalyticsEvents.API_FAILURE, {
      endpoint,
      error: String(error),
    });
    throw error;
  }
}

// Track retry attempt
async function retryFetch(endpoint: string, attempt: number) {
  await Analytics.track(AnalyticsEvents.RETRY_ATTEMPT, { endpoint, attempt });
  return fetchData(endpoint);
}

// Track offline state
import NetInfo from "@react-native-community/netinfo";

NetInfo.addEventListener((state) => {
  if (!state.isConnected) {
    Analytics.track(AnalyticsEvents.OFFLINE_DETECTED);
  }
});

User Identity

import { Analytics } from "@codeimplants/analytics";

// Set user after login / session restore
await Analytics.setUser("user_42abc");

// Clear user on logout or session expiry
await Analytics.clearUser();

Environment Behaviour

| Environment | Analytics Collected | DebugView (GA4) | | ----------- | ------------------- | --------------- | | dev | ✅ If enabled | ✅ Enabled | | qa | ✅ If enabled | ✅ Enabled | | preprod | ✅ If enabled | ✅ Enabled | | prod | ✅ If enabled | ❌ Disabled |

Even if enableAnalytics: true, the local environment will never send events to Firebase. This prevents development noise in your GA4 dashboard.


Internal Safeguards

The following safety mechanisms are built into the SDK — you don't need to implement them yourself:

| Safeguard | Description | | --------------------- | ------------------------------------------------------------------ | | Try/Catch wrapper | All Firebase calls are wrapped — analytics never crashes the app | | Double-init guard | init can only take effect once per app session | | Event allowlist | Unknown event names are silently dropped by the validator | | Rate-limit guard | Events fired within 300ms of each other are dropped | | Payload sanitizer | Max 25 params, max 100 chars per string value, filters null values | | Environment gate | local environment always skips tracking | | Init check | track / screen are no-ops if init was never called |


Mandatory Rules

| Rule | Detail | | ------------------------------------------------------------------------ | ------------------------------------------------------- | | ❌ Do NOT import @react-native-firebase/analytics directly in your app | Always go through this SDK | | ❌ Do NOT invent or hardcode event name strings | Always use AnalyticsEvents.* constants | | ✅ Call Analytics.init exactly once at app startup | Place it before any screen renders | | ✅ Always use Analytics.setUser after login | And clearUser on logout | | ✅ Use Analytics.screen for screen tracking | Integrate with your navigation library's state listener |