●  New: build your backend and app together with AI. Point Claude or Cursor at AppAmbit over MCP.

On mobile?

Email yourself the setup link so you can finish when you're at your computer.

React Native · iOS & Android

One package at launch. Every route in the crash trail.

Install appambit, call AppAmbit.start() once, and your app reports sessions, device details and crashes from both stores. Hand it your navigation container and every screen your users passed through arrives attached to the crash.

npm: appambit Open source TypeScript types included

No credit card required. Free tier available. The same SDK also gives you a database, cloud functions and remote config.

App.tsx · TypeScript Live
import { useEffect } from "react";
                        import * as AppAmbit from "appambit";
                         
                        export default function App() {
                          useEffect(() => {
                            // the whole integration
                            AppAmbit.start("<YOUR-APPKEY>");
                          }, []);
                         
                          return <RootNavigator />;
                        }
Sessions, device details and crashes start from that call. appambit 1.2.1
One

Call at launch. That is the whole integration.

2

Apps in AppAmbit, one codebase. iOS and Android.

21

Minimum Android API level. iOS 11 and up.

Zero

Type packages to install. They ship with it.

Screen breadcrumbs

Your screens are JavaScript. Give the SDK the ref.

On a native project the SDK sees every screen the system pushes. In React Native the screens live in your bundle, so the native side is blind to them until you hand over your navigation container. One call on onReady and it listens for route state changes from then on, with nothing added inside your screens.

01

Create the ref

useNavigationContainerRef() from React Navigation, in the component that renders your container.

02

Register it once

Call AppAmbit.registerNavigationTracking(ref) from the container's onReady. Once is enough for the life of the app.

03

Name your routes

A breadcrumb carries the route name it was given, so a screen called CartScreen reads as itself in the trail instead of as an index.

How the session timeline works
Session trail · one session Recording
ScreenHomeScreen0.0s
EventProduct openedsku=RN-204
ScreenProductScreen2.4s
ScreenCartScreen9.1s
EventCheckout started11.7s
CrashTypeError: undefined is not an object12.0s

Six breadcrumbs, and the last one is the crash. This is what arrives attached to the report.

See a session timeline

Every crash lands inside the session that led to it, with the run-up already attached.

One codebase, two stores

One project, two App Keys.

An app in AppAmbit belongs to one operating system, so a project that ships to both stores gets an iOS app and an Android app. Pick between their keys where you start the SDK and the rest of your code never has to know which one it got.

Two apps in the dashboard, each with its own App Key on its Info page and its own crash list. An Android crash never lands in the iOS app.
One account, one bill. Both apps sit in the same team, share the same billing and read from the same database and remote config.
The same calls either way. AppAmbit.trackEvent, AppAmbit.logError and the rest are identical on both platforms. Only the key changes.
appKey.ts · TypeScript
import { Platform } from "react-native";
                        import * as AppAmbit from "appambit";
                         
                        // one app per store, one App Key each
                        const APP_KEY = Platform.select({
                          ios: "<IOS-APPKEY>",
                          android: "<ANDROID-APPKEY>",
                        }) as string;
                         
                        AppAmbit.start(APP_KEY);
Platform.select is React Native's own, not ours. One key per store
Create your two apps

One team, one App Key per store, and both of them on the same free tier.

The whole API

Six calls, and you have seen all of it.

There is no client to configure, no pipeline to describe and no schema to declare. Every one of these is typed by the package itself.

AppAmbit.start("<YOUR-APPKEY>")

The one you always write

Called once from your entry point, inside a useEffect on your root component. Everything else on this page keys off it.

AppAmbit.registerNavigationTracking(ref)

Hand over your routes

Give it the ref from useNavigationContainerRef and every route change becomes a breadcrumb, with no instrumentation inside your screens.

AppAmbit.trackEvent(title, properties)

Track what matters

A named event and a plain object of string values. Up to 150 distinct names, 120 characters per name and 80 per property.

AppAmbit.logError({ exception, stack })

Report a handled error

Catch it, log it, carry on. Pass the stack, the error and its constructor name, and it lands beside your crashes with the same session context.

Crash monitoring

AppAmbit.logErrorMessage(message)

Log without an exception

For the cases where you have a message and nothing was thrown. Same destination, same context.

AppAmbit.generateTestCrash()

Prove it works

Fire a deliberate crash on a debug build and watch a real report arrive, so you know the native side is wired before you ship anything.

Get an App Key

That is the whole surface. The key that makes those calls report takes a minute to create.

Same SDK, same App Key

The backend was already in the package.

Analytics and crashes are where most teams start. Everything below is documented for React Native too, behind the same key you already pasted in.

App Analytics

Sessions, devices and OS versions from both builds, drawn from what the SDK already sends.

App Analytics

Event Tracking

The events you name yourself, with their properties kept on every occurrence and grouped in the dashboard.

Event Tracking

Session Timeline

Every crash arrives inside the session it happened in, next to the events and logs that came before it.

Session Timeline

Breadcrumbs

The trail that led to the crash. Hand over your navigation ref and your routes write it for you.

Breadcrumbs

Remote config

Await a string, a number or a boolean and change it from the dashboard, with no rebuild and no wait behind either store.

Remote config

App Database

Real SQL from your JavaScript, awaited like anything else, with no server to run and no connection string bundled into the app.

App Database

Cloud Code

Call a Node.js function you deployed inside AppAmbit. It is exported from the same appambit package, so there is no second install.

Cloud Code

Content management

Read published content types and entries from the SDK, so copy and screens can change without shipping a new bundle.

CMS guide

Push notifications

One more package, your own APNs and FCM credentials, and listeners that hand back a cleanup function for useEffect.

Push notifications

Build delivery

Hand the .ipa and the .apk to your testers over a link, and see who is running which one.

Build delivery

AI Agent over MCP

Point Claude or Cursor at AppAmbit over MCP and let it read your crashes and sessions, or set the backend up for you.

AI Agent

AI App Builder

Ask Claude or Cursor for a feature and let it provision the backend that feature needs, on this same account.

AI App Builder
Open an account

Everything on this row is included, on the same App Key and the same free tier.

Build delivery

Two artifacts, one pipeline.

A React Native release is an .ipa and an .apk out of the same commit. Send both to AppAmbit from the job that built them and your testers install from a link, with the branch, commit and author attached. The build guides cover the secrets and the signing for each one.

.ipa .apk Build delivery

GitHub Actions

Build both targets in one workflow and let the signed webhook hand the .ipa and the .apk straight to AppAmbit.

Bitbucket Pipelines

Wire a pipeline step to publish each build, with the branch, commit and author carried along.

Azure DevOps

Connect an Azure pipeline and every green build shows up ready to send to your testers.

Distribute your first build

Connect the repository, and testers install from a link instead of waiting on a store.

Setup

Three steps, and only one of them is native.

Create your app in the dashboard to get an App Key, then add one package and one call. The middle step is the only place iOS and Android part ways, which is what the switch on the right is for.

01

Add the package

One dependency, from the npm registry. Version 1.2.1 is the current release, and the types come with it, so there is no second package to install for TypeScript.

# the current release
                            npm install appambit
                             
                            # or pin the version yourself
                            npm install appambit@1.2.1
# the current release
                            yarn add appambit
                             
                            # or pin the version yourself
                            yarn add appambit@1.2.1
Autolinking registers the native module for you. MIT licensed
02

Build it once for the platform

This is the only step that differs. On iOS the pods have to be installed before the native module is in the workspace; on Android autolinking handles it and a rebuild is enough.

Terminal · iOS Terminal · Android
# install the pods the native module brings in
                            cd ios && pod install
                             
                            # then build from the workspace as usual
                            npx react-native run-ios
# autolinking has already registered the module,
                            # so the app only has to be built again
                            npx react-native run-android
iOS 11.0 and up. Android 5.0, API level 21, and up. No manual linking
03

Start it, and hand over your routes

One call with the App Key from your app's Info page, and one on the navigation container. Sessions, device information and crash reporting begin at the first, screen breadcrumbs at the second.

App.tsx · TypeScript
import { useEffect } from "react";
                    import * as AppAmbit from "appambit";
                    import {
                      NavigationContainer,
                      useNavigationContainerRef,
                    } from "@react-navigation/native";
                     
                    export default function App() {
                      const navigationRef = useNavigationContainerRef();
                     
                      useEffect(() => {
                        AppAmbit.start("<YOUR-APPKEY>");
                      }, []);
                     
                      return (
                        <NavigationContainer
                          ref={navigationRef}
                          onReady={() => AppAmbit.registerNavigationTracking(navigationRef)}>
                          <RootStack />
                        </NavigationContainer>
                      );
                    }
The second call is what makes the trail below possible.

Both import styles work: the namespace as above, or import { start } from "appambit" if you would rather call each function bare. The full walkthrough is in the getting started guide.

Create your App Key

Step one is a free account. The other two take about five minutes.

Push notifications

One more package, not another vendor.

Push runs on the same App Key and the same install. You bring the APNs and FCM credentials from your own developer accounts, AppAmbit keeps the device tokens, and you send from the dashboard or from a Cloud Code function.

Add appambit-push-notifications next to the core package, then run pod install again on iOS. Android needs a Firebase project and its google-services.json.
Every listener returns its own cleanup, which is exactly what useEffect wants. Registering again replaces the previous subscription rather than stacking a second one.
The payload is typed: title, body, imageUrl and your own data, plus the ios and android blocks for the fields only one platform has.
How push notifications work
App.tsx · push
import * as PushNotifications
                          from "appambit-push-notifications";
                         
                        PushNotifications.start();
                        PushNotifications.requestNotificationPermission();
                         
                        useEffect(() => {
                          // fires when the user taps one, in any app state
                          const unsub = PushNotifications.setOpenedListener((p) =>
                            navigationRef.navigate(p.data.screen)
                          );
                         
                          return () => unsub();
                        }, []);
Ask for the permission when the moment makes sense, not at first launch.
Set up push

Your own credentials, the tokens already tied to your App Key, and no second vendor to sign with.

Questions

Answered straight.

Does it work with Expo?
It needs a project you can build natively. The SDK ships native modules for iOS and Android, so it runs in a React Native CLI project, or in an Expo project once you have prebuilt it and own the ios and android folders. It does not run inside Expo Go, and there is no Expo config plugin, so the push notification setup is done by hand.
Do I need one App Key or two?
Two. An app in AppAmbit belongs to one operating system, so a project that ships to both stores has an iOS app and an Android app, each with its own App Key and its own crash list. Pick between them with Platform.select where you call AppAmbit.start, and the rest of your code never has to know which one it got.
How do screen breadcrumbs work here?
On a native project the SDK sees screens through the platform. In React Native the screens live in your JavaScript, so the native side is blind until you hand it your navigation container ref with AppAmbit.registerNavigationTracking. From then on it listens for route state changes and records each one as a breadcrumb with the route name. Name your routes and the trail reads like your app.
Is TypeScript supported?
Yes, and there is nothing extra to install. The appambit package ships its own type definitions, so every call is typed the moment you add it. There is no separate types package to keep in step with the SDK.
What are the minimum versions?
iOS 11.0 and Android 5.0, API level 21, for the core SDK, on top of a working React Native environment. Push notifications ask for a little more on iOS: 13.0, and the Push Notifications capability turned on for the target.
Can I keep my current crash reporter alongside it?
No, and that is true of any pair of crash reporters. Under the JavaScript, two libraries installing handlers for the same native signals will fight over them, and you end up with reports missing from both. Remove the other one before you ship AppAmbit.
What happens when the device has no connection?
Nothing is lost. Sessions, events, logs and crashes are written to local storage while the device is offline, and the SDK sends everything that queued up in batches once connectivity returns. A crash is written to disk and sent on the next launch.

Building for the other platforms too? AppAmbit has an SDK for iOS, Android, Flutter, .NET MAUI, .NET and Avalonia. Each one takes its own App Key and reports into the same dashboard, on the same team and the same bill.

Try it on your own app

The free tier is enough to point the SDK at a real build and read your own sessions.

Ready when you are

Install the package. Watch the first session land.

Create a free account, paste your App Key into your entry point, and reload the app. The first session shows up while Metro is still running, and the next crash comes back with the screens your user walked through. iOS 11 and Android 5 and up, no credit card.

One package, and both stores report.

Start free