flutter_gemma's engines are pluggable: you register them in
FlutterGemma.initialize(...), and the registry picks one per model by its
declared ModelFileType. flutter_gemma_mediapipe is the engine for Google's
MediaPipe runtime (tasks-genai) — it runs .task
bundles (and .bin).
A .task archive packages the model's .tflite weights, tokenizer, and
metadata together, and MediaPipe applies each model's chat template
internally, so you feed plain messages and it handles the formatting.
Platforms#
| Platform | Support | Runtime |
|---|---|---|
| Android | ✅ | MediaPipeTasksGenAI (Gradle) |
| iOS | ✅ | MediaPipeTasksGenAI (CocoaPods) — requires iOS 16.0+ |
| Web | ✅ | @mediapipe/tasks-genai (CDN) |
| Desktop (macOS/Windows/Linux) | ❌ | no MediaPipe engine — use LiteRT-LM or ONNX |
Mobile + Web only. There is no MediaPipe engine on desktop; for macOS/Windows/Linux run the
.litertlmformat via LiteRT-LM instead.
Setup#
Add the package and register MediaPipeEngine() at startup, alongside any other
engines your app uses:
dependencies:
flutter_gemma: latest_version
flutter_gemma_mediapipe: latest_version # MediaPipe .task engine
import 'package:flutter_gemma/flutter_gemma.dart';
import 'package:flutter_gemma_mediapipe/flutter_gemma_mediapipe.dart';
await FlutterGemma.initialize(
inferenceEngines: [MediaPipeEngine()],
);
MediaPipeEngine handles ModelFileType.task / .bin models. Pass it
alongside other engines (e.g. LiteRtLmEngine from flutter_gemma_litertlm) if
your app uses both formats — the registry routes each model to the right one.
iOS: this package requires iOS 16.0+ (MediaPipe GenAI's floor — it is the only flutter_gemma package that needs it). Set
platform :ios, '16.0'in thePodfileand the Runner's iOS Deployment Target in Xcode, and useuse_frameworks! :linkage => :static(MediaPipe ships static xcframeworks). Android needs no extra setup — the MediaPipe Gradle deps are bundled.
Install a .task model#
installModel defaults fileType to ModelFileType.task, so a .task
model
needs no explicit file-type declaration:
await FlutterGemma.installModel(
modelType: ModelType.gemmaIt,
).fromNetwork('https://.../gemma3-1b-it.task').install();
final model = await FlutterGemma.getActiveModel(maxTokens: 4096);
final session = await model.createSession();
await session.addQueryChunk(const Message(text: 'Hello!', isUser: true));
final response = await session.getResponse();
Models can also come from an asset, a bundled file, or a local path — see Models for every source and the model catalog.
Web setup#
On Web the MediaPipe runtime is loaded from a CDN. Add this to your app's
web/index.html inside a <script type="module"> (before the Flutter
bootstrap), exposing the symbols on window:
<script type="module">
import { FilesetResolver, LlmInference } from 'https://cdn.jsdelivr.net/npm/@mediapipe/[email protected]';
window.FilesetResolver = FilesetResolver;
window.LlmInference = LlmInference;
</script>
The pinned version is @mediapipe/[email protected]. Web runs GPU-only
— there is no CPU backend in the browser, so PreferredBackend.gpu is required.
Vision works on Web with Gemma 4's .task web build; thinking mode
(extraContext) is not available through MediaPipe on Web.
Backends#
PreferredBackend | Android | iOS | Web |
|---|---|---|---|
cpu | ✅ | ✅ | ❌ |
gpu | ✅ | ✅ | ✅ (required) |
Pass the backend when you open the model:
final model = await FlutterGemma.getActiveModel(
maxTokens: 4096,
preferredBackend: PreferredBackend.gpu,
);