Flutter on Raspberry Pi: Building High-Performance Kiosks (No Electron)

I recently audited a fleet of digital signage devices running a React/Electron stack on Raspberry Pi 4s. The result? Constant overheating, memory leaks, and a sluggish 24 FPS UI. We ripped out the web stack and replaced it with Flutter.

The outcome was immediate: RAM usage dropped from 600MB to 80MB, and animations hit a locked 60 FPS. If you are building an embedded kiosk, stop treating it like a web browser. Here is how to run Flutter directly on the metal using DRM/KMS.

Why Flutter Beats Qt and Electron on Embedded

The traditional "Write Once, Run Anywhere" dream often turns into "Debug Everywhere" when dealing with low-power ARM chips. Electron is a resource hog, and Qt (while powerful) has a steep licensing and C++ learning curve. Flutter strikes the perfect balance.

Metric Electron (Web) Flutter (Embedded)
Cold Boot Time 15s - 25s 2s - 4s
RAM Footprint ~400MB+ ~60MB - 90MB
Rendering DOM/CSS Overhead Skia/Impeller (Direct GL)

For this guide, we aren't using a desktop environment (GNOME/Pixel). We are using flutter-pi, a lightweight embedder that runs Flutter directly on the Linux Direct Rendering Manager (DRM) and Kernel Mode Setting (KMS). This bypasses the X11/Wayland compositor entirely for raw performance.

The Implementation: Bare Metal Kiosk

Start with a fresh image of Raspberry Pi OS Lite (64-bit). Do not install the desktop version; we need every CPU cycle.

Pro Tip: Ensure your GPU memory split is sufficient. In /boot/config.txt, set gpu_mem=128 to give the Flutter engine breathing room for texture uploads.

1. Installing the Embedder

First, install the necessary dependencies for hardware acceleration. We need generic graphics drivers and the font configuration.

sudo apt update && sudo apt install -y \
  cmake libgl1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev \
  libdrm-dev libgbm-dev fontconfig libsystemd-dev \
  libinput-dev libudev-dev libxkbcommon-dev

2. Building the App for ARM64

You cannot simply flutter run on the Pi. You must build an Asset Bundle on your host machine (Mac/Windows/Linux) and transfer it.

# On your Host Machine
# Build specifically for the linux-arm64 target architecture
flutter build bundle --release

# Transfer to the Raspberry Pi (assuming IP is 192.168.1.50)
scp -r build/flutter_assets pi@192.168.1.50:/home/pi/my_kiosk_app

Auto-Booting into Kiosk Mode

A true kiosk shouldn't show a login prompt. We use systemd to launch the Flutter application immediately after the network stack initializes. This is more reliable than using .bashrc or cron.

Warning: If your app crashes in a loop, you might lose SSH access if the CPU is pegged. Always keep SSH enabled and test manually before enabling the service.

Create the service file: /etc/systemd/system/kiosk.service

[Unit]
Description=Flutter Kiosk Service
After=network.target

[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi
# -r 90 rotates the screen 90 degrees if you have a vertical kiosk
ExecStart=/usr/bin/flutter-pi --release -r 90 /home/pi/my_kiosk_app
Restart=always
RestartSec=5s

[Install]
WantedBy=multi-user.target

Enable it with:

sudo systemctl enable kiosk.service
sudo systemctl start kiosk.service

Handling Touch and Inputs

The raspberry pi touchscreens (official 7" or HDMI variants) usually expose input events via /dev/input/event*. Flutter-pi automatically detects these, but permissions can be tricky.

If touch isn't working, ensure the pi user is part of the input and video groups:

sudo usermod -a -G render,video,input pi

Conclusion

By leveraging Flutter's Skia engine directly on DRM/KMS, we transform the Raspberry Pi from a hobbyist toy into a production-grade industrial controller. You gain the developer experience of hot-reload (during dev) and the runtime performance of native C++ code.

Stop over-engineering with web wrappers. The future of embedded UIs is compiled, lightweight, and hardware-accelerated.

Post a Comment