Pub Version CI

The world's best Flutter Crash Reporting solution.


Library organisation

Raygun4Flutter is from version 1.0.0 onwards built entirely in Dart and does not rely on the native providers Raygun4Android and Raygun4Apple anymore as earlier versions of Raygun4Flutter.

The file lib/raygun4flutter.dart provides the main API entry point for Flutter users.


  • Dart SDK 3.3.0+

As of release 1.0.0 we've started to improve support for Flutter Desktop and Web. The package seems to be working fine with these targets but we'd appreciate any additional feedback on Github.


1. Depend on it

Run this command:

$ flutter pub add raygun4flutter

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):

  raygun4flutter: ^x.y.z

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

2. Import it

Now in your Dart code, you can use:

import 'package:raygun4flutter/raygun4flutter.dart';

Check the "Installing" tab on https://pub.dev/packages/raygun4flutter/install for more info.

3. Platform-specific notes


If your application comprises hybrid code both using Flutter and native Android or iOS elements, please be aware that the Raygun4Flutter package will only track and report crashes from Flutter and Dart.

If you have a requirement to track crash reports across various layers and parts of your application written in different technologies you might need to implement the respective native providers for Android, iOS or other platforms of choice as well.


In your app's AndroidManifest.xml (usually located in your Flutter project's /android/src/main directory), make sure you have granted Internet permissions. Inside the <manifest> element add:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

if it doesn't exist yet.

Setup and usage

Initialisation and version tracking

Call Raygun.init() with an apiKey argument to initialise RaygunClient on application start, for example, from your initState method.

class _MyAppState extends State<MyApp> {

  void initState() {


The .init() method can also accept an optional version argument. If this is supplied, the version of your app will be tracked across Raygun crash reports:

Raygun.init(apiKey:'12345', version:'1.4.5');

As an additional convenience way to set the version, a method .setVersion() is available. Typical use cases would most likely fall back to setting the app version in the .init() method call when you setup the library.

Capturing and sending errors

To be able to capture errors inside Flutter, you need to add a custom FlutterError.onError handler to your main method. That redirects Flutter errors to Raygun.

Note: This only works when the app is running in "Release" mode.

  FlutterError.onError = (details) {
    // Default error handling

    // Raygun error handling
      error: details.exception,
      stackTrace: details.stack,

You can also catch Dart errors outside of the code controlled by the Flutter framework by calling to runApp from a runZonedGuarded and redirecting captured errors to Raygun. For example: errors that happen in asynchronous code.

Note: This works both in "Release" and "Debug" modes.

  runZonedGuarded<Future<void>>(() async {
    runApp(const MyApp());
  }, (Object error, StackTrace stackTrace) {
      error: error,
      stackTrace: stackTrace,

Sending errors manually

Call Raygun.sendException(error, tags, customData, stackTrace) to send errors to Raygun.

For example:

try {
  // code that crashes
} catch (error) {
  Raygun.sendException(error: error);

All arguments but error are optional. This method is mainly a convenience wrapper around the more customisable .sendCustom() method that obtains the class name and the message from the error object.

Sending custom errors manually

Call Raygun.sendCustom(className, reason, tags, customData, stackTrace) to send custom errors to Raygun with your own customised className and reason. As with .sendException(), tags, customData and stackTrace are optional.

For example:

  className: 'MyApp',
  reason: 'test error message',
  tags: ['API','Tag2'],
  customData: {
    'custom1': 'value',
    'custom2': 42,
  stackTrace: StackTrace.current,

Crash reports will be sent to the Raygun backend after the crash occurred. Should a user's device be offline, Raygun4Flutter will store up to 64 crash reports locally and try to send them when the device comes back online.

Other functionality

Setting tags

Raygun.setTags() sets a list of global tags that will be logged with every exception. This will be merged with other tags passed into manually created crash reports via sendException() and sendCustom().


Setting custom data

Raygun.setCustomData() sets a global map of key-value pairs that, similar to tags, that will be logged with every exception. This will be merged with other custom data passed into manually created crash reports via sendException() and sendCustom().

  'custom1': 'value',
  'custom2': 42,

Sending breadcrumbs

Breadcrumbs can be sent to Raygun to provide additional information to look into and debug issues stemming from crash reports. Breadcrumbs can be created in two ways.

Simple string:

Call Raygun.recordBreadcrumb(message), where message is just a string:

Raygun.recordBreadcrumb('test breadcrumb');

Using RaygunBreadcrumbMessage:

Create your own RaygunBreadcrumbMessage object and send more than just a message with Raygun.recordBreadcrumb(RaygunBreadcrumbMessage).

The structure of the type RaygunBreadcrumbMessage is as shown here:

    required this.message,
    this.level = RaygunBreadcrumbLevel.info,

Breadcrumbs can be cleared with Raygun.clearBreadcrumbs().

Getting/setting/cancelling the error before it is sent

This provider has an onBeforeSend API to support accessing or mutating the candidate error payload immediately before it is sent, or cancelling the sending action.

This is provided as the public callback Raygun.onBeforeSend, which takes an OnBeforeSendCallback.


Raygun.onBeforeSend = (payload) {
  // e.g. override the payload error message with a new message
  payload.details.error!.message = 'New Error Message';
  // important: return the payload to continue the sending action
  return payload;

To cancel the sending action, return null:

Raygun.onBeforeSend = (payload) {
  return null;

Set the Raygun.onBeforeSend to null to remove your custom callback:

Raygun.onBeforeSend = null;

Affected Customers

Raygun supports tracking the unique customers who encounter bugs in your apps.

By default, a device-derived UUID is transmitted. You can also add the currently logged in customer's data like this using an object of type RaygunUserInfo:

    identifier: '1234',
    firstName: 'FIRST',
    fullName: 'LAST',
    email: 'test@example.com',

To clear the currently logged in customer, call setUser(null).

There is an additional convenience method that offers a shortcut to just track your customer by an indentifier only. If you use an email address to identify the user, please consider using setUser instead of setUserId as it would allow you to set the email address into both the identifier and email fields of the crash data to be sent.


Call with null to clear the user identifier: setUserId(null)

Custom endpoints

Raygun supports sending data from Crash Reporting to your own endpoints. If you want to set custom endpoints, could can do so by setting them after you've initialised Raygun:


Please note that setting a custom endpoint will stop Crash Report or Real User Monitoring data from being sent to the Raygun backend.

Comprehensive sample app

For a working sample app across multiple platforms, check the Flutter project in the example directory.

Known issues

  1. setMaxReportsStoredOnDevice is not exposed and is currently set to 64.