FlutterFever Studio
Back to packages

Mediapipe Face Mesh Flutter package guide

Real‑time on‑device face detection, 478‑point mesh and iris tracking for Flutter.

Install command
Copy and run in your Flutter project
flutter pub add mediapipe_face_mesh

When to use Mediapipe Face Mesh

The **mediapipe_face_mesh** package brings Google’s MediaPipe face‑mesh technology to Flutter, allowing developers to run high‑precision facial landmark detection entirely on the device. With support for up to 478 landmarks—including detailed iris points—and multi‑face tracking, the library enables a range of immersive experiences such as avatar animation, AR filters, virtual try‑ons, and head‑pose estimation without sending any image data to a server. Because the inference runs locally, latency stays low, battery consumption is predictable, and privacy concerns are minimized.

When you need to overlay graphics on a live camera feed, animate a 3D avatar based on a user’s expressions, or capture subtle eye movements for accessibility features, this package is a natural fit. It works alongside the standard `camera` plugin, feeding each frame into MediaPipe’s on‑device model and returning a structured list of landmarks. The output includes ARKit‑style blendshape coefficients, making it easy to drive facial animation rigs directly from the data. For developers building cross‑platform AR experiences, the same Dart API works on Android and iOS, abstracting away the native implementation details.

Integrating the package into a typical Flutter architecture is straightforward. In a clean‑architecture or MVVM setup, you would place the face‑mesh service in the data layer, expose a `Stream<List<Landmark>>` from a repository, and consume it in a view model or BLoC. UI widgets can then subscribe to the stream and render custom painters, 3D meshes, or blendshape‑driven widgets in real time. Because the package does not depend on any backend, it can be used in offline‑first apps, and it plays nicely with popular state‑management solutions like Provider, Riverpod, or Bloc.

Setup is simple: add the dependency, configure platform‑specific permissions for camera access, and initialise the `FaceMeshController`. The package automatically downloads the required native binaries on first run, but you should test on a range of devices to verify performance. Production‑grade apps should consider throttling the frame rate on low‑end hardware, handling permission denials gracefully, and providing a fallback UI when the model fails to initialise. Additionally, be aware that continuous camera usage can increase battery drain, so offering an explicit start/stop control is recommended.

For beginners, a minimal example can be built in under ten minutes. Create a `CameraPreview` widget, attach the `FaceMeshController`, and draw the landmarks with a `CustomPaint`. The package also supplies utility methods to convert landmark coordinates into normalized screen space, simplifying the overlay logic. As you grow more comfortable, you can experiment with blendshape values to drive a 3D avatar, or combine the mesh data with other sensors for advanced head‑pose tracking. The flexibility of the API makes it suitable for both quick prototypes and production‑ready AR pipelines.

augmented reality filters
avatar animation from live video
eye‑tracking for accessibility
virtual try‑on of glasses or makeup
head‑pose estimation for gaming

Pros

  • on‑device inference preserves privacy
  • high‑resolution 478 landmarks with iris detail
  • cross‑platform Android & iOS support
  • no external server required

Watch outs

  • no web or desktop support yet
  • requires camera permission and sufficient device performance
  • adds native binary size to the app

Setup notes

1. Add the dependency: `flutter pub add mediapipe_face_mesh` 2. Run `flutter pub get` 3. For Android, add `CAMERA` permission to `AndroidManifest.xml`. 4. For iOS, add `NSCameraUsageDescription` to `Info.plist`. 5. Initialise `FaceMeshController` after obtaining camera permission. 6. Dispose the controller when the widget is removed to free native resources.

Requires Android API 21+ and iOS 11+. Works with Flutter 3.0 and later. The package depends on the `camera` plugin; ensure both plugins use compatible versions. No web support at this time.

import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:mediapipe_face_mesh/mediapipe_face_mesh.dart';

class FaceMeshDemo extends StatefulWidget {
  @override
  _FaceMeshDemoState createState() => _FaceMeshDemoState();
}

class _FaceMeshDemoState extends State<FaceMeshDemo> {
  late CameraController _cameraController;
  late FaceMeshController _faceMeshController;
  List<Landmark> _landmarks = [];

  @override
  void initState() {
    super.initState();
    _initializeCamera();
  }

  Future<void> _initializeCamera() async {
    final cameras = await availableCameras();
    _cameraController = CameraController(cameras.first, ResolutionPreset.medium);
    await _cameraController.initialize();
    _faceMeshController = FaceMeshController();
    _cameraController.startImageStream((image) async {
      final lm = await _faceMeshController.processImage(image);
      setState(() => _landmarks = lm);
    });
  }

  @override
  void dispose() {
    _cameraController.dispose();
    _faceMeshController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          CameraPreview(_cameraController),
          CustomPaint(
            painter: LandmarkPainter(_landmarks),
          ),
        ],
      ),
    );
  }
}

class LandmarkPainter extends CustomPainter {
  final List<Landmark> landmarks;
  LandmarkPainter(this.landmarks);
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()..color = Colors.red..strokeWidth = 2;
    for (var lm in landmarks) {
      canvas.drawCircle(Offset(lm.x * size.width, lm.y * size.height), 2, paint);
    }
  }
  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

Official package resources