Skip to main content

Raspberry Pi - Kiosk

Configure kiosk mode

Checked 7 Oct 2026 against Raspberry Pi OS 2026-10-06 (Debian 13 "Trixie"). Since the 2024-10-22 release, every Raspberry Pi model runs a Wayland desktop with the labwc compositor by default, and the Chromium package/command is now chromium (it used to be chromium-browser). The old X11 tools (xset, xdotool, unclutter, DISPLAY=:0) do not work on a default install. The old method is kept at the bottom under "Older Raspberry Pi OS (Bullseye / X11)".

Raspberry Pi OS no longer has a default pi user (removed in April 2022). Use the username you set in Raspberry Pi Imager and work in that user's home directory (~).

1. Base setup

Flash Raspberry Pi OS (64-bit) with Raspberry Pi Imager. In OS customisation set the hostname, username/password and Wi-Fi, and turn on SSH. Kiosk mode needs a Raspberry Pi 3 or newer with at least 1 GB RAM.

Change hostname if not already done

sudo hostnamectl set-hostname <new-hostname>
sudo reboot

Update the system

sudo apt update
sudo apt -y full-upgrade

2. Boot to the desktop with auto login (labwc)

sudo raspi-config
  • 1 System Options > S5 Boot → B2 Desktop
  • 1 System Options > S6 Auto Login → answer Yes to "automatically log in to the desktop"
  • 6 Advanced Options > A7 Wayland → W2 Labwc (already the default; older Bookworm images on Pi 4/5 used Wayfire, so switch them to labwc)

3. Turn off screen blanking

In sudo raspi-config: 2 Display Options > D2 Screen Blanking → No. (Desktop alternative: Control Centre > Display > turn Screen Blanking off.)

4. Install wtype (only needed to rotate tabs)

wtype is the Wayland replacement for xdotool. It simulates the Ctrl+Tab keypress.

sudo apt -y install wtype

5. Clear Chromium cache (optional)

rm -rf ~/.cache/chromium ~/.config/chromium

6. Start Chromium in kiosk mode from the labwc autostart file

mkdir -p ~/.config/labwc
nano ~/.config/labwc/autostart

Add these two lines (replace the URLs; use one URL and drop the second line if you don't need to rotate tabs)

chromium https://YOUR-URL-1 https://YOUR-URL-2 --kiosk --noerrdialogs --disable-infobars --no-first-run --enable-features=OverlayScrollbar --start-maximized &
~/switchtab.sh

The & at the end of the first line is required so the tab-switch script also runs. Flags: --noerrdialogs hides error dialogs, --disable-infobars hides info bars, --no-first-run skips the first-run screens, --enable-features=OverlayScrollbar uses overlay scrollbars, --start-maximized starts full screen.

7. Tab switch script (only for 2+ URLs)

nano ~/switchtab.sh

Paste the following in

#!/bin/bash
# Find Chromium browser process ID
chromium_pid=$(pgrep chromium | head -1)
# Check if Chromium is running
while [[ -z $chromium_pid ]]; do
  echo "Chromium browser is not running yet."
  sleep 5
  chromium_pid=$(pgrep chromium | head -1)
done
echo "Chromium browser process ID: $chromium_pid"
# Loop to send keyboard events
while true; do
  # Send Ctrl+Tab using `wtype` command
  wtype -M ctrl -P Tab -p Tab
  sleep 10
done

Make it executable (no sudo / 777 needed)

chmod +x ~/switchtab.sh

Firefox instead of Chromium (optional)

Use this as the first line of ~/.config/labwc/autostart instead of the Chromium line. If you also use switchtab.sh, change both pgrep chromium to pgrep firefox.

firefox --kiosk --private-window https://YOUR-URL &

8. Reboot

sudo reboot

The Pi should log in, start labwc and open the browser full screen. No systemd service is needed. The labwc autostart file replaces the old kiosk.service.

Mouse cursor

unclutter is X11-only and does nothing under labwc/Wayland. Run the kiosk without a mouse attached; plug one in only to dismiss cookie pop-ups, then unplug it. labwc 0.8.4 and newer (Trixie) also has a HideCursor action you can bind to a key in ~/.config/labwc/rc.xml; the cursor comes back when the pointer moves (see labwc-actions(5)).

Hardening (optional)

  • Use SSH keys and set PasswordAuthentication no in /etc/ssh/sshd_config.
  • Make the SD card read-only: sudo raspi-config → 4 Performance Options > P2 Overlay File System → Yes. Turn it off again before making changes or running updates.
  • Put the Pi in a case that blocks access to the USB ports.

Sources

Other community kiosk projects

https://reelyactive.github.io/diy/pi-kiosk/

https://github.com/debloper/piosk

Older Raspberry Pi OS (Bullseye / X11)

Legacy method. Only use it on Bullseye or older, or on a Pi switched to X11 (raspi-config > 6 Advanced Options > A7 Wayland > W1 X11, not recommended by Raspberry Pi). It depends on X11 tools and on the old chromium-browser command and pi user, so it does not work on a default Trixie or current Bookworm install.

Install the following

sudo apt install xdotool unclutter

Create a kiosk file

sudo nano /home/pi/kiosk.sh

Paste the following in for chromium

#!/bin/bash

xset s noblank
xset s off
xset -dpms

unclutter -idle 0.5 -root &

sed -i 's/"exited_cleanly":false/"exited_cleanly":true/' /home/pi/.config/chromium/Default/Preferences
sed -i 's/"exit_type":"Crashed"/"exit_type":"Normal"/' /home/pi/.config/chromium/Default/Preferences

#/usr/bin/chromium-browser --noerrdialogs --disable-infobars --kiosk https://www.raspberrypi.com/ https://time.is/London &
#/usr/bin/chromium-browser --no-sandbox --window-size=1024,768 --kiosk --window-position=0,0 https://hdrcameras.onling.com:5001/webman/3rdparty/SurveillanceStation/?launchApp=SYNO.SS.App.VideoViewerVue.Instance&SynoToken=W9ZwQIG7NiF1Q &
#/usr/bin/chromium-browser --window-size=1080,720 --kiosk --window-position=0,0 https://www.hammerdownrange.com/lobby/index.php &
/usr/bin/chromium-browser --window-size=1080,720 --kiosk --window-position=0,0 https://www.hammerdownrange.com/lineup/lineup.php &
 
while true; do
   xdotool keydown ctrl+Tab; xdotool keyup ctrl+Tab;
   sleep 10
done

Paste the following in for firefox

# Disable screen blanking and power management (X11 only)
xset s noblank
xset s off
xset -dpms

# Hide mouse cursor (X11 only)
unclutter -idle 0.5 -root &

# Optional: Clean any crash flags (Firefox is more forgiving, but harmless to keep)
sed -i 's/"exited_cleanly":false/"exited_cleanly":true/' ~/.mozilla/firefox/*.default*/prefs.js 2>/dev/null || true

# Launch Firefox in kiosk mode
# -kiosk          → Fullscreen kiosk (hides UI, prevents exiting easily)
/usr/bin/firefox --kiosk --private-window https://synology.onling.com/webman/3rdparty/SurveillanceStation/login.cgi?SynoToken=nQhMc44EQyoEpeg &

# Optional: Cycle tabs / refresh every 10 seconds (your original behavior)
# If you only have one URL, you can comment this out or change it to a refresh instead
while true; do
    # Send Ctrl+Tab to cycle tabs (if you open multiple tabs)
    xdotool keydown ctrl+Tab; xdotool keyup ctrl+Tab;
    sleep 10
done

Make it executable

sudo chmod +x /home/pi/kiosk.sh

Make a service file to auto startup

sudo nano /lib/systemd/system/kiosk.service

Paste the following in

[Unit]
Description=Firefox Kiosk Mode
After=graphical.target
Wants=graphical.target

[Service]
Type=simple
Environment=DISPLAY=:0
ExecStart=/home/pi/kiosk.sh
Restart=always
RestartSec=5
User=pi
WorkingDirectory=/home/pi

[Install]
WantedBy=graphical.target

Make it so it auto starts and start it

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