qora_flutter
Flutter integration for Qora. Bind server state to your UI with a single widget: no setState, no StreamBuilder, no loading flag boilerplate.
Part of the Qora monorepo.
Features
| Feature | Description |
|---|---|
| Declarative UI | Access your data directly via QoraBuilder |
| Lifecycle aware | Queries pause when the app is in the background |
| Network aware | Triggers refetches when the connection is restored |
| Zero boilerplate | Loading, error, and data states handled in one place |
Install
dependencies:
qora_flutter: ^1.0.0
qora_flutter automatically includes qora and connectivity_plus as dependencies; no extra packages needed.
Setup
Wrap your app with QoraScope once:
import 'package:qora_flutter/qora_flutter.dart';
void main() {
final client = QoraClient(
config: const QoraClientConfig(debugMode: kDebugMode),
);
runApp(
QoraScope(
client: client,
lifecycleManager: FlutterLifecycleManager(qoraClient: client),
connectivityManager: FlutterConnectivityManager(),
child: const MyApp(),
),
);
}
Fetch and display data
QoraBuilder<T> fetches on mount, caches the result, and rebuilds on every state change:
QoraBuilder<User>(
queryKey: ['users', userId],
fetcher: () => api.getUser(userId),
builder: (context, state, fetchStatus) => switch (state) {
Loading(:final previousData) => previousData != null
? UserCard(user: previousData, isRefreshing: true)
: const CircularProgressIndicator(),
Success(:final data) => UserCard(user: data),
Failure(:final error, :final previousData) => ErrorScreen(
message: error.toString(),
onRetry: () => context.qora.invalidate(['users', userId]),
),
_ => const SizedBox.shrink(),
},
)
Invalidate after a mutation
await api.createPost(payload);
context.qora.invalidate(['posts']);
context.qora.invalidateWhere((k) => k.firstOrNull == 'posts');
Every QoraBuilder subscribed to a matching key re-fetches automatically.
Optimistic updates
final client = context.qora;
final key = ['users', userId];
final snapshot = client.getState<User>(key);
client.setQueryData<User>(key, user.copyWith(name: newName));
try {
final updated = await api.updateUser(userId, newName);
client.setQueryData<User>(key, updated);
} catch (_) {
client.restoreQueryData<User>(key, snapshot);
}
Observe without fetching
QoraStateBuilder<T> mirrors a query's state without triggering a fetch; ideal for badges, counters, or secondary displays:
QoraStateBuilder<List<Notification>>(
queryKey: ['notifications'],
builder: (context, state) {
final count = state.dataOrNull?.length ?? 0;
return Badge(label: Text('$count'), child: const Icon(Icons.notifications));
},
)
Documentation
Full guides and API reference: qora.meragix.dev
Libraries
- qora_flutter
- Flutter integration layer for Qora.