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

@apex-inc/capacitor-plugin

v0.2.0

Published

Apex Capacitor plugin — iOS/Android attribution, events, deep linking, SKAN, and offline-tolerant tracking for Capacitor apps.

Readme

@apex-inc/capacitor-plugin

Apex Capacitor plugin — iOS and Android attribution, events, deep linking, SKAN, and offline-tolerant tracking for Capacitor apps.

Ships alongside apex.js (the web snippet) so a Capacitor app gets unified identity and events across WebView + native APIs with one dependency pattern.

Scope. This plugin is for Capacitor apps. Native iOS (Swift), native Android (Kotlin), React Native, and Flutter apps need their own SDKs — see https://apex.inc/docs/mobile/which-sdk.

Try it in 5 minutes. The sample app is a three-screen Capacitor + React app that exercises every API in this plugin. git clone, npm install, npm run dev, watch events land in your Apex dashboard.

Install

npm install @apex-inc/capacitor-plugin
npx cap sync

Initialize

Call initialize() once at app startup, before any other plugin method.

import { Apex } from "@apex-inc/capacitor-plugin";

await Apex.initialize({
  projectKey: "prj_your_key",
  // Optional:
  // apiUrl: "https://api.apex.inc",
  // sessionTimeoutMinutes: 30,
  // offlineQueueMaxSize: 1000,
  // testMode: false,
  // debug: false,
});

Track events

await Apex.track({
  type: "app_open",
  data: { from: "push_notification" },
});

// In-app purchase — typed payload
await Apex.track({
  type: "in_app_purchase",
  purchase: {
    productId: "com.example.app.pro_monthly",
    amount: 9.99,
    currency: "USD",
    transactionId: "abc123",
  },
});

Every event gets a client-generated UUIDv4 id automatically. Server-side idempotency means replayed events never double-count.

iOS App Tracking Transparency

// Present the ATT prompt once (no-op on Android).
const { status } = await Apex.requestTrackingAuthorization();

// Check status later without prompting.
const { status: current } = await Apex.getTrackingStatus();

Advertising identifiers

// Returns IDFA (iOS, ATT authorized), GAID (Android), or fallback.
const { id, fallback } = await Apex.getAdvertisingId();
if (!id && fallback === "idfv") {
  console.log("Using IDFV fallback — user denied ATT");
}

SKAdNetwork conversion values (iOS 4.0+)

await Apex.updateConversionValue({
  fineValue: 42,
  coarseValue: "high",
});

Deep links

// Cold start: read the URL that opened the app (if any).
const { url } = await Apex.getInitialDeepLink();

// Warm-start / subsequent links while running:
await Apex.addListener("deepLink", ({ url }) => {
  handleRoute(url);
});

Sessions

const { sessionId } = await Apex.startSession();

await Apex.addListener("sessionEnd", ({ sessionId, durationSeconds }) => {
  console.log(`Session ${sessionId} ended after ${durationSeconds}s`);
});

Offline durability

Events are persisted to IndexedDB (web), Core Data (iOS), or Room (Android). If the device is offline, they queue up to the configured offlineQueueMaxSize (default 1000). When the network returns, the plugin drains the queue in batches with exponential-backoff retry.

const { count, oldestEventAt } = await Apex.getQueueSize();

// Manually trigger a flush (rarely needed — happens automatically):
const { flushed, remaining } = await Apex.flushQueue();

Test mode

// At init:
await Apex.initialize({ projectKey: "prj_test", testMode: true });

// Or toggle at runtime:
await Apex.setTestMode({ enabled: true });

Test-mode events are stored separately on the server and never pollute production analytics.

Web fallback

The plugin runs in a browser or PWA too — identifiers return null, ATT is a no-op, events still flow to the server via the normal offline queue. This lets you run shared code paths between web + mobile without Capacitor.isNativePlatform() checks everywhere.

License

Apache-2.0 — see LICENSE. See also the project plan document for the full MMP roadmap.