MiteSDK

Getting Started

Get up and running with the Mite SDK for React Native.

Mite is a React Native SDK for in-app feedback, error tracking, release notes, and feature requests. It ships ready-made UI (shake-to-report, a "What's New" widget, a feature request board) alongside hooks and a plain imperative API if you would rather build your own.

The source is at github.com/usemite/mite-sdk.

Installation

npm install @usemite/sdk

The package is @usemite/sdk. The older @usemite/mite-sdk name is no longer published to and is frozen at 0.1.2 — if you installed it, switch to @usemite/sdk.

Peer dependencies

react, react-native, and expo-device are required. Everything else is optional and only needed for the feature that uses it — when a module is missing the SDK logs a [Mite] warning and degrades gracefully instead of crashing.

PackageRequiredNeeded for
react ^19.1.0Yes—
react-native ^0.81.5Yes—
expo-device >=57.0.0YesDevice info on bug reports
expo-sensors >=57.0.0NoShake detection (ShakeToReport)
react-native-view-shotNoScreenshot capture (ShakeToReport)
expo-store-review >=57.0.0NoNative review dialog (StoreReviewPrompt)
expo-application >=57.0.0NoApp version detection (What's New)
expo-constants >=57.0.0NoApp version fallback (What's New)
expo-router >=57.0.0NoNavigation breadcrumbs
@react-navigation/native >=6.0.0NoNavigation breadcrumbs

Setup

1. Initialize Mite

Create a Mite instance and initialize it in your app's entry point:

import AsyncStorage from '@react-native-async-storage/async-storage'
// or: import { MMKV } from 'react-native-mmkv'
import { Mite, MiteProvider } from '@usemite/sdk'

const mite = new Mite({
  apiKey: process.env.EXPO_PUBLIC_MITE_API_KEY,
  identityStorage: AsyncStorage, // or: new MMKV()
})

mite.init()

export default function RootLayout() {
  return (
    <MiteProvider client={mite}>
      {/* Your app */}
    </MiteProvider>
  )
}

mite.init() sets up the offline queue, syncs the anonymous identity in the background, and sends errors a previous launch left behind. Call it once, after constructing the instance. Uncaught errors and unhandled rejections are captured from construction, even before init().

Pass identityStorage unless you have a reason not to. Without it the anonymous ID lives in memory only and resets on every full app reload, so the same user looks like a new user each launch. The SDK logs a [Mite] warning at init() when no persistent storage is configured.

2. Configuration options

interface MiteConfig {
  apiKey?: string
  endpoint?: string
  timeout?: number
  retries?: number
  anonymousId?: string
  identityStorage?: MiteIdentityStorage | MiteMMKVLikeStorage
  identificationOptOut?: boolean
  enableOfflineQueue?: boolean
  enableNavigationBreadcrumbs?: boolean
  maxNavigationBreadcrumbs?: number
  captureUncaughtErrors?: boolean
  captureUnhandledRejections?: boolean
  enableErrorTracking?: boolean
  ignoreErrors?: Array<string | RegExp>
  beforeSendError?: (event: MiteErrorEvent) => MiteErrorEvent | null
  onQuotaExceeded?: (refusal: MiteQuotaRefusal) => void
}
OptionTypeDefaultDescription
apiKeystring—Your project API key. Required for every network call; methods throw without it
endpointstringMite's hosted APIOverride the backend base URL
timeoutnumber5000Request timeout in ms
retriesnumber0Automatic retry attempts, with exponential backoff capped at 10s
anonymousIdstringgeneratedOverride the generated anonymous identifier
identityStorageMiteIdentityStorage | MiteMMKVLikeStoragein-memoryAsyncStorage-compatible adapter or an MMKV instance
identificationOptOutbooleanfalseStart in anonymous-only mode
enableOfflineQueuebooleantrueRetry feedback that fails on a network error
enableNavigationBreadcrumbsbooleantrueAttach the navigation trail to feedback
maxNavigationBreadcrumbsnumber20Screens kept in the navigation trail
captureUncaughtErrorsbooleantrueCapture uncaught JS errors. See Error Tracking
captureUnhandledRejectionsbooleantrueCapture unhandled promise rejections. Hermes only
enableErrorTrackingbooleantrueSend captured errors to Mite
ignoreErrorsArray<string | RegExp>—Drop errors whose message matches
beforeSendError(event) => event | null—Edit an error before it is sent. Return null to drop it
onQuotaExceeded(refusal) => void—Called on a plan quota refusal

apiKey is typed as optional so you can construct an instance without one, but every method that talks to the API (feedback.send, user.identify, releases.list, announcements.list, every features method) throws [Mite] API key is required to … when it is missing. Errors are not sent without it.

3. Access the instance

Any component under MiteProvider can reach the instance with useMite():

import { useMite } from '@usemite/sdk'

function ReportButton() {
  const mite = useMite()
  // ...
}

useMite() throws if called outside a MiteProvider.

4. The everyday API

Each area of Mite has its own namespace on the instance, so mite. autocompletes to feedback, features, errors, user, releases, announcements, and storeReview. Most apps need these calls:

// Anything a user sends: a bug, a question, an idea.
await mite.feedback.send({ type: 'question', message: 'How do I export my data?' })

// A request for the public feature board, where other users vote on it.
await mite.features.request({ title: 'Dark mode', author: { email } })

// An error your code caught. Uncaught errors are sent for you.
mite.errors.capture(error)

// After sign-in and sign-out.
await mite.user.identify(user.id, { email: user.email, isPaying: true })
await mite.user.reset()

The 1.0 methods such as submitBug and identify still work and are deprecated. See Deprecated 1.0 methods.

Drop-in UI

The fastest way to get value out of Mite is to mount the prebuilt components. Each one is self-contained and only needs to sit inside MiteProvider:

import { ShakeToReport, WhatsNew } from '@usemite/sdk'

<MiteProvider client={mite}>
  {/* Your app */}
  <ShakeToReport />
  <WhatsNew />
</MiteProvider>

What's next?

On this page