Skip to content

Herald Herald

Herald is an analytics library for mobile apps. Your app describes what happened as an event, and Herald sends that event to every analytics service you use: Firebase, Adjust, Mixpanel, AppsFlyer, Amplitude, Meta, or one you build yourself.

Choose your platform

  • Android


    Kotlin libraries on Maven Central: the core, one module per vendor, helpers for Compose, and a fake for your tests.

    Quick start · Android SDK

  • iOS


    Swift packages, over each vendor's official iOS SDK: the core, one package per vendor, optional SwiftUI helpers, a logger and a fake for your tests.

    Quick start · iOS SDK

  • Flutter


    Dart packages on pub.dev, over each vendor's official Flutter plugin: the core, one package per vendor, optional widgets, a logger and a fake for your tests.

    Quick start · Flutter SDK

  • React Native


    TypeScript packages on npm, over each vendor's official React Native package: the core, one package per vendor, optional React hooks, a logger and a fake for your tests.

    Quick start · React Native SDK

  • Kotlin Multiplatform


    Write events once, in shared Kotlin, over the Android and iOS SDKs: the core, and revenue events for Amplitude, Adjust, AppsFlyer and Meta.

    Quick start · Kotlin Multiplatform SDK

Not sure which one fits? Choose a platform compares them.

Why Herald

Your features don't know which vendors you use. A feature tracks its own event, like CheckoutStarted, and never calls Firebase or Adjust directly. You can add, replace or remove a vendor without touching feature code.

Each vendor gets data the way it expects. Vendors disagree on the details. GA4 wants screen views as its own screen_view event. Adjust only takes events you created a token for. AppsFlyer counts money only when it arrives as af_revenue. You describe these rules once per vendor, instead of spreading them across the app.

It fits apps split into feature modules. Each feature module keeps its own events and decides how they reach each vendor. The app module only chooses the vendors. It never needs a list of every event in the app, so a new feature doesn't mean editing a shared file.

One broken vendor can't break the rest. If a vendor SDK throws, Herald catches the error, tells you about it, and keeps sending to the other vendors. Your app keeps running.

Easy to test. Your classes depend on a small interface, not on a vendor SDK. In tests, a fake records every event, so you can check exactly what was tracked.

How it works

flowchart LR
    F[Feature code] -- "track(CheckoutStarted)" --> H[Herald]
    H --> C1[Firebase rules]
    H --> C2[Adjust rules]
    H --> C3[Amplitude rules]
    C1 --> V1[(GA4)]
    C2 --> V2[(Adjust)]
    C3 --> V3[(Amplitude)]

Your code calls track(CheckoutStarted), and Herald hands the event to every vendor you set up. For each vendor, you decide what happens to it: send it as it is, send it in that vendor's own format, or don't send it at all.

You write those decisions in small classes called factories, usually in the feature that owns the event. For example, your checkout feature can tell Adjust to send CheckoutStarted with the token from your Adjust dashboard. It says nothing to Firebase, so Firebase sends the event as it is.

You don't write a factory for every event. Herald comes with ready-made factories for the common cases: sending any event under its own name, sending screen views the way each vendor expects, and saving user properties. You only write your own for events that need something special.

Start here

  • Quick start: send your first event, on your platform.
  • Philosophy: why Herald works the way it does.
  • Guides: routing, feature modules, consent, identity, revenue and testing.
  • Vendors: what each vendor receives, and what to watch out for.
  • Moove: a sample app that uses every module, including feature modules, consent, sign-in, Compose and a screen that shows every event it sent.
  • The Flutter example app: screen views with and without herald_widgets, and a timeline of every event it sent.
  • The React Native example app: an Expo Router app with screen views, impressions, and a timeline of every event it sent.