Flutter InstantDB
API Reference

Flutter Widgets

Complete reference for Flutter InstantDB reactive widgets

Flutter InstantDB provides a set of reactive widgets that automatically update when data changes. These widgets integrate seamlessly with Flutter's widget tree and provide optimized performance.

Core Widgets

InstantProvider

Provides the InstantDB instance to the widget tree using Flutter's InheritedWidget pattern. This should typically wrap your entire app.

class InstantProvider extends InheritedWidget {
  const InstantProvider({
    super.key,
    required this.db,
    required super.child,
  });
  
  final InstantDB db;
  
  static InstantDB of(BuildContext context) {
    // Returns the InstantDB instance
  }
}

Parameters:

  • db (InstantDB): The database instance to provide
  • child (Widget): The child widget tree

Example:

void main() async {
  final db = await InstantDB.init(appId: 'your-app-id');
  runApp(InstantProvider(db: db, child: MyApp()));
}

Watch

Part of the signals_flutter library (re-exported by flutter_instantdb). This widget rebuilds whenever any signal accessed inside its builder function changes value.

class Watch extends StatelessWidget {
  const Watch(this.builder, {super.key});
  
  final Widget Function(BuildContext context) builder;
}

Example:

Watch((context) {
  final db = InstantProvider.of(context);
  final isOnline = db.isOnline.value; // Accessing .value creates a dependency
  return Text(isOnline ? 'Connected' : 'Disconnected');
});

Query Widgets

InstantBuilder

The primary widget for building UI based on InstaQL queries. It handles loading and error states automatically.

class InstantBuilder extends StatelessWidget {
  const InstantBuilder({
    required this.query,
    required this.builder,
    this.errorBuilder,
    this.loadingBuilder,
  });
}

Properties:

  • query (Map<String, dynamic>): The InstaQL query
  • builder (Widget Function(BuildContext, Map<String, dynamic>)): Called when data is available
  • loadingBuilder (Widget Function(BuildContext)?): Optional custom loading UI
  • errorBuilder (Widget Function(BuildContext, String)?): Optional custom error UI

Example:

InstantBuilder(
  query: {'goals': {}},
  builder: (context, data) {
    final goals = data['goals'] as List;
    return ListView(children: [ ... ]);
  },
)

InstantBuilderTyped<T>

A generic version of InstantBuilder that includes a transformer function to convert raw map data into your own model classes.

Example:

InstantBuilderTyped<List<Todo>>(
  query: {'todos': {}},
  transformer: (data) => (data['todos'] as List)
      .map((json) => Todo.fromJson(json))
      .toList(),
  builder: (context, todos) {
    return TodoList(todos: todos);
  },
)

InstantBuilder.list / InstantBuilder.single

Convenience static methods for common query patterns.

// Fetch a list of entities
InstantBuilder.list(
  entityType: 'todos',
  where: {'completed': false},
  builder: (context, todos) => ...,
)

// Fetch a single entity by ID
InstantBuilder.single(
  entityType: 'users',
  id: 'user-123',
  builder: (context, user) => ...,
)

Authentication Widgets

AuthBuilder

Rebuilds when the authentication state changes.

AuthBuilder(
  builder: (context, user) {
    if (user == null) return Text('Not logged in');
    return Text('Logged in as ${user.email}');
  },
)

AuthGuard

A higher-level widget that shows a child if the user is authenticated, or a fallback (or loginBuilder) if they are not.

AuthGuard(
  fallback: LoadingScreen(),
  loginBuilder: (context) => LoginScreen(),
  child: DashboardScreen(),
)

OAuthButton

A drop-in OAuth sign-in button. Builds an authorization URL (PKCE on by default) and hands the OAuthFlow to onLaunch; your app opens it and calls db.auth.exchangeCodeForToken. Does not bundle url_launcher.

OAuthButton(
  provider: OAuthProvider.google, // default label/color/icon
  clientName: 'google',           // OAuth client from the dashboard
  redirectUri: 'myapp://oauth',
  onLaunch: (flow) async {
    final result = await FlutterWebAuth2.authenticate(
      url: flow.url, callbackUrlScheme: 'myapp');
    final code = Uri.parse(result).queryParameters['code']!;
    await db.auth.exchangeCodeForToken(
      code: code, codeVerifier: flow.codeVerifier);
  },
)

OAuthProvider values: google, apple, github, linkedin, clerk, firebase. Override the preset with label, color, or icon; pass scopes or usePKCE: false as needed. See User Management.

Presence Widgets

Reactive equivalents of InstantDB's React presence hooks. Each joins the room and rebuilds on change. See Presence System.

PresenceBuilder

Equivalent of usePresence. Rebuilds on peer presence changes.

PresenceBuilder(
  roomId: 'doc-42',
  initialPresence: {'name': 'Alice'},
  builder: (context, room, peers) => Text('${peers.length} online'),
)

TopicListener

Equivalent of useTopicEffect. Side-effect widget; renders child.

TopicListener(
  roomId: 'doc-42',
  topic: 'emoji',
  onEvent: (data) => _showFloatingEmoji(data['emoji']),
  child: const Editor(),
)

TypingIndicatorBuilder

Rebuilds with the current typing peers.

TypingIndicatorBuilder(
  roomId: 'doc-42',
  builder: (context, typing) =>
      typing.isEmpty ? const SizedBox() : Text('${typing.length} typing…'),
)

ReactionsBuilder

Rebuilds with the live list of reactions.

ReactionsBuilder(
  roomId: 'doc-42',
  builder: (context, reactions) =>
      Wrap(children: [for (final r in reactions) Text(r.emoji)]),
)

CursorOverlay

Multiplayer cursor layer — Flutter equivalent of <Cursors>.

CursorOverlay(
  roomId: 'doc-42',
  userName: 'Alice',
  userColor: '#E91E63',
  child: const Canvas(),
)

Connection Widgets

ConnectionStatusBuilder

Provides periodic updates on the database connection status.

ConnectionStatusBuilder(
  builder: (context, isOnline) {
    return Icon(
      isOnline ? Icons.cloud_done : Icons.cloud_off,
      color: isOnline ? Colors.green : Colors.red,
    );
  },
)

State Management Hooks

useInstantQuery

A function that returns a Signal<QueryResult> for a given query. Useful inside StatefulWidget or other places where you want to manage the signal lifecycle yourself.

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  late Signal<QueryResult> query;

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    query = useInstantQuery(context, {'messages': {}});
  }

  @override
  Widget build(BuildContext context) {
    return Watch((context) {
       final result = query.value;
       // ... build UI
    });
  }
}

On this page