flutter-pi: running Flutter on Raspberry Pi without a display server
A light-weight Flutter Engine Embedder for Linux Embedded that runs without X11 or Wayland.
At a glance
- What is it?
- flutter-pi is a Flutter Engine Embedder written in C that lets a Raspberry Pi or similar ARMv7/ARMv8 board run Flutter from a bare console with no X11 or Wayland required. Every Flutter plugin that includes native code needs its own C platform port before it will work on this embedder.
- Who is it for?
- flutter-pi fits a single-app kiosk or digital signage board on a Pi 2, 3, 4, or Pi Zero 2 W where you control the full plugin surface. Engineers with Linux build experience will find the CMake process manageable, and the flutterpi_tool on pub.dev reduces the app bundle step considerably.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 21 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 6, 2026, and from our analysis. They are not legal advice.
Editorial analysis
KMS and DRI direct rendering take the place of X11 and Wayland
Standard Linux graphics run through a display server: X11 or Wayland handles DRM calls, composites windows, and exposes an API to client applications. flutter-pi skips that layer entirely. It speaks directly to the kernel-modesetting (KMS) subsystem and the direct rendering infrastructure (DRI), giving the Flutter engine access to the display without any other process in between.
This design carries a hard requirement: no other process may be using the video output when flutter-pi starts. A running desktop environment claims the output first and blocks the embedder from claiming it. There is no co-existence mode. The project therefore requires booting into a console rather than a desktop environment.
Mesa provides the OpenGL ES and EGL implementation that flutter-pi links against. libdrm and libgbm are required alongside it. Boards using non-Mesa GPU stacks fall outside tested configurations; no such setup is documented as working.
Removing the display server costs you multi-window compositing and the ability to run other GUI applications alongside your Flutter app. On a Pi with limited RAM, such as a 512MB model, that tradeoff is what makes the approach sensible for dedicated use cases like kiosks and information displays.
Pi Zero (original) and Pi 1 are explicitly unsupported
flutter-pi requires hardware 3D acceleration, specifically KMS and DRI. The original Pi Zero and Pi 1 do not have GPUs that meet this requirement. Pi Zero 2 W is on the known-working list, and Pi 2, Pi 3, and Pi 4 (including 512MB variants) are confirmed. The project is only tested on a Raspberry Pi 4 2GB, so results on other boards fall to you to verify.
For boards beyond Raspberry Pi, the requirement is architecture-based: ARMv7, ARMv8, x86 and x86 64bit are claimed to work, subject to the KMS/DRI condition. The Linux embedded topics in the repository metadata confirm that Raspberry Pi is not the only intended target.
The V3D driver situation differs by OS version. On a Raspberry Pi 4 running Raspbian Bullseye, the V3D driver is the default and the driver configuration step in raspi-config can be skipped. On older setups, you use raspi-config to select GL (Fake KMS) under Advanced Options. The old broadcom-proprietary GL driver is documented as broken with Flutter.
GPU memory allocation is set under Performance Options in raspi-config. A value of 64MB is the documented setting, with 16MB noted as an alternative that also works. This allocation exists because KMS needs some GPU-side memory, and the default may be insufficient on some Pi generations.
Building from source: apt dependencies, CMake, and a font cache step
flutter-pi ships no binary package. Building it directly on the Pi starts with installing development headers:
sudo apt install cmake libgl1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdrm-dev libgbm-dev ttf-mscorefonts-installer fontconfig libsystemd-dev libinput-dev libudev-dev libxkbcommon-devDespite sharing a name prefix with the init system, libsystemd is a separate utility library; within flutter-pi it supplies the event loop and a dbus connection, not process supervision. The Arial font (ttf-mscorefonts-installer) is required because the Flutter engine depends on it and it does not ship with Raspbian by default. After installing packages, update the font cache:
sudo fc-cacheWith dependencies in place, clone the repository and build:
git clone --recursive https://github.com/ardera/flutter-pi
cd flutter-pi
mkdir build && cd build
cmake ..
make -j`nproc`The --recursive flag is necessary because flutter-pi uses git submodules. Running make with -j`nproc` uses all available CPU cores, which matters on a Pi where a single-threaded build takes much longer. After compilation completes:
sudo make installTo update an existing installation, the documented procedure is `git pull && git checkout origin/master` followed by the compile steps again from step 2.
Console mode and render group permissions are required before the first launch
Two configuration steps on the Pi side are required before flutter-pi can open the display. First, switch the Pi to boot into console mode. In raspi-config, the path is System Options -> Boot / Auto Login, and you select Console or Console (Autologin). This step cannot be skipped: the display server that a desktop environment starts will claim the video output before flutter-pi gets to it.
Second, grant the pi user access to 3D acceleration:
usermod -a -G render piAdding a user to the render group carries security implications that the project documentation flags explicitly. Running flutter-pi with sudo is the documented alternative when that tradeoff is unacceptable. Both paths achieve the same result from the embedder's perspective.
On older Pi setups that are not running Raspbian Bullseye on a Pi 4, you also need to enable the V3D driver through raspi-config at Advanced Options -> GL Driver -> GL (Fake KMS). After making these changes, a reboot is required.
Running a Flutter app means passing the compiled app bundle to the flutter-pi binary. For building that bundle, the flutterpi_tool package on pub.dev is the current recommended approach, documented in the project's news section.
Plugins with native code require a manual C platform port
Flutter's plugin system separates pure Dart packages from plugins that include platform-specific native code. Pure Dart packages contain no native code and work under flutter-pi without modification. Plugins that include a platform side (shared_preferences is the example given in the project documentation) require that someone write and compile the C platform side for Linux before the plugin will function.
The project frames this as a theoretical possibility with a concrete caveat: building the C platform side for each plugin with native code is entirely the developer's responsibility. That framing is accurate. In practice, an app's compatibility depends entirely on whether its plugins have Linux support and whether that support compiles against what flutter-pi exposes.
For a kiosk or signage project where the plugin surface is small and under your control, this constraint is workable. For a production app with a wide plugin dependency tree, each third-party plugin with native code is a porting task before deployment can proceed. An audit of every plugin dependency, separating pure Dart packages from those with platform code, is the first real step in evaluating whether an existing Flutter app can run on flutter-pi without modification.
Optional GStreamer packages extend video and audio playback
Video playback via GStreamer requires a separate set of apt packages beyond the core build dependencies:
sudo apt install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly gstreamer1.0-plugins-bad gstreamer1.0-libav gstreamer1.0-alsaThis set covers the base, good, ugly, bad, libav and alsa plugin groups. GStreamer's architecture means codec support depends on which plugin packages are installed: a video file in a format not covered by the installed plugins will not play. The specific codecs your content uses determine which plugin groups you actually need.
The project's README table of contents also lists audioplayers as a separate component with its own section. The source material does not include the full content of that section, so the specific setup steps for audioplayers are not documented here. The table of contents entry suggests it has its own configuration requirements.
Neither the GStreamer video player nor audioplayers are required for a basic Flutter UI. They become relevant when the Flutter application includes video playback or audio output beyond simple system sounds.
MIT licence, version 1.1.1, and an experimental sentry plugin
The project is MIT-licensed. The LICENSE file sits at the repository root. Version 1.1.1 was released on 2026-01-31, following 1.1.0 on 2025-03-21 and 1.0.0 on 2024-06-08. The last push to the repository was on 2026-09-17.
A not-complete sentry plugin for crash reporting is documented on the project wiki at https://github.com/ardera/flutter-pi/wiki/Sentry-Support. The news section of the README marks it explicitly as not complete, which is the qualification to hold onto before building a crash-monitoring workflow around it.
The repository also contains GETTING_STARTED.md at the top level, separate from the README, along with a .devcontainer configuration and CMakePresets.json. These suggest some structured development environment support exists beyond what the README covers.
Upgrading to a newer version of flutter-pi is a manual process: pull the new commit, run cmake and make again, then run sudo make install. No package manager is involved. Anyone pinning to a specific build must track the commit hash themselves, since the release history uses release branch tags rather than semver tags on the main branch.
Editorial conclusion
flutter-pi fits a single-app kiosk or digital signage board on a Pi 2, 3, 4, or Pi Zero 2 W where you control the full plugin surface. Engineers with Linux build experience will find the CMake process manageable, and the flutterpi_tool on pub.dev reduces the app bundle step considerably. Skip it if you need a Pi 1 or the original Pi Zero, if your app relies on third-party plugins with native code you have not ported, or if the display must coexist with other GUI processes. Before deploying, verify that your specific board has a working KMS/DRI driver, add the pi user to the render group, and test each plugin on the actual target hardware.
Frequently asked questions
What is flutter-pi?
flutter-pi is a Flutter Engine Embedder written in C that runs Flutter applications on Raspberry Pi and other Linux embedded boards without requiring X11 or Wayland. It communicates directly with the kernel via KMS and DRI.
Does flutter-pi work on the original Raspberry Pi Zero?
No. flutter-pi requires hardware 3D acceleration with KMS and DRI support, which the original Pi Zero and Pi 1 do not have. Pi Zero 2 W is on the known-working list.
How do I install flutter-pi?
flutter-pi has no binary package. You install its apt dependencies, clone the repository with --recursive, then build and install using cmake and make. The full dependency list and build steps are in the README.
Can I use Flutter plugins with flutter-pi?
Pure Dart packages work without modification. Plugins that include native platform code require you to build the C platform side yourself for Linux before they will function under flutter-pi.
Does flutter-pi support video playback?
Yes, through an optional GStreamer integration. Installing the GStreamer development packages alongside the core dependencies enables the video player. The README lists both a GStreamer video player and audioplayers as separate components.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ardera-flutter-pi)