
Company News
Free Business Plan Upgrades for Open Source Maintainers
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.
@cross-deck/react-native
Advanced tools
Crossdeck SDK for React Native + Expo — verified subscriptions, entitlements, error capture, and product telemetry across iOS + Android JS apps in one package.
Crossdeck's React Native SDK — verified subscriptions, entitlements,
error capture, and product telemetry across iOS + Android JS apps in
one package. Same SDK surface as @cross-deck/web
@cross-deck/node
— cross-platform teams write identical call-sites.import { Crossdeck } from "@cross-deck/react-native";
Crossdeck.init({
appId: "app_rn_xxx",
publicKey: "cd_pub_live_…",
environment: "production",
});
await Crossdeck.identify("user_847");
const ents = await Crossdeck.getEntitlements();
if (Crossdeck.isEntitled("pro")) showPro();
Crossdeck.track("paywall_shown", { variant: "v3" });
npm install @cross-deck/react-native @react-native-async-storage/async-storage
# Expo
npx expo install @cross-deck/react-native @react-native-async-storage/async-storage
@react-native-async-storage/async-storage is an optional peer
dependency. Without it the SDK falls back to in-memory storage
(identity + queue don't survive app restarts; events queued offline
are lost on cold launch). Install it for production.
| Pillar | Surface |
|---|---|
| Subscriptions & entitlements | getEntitlements(), isEntitled(key), listEntitlements(), onEntitlementsChange(listener), syncPurchases({rail, signedTransactionInfo, purchaseToken}) |
| Behavioural analytics | track(name, properties), identify(userId, options), register(props), group(type, id, traits), consent({...}) |
| Error capture | Auto: ErrorUtils.setGlobalHandler + globalThis.fetch wrap. Manual: captureError(err), captureMessage(msg), setTag, setContext, addBreadcrumb, setErrorBeforeSend |
Every Crossdeck SDK ships these patterns by default:
isEntitled() after init(),
even on a cold launch with no network. A Crossdeck outage can
never fail a paying customer down to free.identify(userId)
switches the entitlement cache to a per-user AsyncStorage slot
(crossdeck:entitlements:<sha256(userId)>) and unconditionally
wipes the in-memory snapshot. A user-switch on a shared device
CANNOT cross-read a prior user's cache, even if the in-memory
clear is somehow skipped — the storage keys are physically
separate. reset() then wipes every per-user slot on the device
(logout-grade).(projectId, eventId).syncPurchases (v1.4.0).
Same signed transaction → same key → backend short-circuits
with idempotent_replay: true on retry. A network blip or app
crash mid-flight that re-fires the same purchase never
double-processes.onPermanentFailure + console.error regardless of debug mode.
No silent infinite-retry-with-growing-backlog.<email> / <card> (sentinel tokens
match the backend's defence-in-depth scrubber). Recursive — nested
{user:{email:...}} payloads ship scrubbed.| Option | Default | Notes |
|---|---|---|
appId | — | Required. From the Crossdeck dashboard. |
publicKey | — | Required. cd_pub_live_… or cd_pub_test_…. |
environment | — | Required. "production" or "sandbox". Must match key prefix. |
baseUrl | https://api.cross-deck.com/v1 | Override for self-hosted setups. |
persistIdentity | true | Set false to defer AsyncStorage writes until after a consent gate. |
storage | AsyncStorage (auto-detected) | Pass a SecureStore / MMKV adapter for higher-security app shells. |
storagePrefix | "crossdeck:" | Key namespace inside the storage adapter. |
autoHeartbeat | true | Disable for CI / tests. |
eventFlushBatchSize | 20 | Flush when buffer reaches this size. |
eventFlushIntervalMs | 5000 | Idle interval before flushing a partial batch. |
appVersion | — | Your app's version (e.g. "1.2.3"). Auto-attached to every event as properties.appVersion. |
platform | auto-detected | Override the Platform.OS detection. |
timeoutMs | 15000 | Per-request HTTP timeout. |
debug | false | Verbose diagnostic logging via the §16 debug-signal vocabulary. |
scrubPii | true | Disable only if your pipeline does its own PII redaction downstream. |
errorCapture | true | Disable if you have a separate error tracker (Sentry, Bugsnag) and don't want duplicates. |
init() returns void but kicks off async hydration (identity, super-
props, entitlement cache, persisted event queue). Every async method
(identify, track, flush, getEntitlements, etc.) awaits the
internal ready promise — callers can fire methods immediately after
init() without manual sequencing.
Sync methods (isEntitled, getSuperProperties, diagnostics)
read in-memory state. Until init() has fired they return sensible
empties.
v1.0 ships WITHOUT auto-session tracking. Wire your nav library's listener into:
import { AppState } from "react-native";
AppState.addEventListener("change", (state) => {
if (state === "background") {
void Crossdeck.flush();
}
});
Auto sessions + deep-link tracking land in v1.1 as opt-in
autoTrack: { sessions, deepLinks }.
Crossdeck.diagnostics();
// {
// started: true,
// anonymousId: "anon_1mqz3…",
// crossdeckCustomerId: "cdcust_abc",
// developerUserId: "user_847",
// sdkVersion: "1.0.0",
// baseUrl: "https://api.cross-deck.com/v1",
// platform: "ios",
// clock: { lastServerTime: 1779…, lastClientTime: 1779…, skewMs: 12 },
// entitlements: { count: 2, lastUpdated: 1779…, stale: false, listenerErrors: 0 },
// events: { buffered: 0, dropped: 0, inFlight: 0, lastFlushAt: 1779…, lastError: null, consecutiveFailures: 0, nextRetryAt: null }
// }
MIT © VistaApps (Pty) Ltd
FAQs
Crossdeck SDK for React Native + Expo — verified subscriptions, entitlements, error capture, and product telemetry across iOS + Android JS apps in one package.
The npm package @cross-deck/react-native receives a total of 17 weekly downloads. As such, @cross-deck/react-native popularity was classified as not popular.
We found that @cross-deck/react-native demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.