gemini_flutter_kit 0.1.0
gemini_flutter_kit: ^0.1.0 copied to clipboard
A production-ready toolkit for integrating Google Gemini AI into Flutter apps: streaming chat UI, rate limiting, retries, secure key storage, offline queueing, and usage tracking, out of the box.
gemini_flutter_kit #
Ship Gemini AI features in your Flutter app without rebuilding the same production plumbing every time.
A production-ready Google Gemini toolkit for Flutter: a drop-in streaming chat UI, rate limiting, retries, secure key storage, offline queueing, and usage tracking — all batteries included.
Add a demo GIF here —
GeminiChatViewstreaming a Markdown response.
Why this package #
Most Flutter + Gemini tutorials show a text field and a raw API call. That
breaks in production: quota runs out silently, errors surface as blank UI, API
keys leak into source, there's no retry logic, and no built-in way to track cost
or handle offline usage. gemini_flutter_kit wraps
google_generative_ai in an
opinionated layer that handles those "boring but critical" concerns for you, so
you can get a working streaming chat in under 10 lines of code.
Features #
| Feature | Class | What it does |
|---|---|---|
| Core client | GeminiClient |
Clean wrapper: sendMessage, sendMessageStream, startChat |
| Secure key storage | GeminiKeyManager |
Stores your API key in the platform keychain/keystore |
| Rate limiting | GeminiRateLimiter |
Client-side quota tracking with a remainingQuota getter |
| Retries | GeminiRetryPolicy |
Exponential backoff for transient network errors only |
| Typed errors | GeminiException & subtypes |
Every error carries a UI-safe userMessage |
| Offline queueing | GeminiOfflineQueue |
Persists requests offline, auto-flushes on reconnect |
| Usage tracking | GeminiUsageTracker |
Daily/monthly token & request counters |
| Chat UI | GeminiChatView |
Themeable, streaming, Markdown-rendering chat widget |
| Content safety | GeminiSafetyGuard |
Surfaces Gemini safety ratings + a report hook |
| Disclosure copy | GeminiDisclosureText |
Editable privacy-policy starter text |
Installation #
flutter pub add gemini_flutter_kit
Quick start #
import 'package:gemini_flutter_kit/gemini_flutter_kit.dart';
final client = GeminiClient(
apiKey: 'YOUR_API_KEY', // load via GeminiKeyManager in real apps
model: 'gemini-1.5-flash',
);
// Simple usage
final response = await client.sendMessage('Explain widgets in Flutter simply.');
// Drop-in chat UI
Scaffold(
body: GeminiChatView(
client: client,
theme: GeminiChatTheme(
userBubbleColor: Colors.blue,
aiBubbleColor: Colors.grey.shade200,
),
onReportResponse: (id, reason) {
// wire to your own analytics/backend
},
),
);
// Check usage before showing a "premium" upsell, etc.
final usage = await client.usageTracker.getSummary();
print('Tokens used today: ${usage.tokensToday}');
Getting a free Gemini API key #
- Go to Google AI Studio.
- Sign in and click Create API key — the free tier needs no billing account or credit card.
- Copy the key. In a real app, store it with
GeminiKeyManagerrather than hardcoding it:
final keys = GeminiKeyManager();
await keys.saveKey(userProvidedKey); // stored in the platform keychain
final key = await keys.getKey();
Never hardcode an API key in source or commit it to version control.
Reliability, without the boilerplate #
Every request routes through the production plumbing automatically:
final client = GeminiClient(
apiKey: key,
rateLimiter: GeminiRateLimiter(maxRequestsPerMinute: 15),
retryPolicy: GeminiRetryPolicy(maxAttempts: 3),
offlineQueue: GeminiOfflineQueue(), // opt-in offline support
);
await client.initialize(); // starts the offline queue
try {
final reply = await client.sendMessage('Hi!');
} on GeminiException catch (e) {
// e.userMessage is always safe to show directly in the UI.
showSnackBar(e.userMessage);
}
- Rate limiting — bind
client.rateLimiter.remainingQuotato show "X requests left this minute" and fail fast with aGeminiRateLimitException. - Retries — network/timeout errors retry with exponential backoff; safety blocks and auth failures never retry.
- Offline queue — when offline,
sendMessagequeues the prompt (persisted to disk) and flushes it automatically on reconnect. Listen toclient.offlineQueue!.queueStatusStreamfor a "Waiting for connection…" banner andclient.queuedResponsesfor the eventual replies.
Theming the chat UI #
GeminiChatView is fully themeable via GeminiChatTheme — nothing is hardcoded
to Material defaults. Start from GeminiChatTheme.light / GeminiChatTheme.dark
and override individual fields:
GeminiChatView(
client: client,
theme: GeminiChatTheme.dark.copyWith(
userBubbleColor: Colors.deepPurple,
bubbleRadius: 20,
hintText: 'Ask me anything…',
),
);
Content safety & reporting #
Gemini applies safety filters server-side; this package surfaces that metadata and gives users a way to report harmful output (which satisfies Google Play's guidance for apps with AI-generated content):
GeminiChatView(
client: client,
onReportResponse: (messageId, reason) {
myBackend.reportHarmfulResponse(messageId, reason);
},
);
Long-pressing an AI message opens the report sheet. Blocked responses throw a
GeminiSafetyBlockedException carrying the SafetyRatings.
Example app #
The example/ app demonstrates every major feature: secure key
entry, streaming chat, a live usage bar, and an offline-queue banner. Run it
with your own key:
cd example
flutter run --dart-define=GEMINI_API_KEY=your_key_here
Roadmap #
- Multi-provider support (Claude, OpenAI) — the client is intentionally abstracted internally so this can be added. Contributions welcome.
- Firebase App Check / enterprise auth.
- Image & multimodal input.
Testing #
Tests are fully hermetic — no API key, network, or cost required. See
test/README.md.
dart run build_runner build
flutter test
Disclaimer #
GeminiDisclosureText provides starter privacy copy for convenience — it is
not legal advice. Review and adapt it for your product and jurisdiction.
License #
MIT © 2026 gemini_flutter_kit contributors.