Raspberry Pi Kiosk using Chromium

For this Raspberry Pi Kiosk tutorial, we will be showing you how you can set up your Pi as a Kiosk using the popular web browser, Chromium.

Raspberry Pi Kiosk

We utilize Chromium as it is one of the best-supported web browsers and openly supports the functionality to act in a kiosk mode.

It is also easy to control through key presses which we can simulate using the xdotool that we install during this guide.

This guide will give you a good idea on how to use autologin tasks and simple bash scripts to perform numerous tasks.

Please note to do this tutorial you will need to be running the full version of Raspbian as this relies on the GUI that comes with it to properly operate.

Equipment List

The entire list of all the pieces of equipment that we made use of for this Raspberry Pi Kiosk tutorial is listed below.



Video Tutorial

In this video, we show you the process of setting up your Raspberry Pi to operate as a Chromium powered kiosk as well as showing you how to get it to start at boot.

If you prefer a written and more thorough explanation, then check out our written guide below.

Adblock removing the video? Subscribe to premium for no-ads.

Setting up the Raspberry Pi Kiosk

1. Before we get started with this tutorial, we will be first removing some packages that we don’t need for our Raspberry Pi kiosk.

Removing these packages will free up some much-needed memory and reduce the number of packages that will be updated every time you update your Raspberry Pi.

To do this just run the following three commands on your Raspberry Pi. We have split these into three different commands to make them easier to copy and write out.

sudo apt purge wolfram-engine scratch scratch2 nuscratch sonic-pi idle3 -y
sudo apt purge smartsim java-common minecraft-pi libreoffice* -y

2. Now that we have removed these numerous packages from our Raspberry Pi Kiosk we will need to run some cleanup commands.

To remove any unnecessary lingering packages and to clean out the local repository of retrieved packages run the following two commands on your Raspberry Pi.

sudo apt clean
sudo apt autoremove -y

3. Now that we have removed the bulk of the unnecessary applications, we must now make sure that our installation of Raspbian is up to date. Also, make sure you have SSH enabled as it is very handy if you need to edit any files later on.

We can use the following two commands within the terminal on our Raspberry Pi to update all the packages to their latest versions.

sudo apt update
sudo apt upgrade

4. We now need also to install xdotool. This tool will allow our bash script to execute key presses without anyone being on the device. We also install the unclutter package, this will enable us to hide the mouse from the display.

Just run the following command on your Raspberry Pi to install the package.

sudo apt install xdotool unclutter sed

5. Now that those packages have been installed we can now proceed to the next stage of this tutorial. That is setting up Raspberry Pi OS to auto login to our user. Having to log in every time for a kiosk would be an annoyance.

Desktop autologin is the default behavior but if for some reason you have changed it follow the next few steps to switch it back. Otherwise, skip to step 6 of this tutorial.

5a. Run the following command on your Raspberry Pi to load up the Raspi-config tool. We will be using this tool to enable auto login.

sudo raspi-config

5b. Now within the tool go to 1 System Options -> S5 Boot / Auto Login -> B4 Desktop Autologin

5c. Desktop autologin should now be enabled and you can safely quit out of the raspi-config tool.

6. Now that we have enabled desktop autologin we need to go ahead and write our kiosk.sh script.

Writing the Raspberry Pi Kiosk Script

The kiosk script will handle the bulk of the work for our Raspberry Pi Kiosk, including launching Chromium itself and also simulating key presses.

1. Begin writing our kiosk bash script by running the following nano command on the Raspberry Pi.

nano ~/kiosk.sh

2. Within this file enter the following lines of code, we will explain the important parts of the script so you can better bend it to your needs.


The very first line defines what the command line interpreter (CLI) should use to try and execute this file.

This is useful for cases where you don’t want to have to specify the specific application required every time you run the script.

xset s noblank
xset s off
xset -dpms

These three lines are pretty important as they help us stop the Raspberry Pi’s display power management system from kicking in and blanking out the screen.

Basically, these three commands set the current xsession not to blank out the screensaver and then disables the screensaver altogether.

The third line disables the entire “display power management system” meaning that the desktop interface should never blank out the screen.

unclutter -idle 0.5 -root &

This line runs the program we installed earlier called unclutter.

This application will hide the mouse from the display whenever it has been idle for longer then 0.5 seconds and will remove it even if it is over the root background.

You can adjust the idle timer to the number of seconds you want with each decimal place being a fraction of a second.

If you would prefer to remove the mouse instantly, then remove the -idle 0.5 from the  command.

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

These two lines of the script use sed to search through the Chromium preferences file and clear out any flags that would make the warning bar appear, a behavior you don’t really want happening on your Raspberry Pi Kiosk.

If Chromium ever crashes or is closed suddenly, the lines above will ensure you don’t have to get hold of a mouse and keyboard to clear the warning bar that would typically appear at the top of the browser.

/usr/bin/chromium-browser --noerrdialogs --disable-infobars --kiosk https://pimylifeup.com https://www.adafruit.com &

This line launches Chromium with our parameters.

We will go through each of these parameters so you know what you can modify, and how you can modify it.


This flag sets Chromium to operate in Kiosk mode, this locks it into a particular set of features and only allows limited access to both the web browser and any other OS functionality.

Chromium’s kiosk functionality takes full control of the screen, maximizing Chromium to the full size of your screen and stops user input from being accepted by the OS, effectively trapping the end user within a sandbox.


This option tells Chromium that it should not display any of its error dialogs to the end user.

It is crucial if you don’t want the end user to know if anything has or is going wrong with Chromium, this goes alongside our code to clear the “exited_cleanly” and “exit_type” state earlier in the code.


We use this to disable Chromium from displaying its info bar to the end user.

The info bar can be used by Chromium to notify them of certain things such as that Chromium is not their default web browser.

Of course, as we are using this as a kiosk, we don’t need the user to know any information that Chromium might want to display.

https://pimylifeup.com https://www.adafruit.com

These are the two web pages that the script will open, each will be opened in a new tab.

You can add additional web pages/tabs by adding to this list by separating each one with a space.

while true; do
         xdotool keydown ctrl+Next; xdotool keyup ctrl+Next;
      sleep 15

These lines run a very simple infinite while loop that uses xdotool to mimic pressing CTRL + Pgdn. Making Chromium switch to the next tab. “Next” is a alias for the “PG DN” key.

After xdotool has executed its key presses, it then puts the loop to sleep for 15 seconds.

To change how long the loop sleeps for before it executes the xdotool command again just change the sleep 15 command.

You can also use this method to add a screen refresh, this may be important when you want to display live scores.

The command for this should look something like what we have shown below.

xdotool keydown ctrl+r; xdotool keyup ctrl+r;

3. Once you have entered all the code for our Raspberry Pi kiosk script, it should look somewhat similar to what we have displayed below.

xset s noblank
xset s off
xset -dpms

unclutter -idle 0.5 -root &

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

/usr/bin/chromium-browser --noerrdialogs --disable-infobars --kiosk https://pimylifeup.com https://www.adafruit.com &

while true; do
   xdotool keydown ctrl+Next; xdotool keyup ctrl+Next;
   sleep 10

4. Once you are sure everything is correct, save the file by pressing CTRL + X then Y and finally ENTER.

5. After creating this script we should make sure that our user has execution privileges for it.

You can give the user that owns the script execution privileges by running the following command.

chmod u+x ~/kiosk.sh

Setting up the Raspberry Pi Kiosk to start at boot

1. Before we get started we need to first utilize the following command to work out what the current display value is.

This value is used for the operating system to know what screen to display the Chromium kiosk to, without it the kiosk will either fail to load or load up on the incorrect screen.

Run the following command to print out the value of the “$DISPLAY” system variable. This command must be run directly on your Raspberry Pi and not over SSH.


Make sure you remember this value as you may need it in step 3 of this section.

2. To get our Raspberry Pi Kiosk to start at boot we will need to go ahead and create a service file by running the command below.

This service file will tell the operating system what file we want to be executed as well as that we want the GUI to be available before starting up the software.

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

3. Within our kiosk service file, enter the following lines of text.

These lines are what will define our service kiosk service, and that we want to run our kiosk.sh script when the system loads into the operating system.

While entering these lines you may have to modify the “Environment=DISPLAY=:” line, replacing the “0” with the value that you retrieved from the command you used in step 1 of this section.

Additionally, you will need to make sure you replace “pi” with the name of your user. For example, with the username “pimylifeup“, the path “/home/pi/kiosk.sh” would become “/home/pimylifeup/kiosk.sh“.

Description=Chromium Kiosk

ExecStart=/bin/bash /home/pi/kiosk.sh


Once you have entered everything into the file, save the file by pressing CTRL + X followed by Y then ENTER.

4. Now that we have created the service file for our Raspberry Pi Kiosk we can go ahead and now enable it by running the following command.

By enabling the service, we will allow our Chromium Kiosk to start up at boot automatically and will enable the systemd to service manager to monitor it.

sudo systemctl enable kiosk.service

5. With the Kiosk service now enabled you can either choose to restart the Raspberry Pi or start the service now by running the following command.

sudo systemctl start kiosk.service

6. If you ever want to check the status of your Raspberry Pi Kiosk’s service, you can run the command below.

This command will return various information about the service, including previously returned lines from the software which can help you debug what’s going wrong when the service is failed.

sudo systemctl status kiosk.service

If this command shows the status as “Active: active (running)” then everything is now working as it should be, and your Raspberry Pi Chromium Kiosk should be up and operating correctly.

7. Now with everything up and running correctly, if there is for any reason you want to stop the service from running, you can utilize the following command.

sudo systemctl stop kiosk.service

By stopping the kiosk service, the service manager will kill off all processes associated with it.

This command will stop our kiosk.sh script from running while also terminating the open Chromium browser.

8. Finally, if you ever want to disable your Kiosk, you can utilize the following command.

sudo systemctl disable kiosk.service

This command will stop the Kiosk service from running on boot until you re-enable it.

Enforcing the Resolution on a Raspberry Pi Kiosk

1. One thing you might want to do is to enforce the resolution that the Raspberry Pi is going to use. Setting the resolution can be quite handy as the Raspberry Pi’s built-in detection can sometimes be a bit flakey.

To begin setting the resolution, we must first load up the Raspberry Pi configuration tool by running the following command.

sudo raspi-config

2. Within the configuration tool, you will want to start by going to “7 Advanced Options“.

3. Now that we are in the advanced options section you should see an option labeled “A5 Resolution” select that option.

4. Within here find and select the resolution that best fits your screen and press ENTER.

5. With your resolution now set you will need to restart the Raspberry Pi. Do this by first exiting out of the configuration tool by pressing ESC, then entering the following command into the Raspberry Pi’s terminal.

sudo reboot

6. Your Raspberry Pi should now restart and be running at the specified resolution.


There are so many ways you can extend this tutorial. For example, you can set up a web server on the Raspberry Pi and have it serve local web pages to be displayed on your Kiosk.

It’s perfect if you want the results of a competition or basically any other sort of information you want to be displayed.

By now you should have your Raspberry Pi successfully booting into the Kiosk mode of Chromium. If you have any issues with this Raspberry Pi kiosk tutorial or want to leave feedback, then feel free to leave a comment below.


  1. Avatar for Michael
    Michael on

    The kiosk works great following your tutorial. However, when I change the URLs, it breaks the kiosk and displays a white background.

    1. Avatar for Emmet
      Emmet on

      Hi Michael,

      That doesn’t seem quite right.

      Can you ensure that the URL’s that you are utilizing loads normally outside of the kiosk mode?


  2. Avatar for Stefan
    Stefan on

    Hello there,

    I had some trouble using the service (which caused chromium not to start on reboot).

    A sudo +x kiosk.sh helped here…. just if you happen to need it.


  3. Avatar for Skipman
    Skipman on

    Hi great Tutorial.
    My Problem was that my ioBroker VIS would not open on reboot.
    In the logs I found someting about Chromion starting as root without a sandbox.
    After some searching I added –no-sandbox to the Kiosk.sh file and now it works.

    /usr/bin/chromium-browser --no-sandbox --noerrdialogs --disable-infobars --Kiosk

    Thanks for the great Tutorial


  4. Avatar for benjamin
    benjamin on

    Hello from france !

    this work great now… I had some issues in January and change a lot of things for that the raspberry pi can work… but now … It’s ok right after doing all your stuff !

    I have install a web server and can now put everythings I want when I want.

    I will change the way I use it by using an external webserver because I’m using now 2 display in 2 differents places.

    Thanks a lot for your Tuto, it help me a lot to make that I want to !



  5. Avatar for Max
    Max on

    Hi Emmet,

    First, thanks alot for this article!

    Followed step by step, but can’t make it work.

    I did all the installation from SSH.

    When I enter this command :

    sudo systemctl status kiosk.service

    Its return :
    ● kiosk.service – Chromium Kiosk
    Loaded: loaded (/lib/systemd/system/kiosk.service; enabled; vendor preset: en
    Active: inactive (dead) since Sun 2019-04-14 19:42:08 EDT; 3min 55s ago
    Process: 531 ExecStart=/bin/bash /home/pi/kiosk.sh (code=exited, status=0/SUCC
    Main PID: 531 (code=exited, status=0/SUCCESS)

    Apr 14 19:42:08 raspberrypi systemd[1]: Started Chromium Kiosk.

    At some point, I also had this error in the log :
    Invalid MIT-MAGIC-COOKIE-1 keyxset: unable to open display “:0”

    1. Avatar for Emmet
      Emmet on

      Hi Max,

      Im assuming your Raspberry Pi was connected to a display upon running the command?

      There is a chance that your display for some reason is not sitting on the typical :0 interface, which i may have to look into dealing with cleaner.


    2. Avatar for Harald Prior
      Harald Prior on

      HI Emmet,
      I already submitted a comment but it does not appear here. I have a similar problem like Max. The service won’t start up. Starting the kiosk.sh manually (after chmod +x) works after I added “export DISPLAY=:0” in the first line of the script. But the service for automatic start is not working at all. The screen was already connected from the very beginning, it’s an ELO touch (touch is working btw).
      Is there anything I can try?

    3. Avatar for Emmet
      Emmet on

      Hi Harald,

      Can you try running the following command on your Raspberry Pi thats connected to the screen and reply with your result. If possible do this physically on the device and not over SSH.

      echo $DISPLAY

      The only reason it should be failing is if for some reason it is failing to access the display, typically this should sit on :0 but that may not always be the case.

      I am unable to reproduce any of the issues which does make it harder to work out what could be going wrong.


    4. Avatar for Manuel Rendon
      Manuel Rendon on

      I had to change ‘Type =simple’ to ‘Type=forking’ in my systemd kiosk.service file

    5. Avatar for Daniel C
      Daniel C on

      Thank you Manuel Rendon, changing the type from type=simple to type=forking resolved this issue for me!

    6. Avatar for Tristan ter Haar
      Tristan ter Haar on

      Hello there, you could also add this line to the end of /etc/xdg/lxsession/LXDE-pi/autostart:

      /bin/bash /home/pi/kiosk.sh

      And then disable the service you created.
      (sudo systemctl disable kiosk.service)

      The reason you experience these issues is because the kiosk service is called BEFORE the X11 (display service) is initialized.
      By including the line in the autostart file, you let X11 start the script for you. This in turn ensures you that X11 is up and running!

  6. Avatar for Kamran
    Kamran on

    I just have one url I want to display. The website/url already has auto refresh built in to the module OF the site so I do not need to refresh it. What do I need to change in order for this to work with 1 tab or URL and no refreshing?

    Thanks for the great tutorial

    1. Avatar for Gus
      Gus on

      Hi Kamran,

      You should only need to remove the following code. By default, the script shouldn’t be refreshing pages.

      while true; do
         xdotool keydown ctrl+Tab; xdotool keyup ctrl+Tab;
         sleep 10
    2. Avatar for Kamran Qadir
      Kamran Qadir on

      Thank you for answering my question about the loop

      Now, I am randomly getting a 504 Gateway error also, that was before the loop and after…

      I am not sure how to troubleshoot this. any steps would be helpful. Thanks

    3. Avatar for Emmet
      Emmet on

      Hi Kamran,

      A 504 Gateway error reflects an issue with the webpage that you are attempting to connect to.

      We are simply loading the Chromium browser in kiosk mode and loading new windows in it.
      Any errors like that is likely issues unrelated to the browser itself.


  7. Avatar for Logan
    Logan on

    Is there a way to change the webpage being shown? This works outside of kiosk mode by opening a new tab, but it doesn’t seem to function correctly in kiosk mode.

    1. Avatar for Gus
      Gus on

      Hi Logan,

      On startup, you can specify as many webpages as you want to load. These webpages should load in new tabs. Alternatively, you can use the xdotool to run some hotkeys to open up a new tab and webpage.

  8. Avatar for Anna
    Anna on

    Hi! I got this to work and it works wonderfully, thank you!
    My problem is that the website I want to show has a slideshow and its displayed really buggy. Is there a known workaround for this? I am new to Rpi so I’m thinking maybe I’m missing something.

    I have increased GPU and enabled flags in chromium and done everything I can think of but nothing works. Youtube works well but not this slideshow on my wordpress site with elements moving in and out of frame.

    1. Avatar for Gus
      Gus on

      Hi Anna,

      Out of curiosity, does the slideshow break when you load it in Chromium with both the kiosk mode and the xdotool disabled?

      You may need to adjust the resources for the Raspberry Pi. You can give the GPU more memory by loading up raspi-config and then going to Advanced options->Memory Split.

      Hope that helps!

  9. Avatar for Nick
    Nick on

    Neither work for me either. Strange.

    1. Avatar for Emmet
      Emmet on

      Hi Nick,

      Is that the issue of not being able to have the kiosk start on boot?

      We have come up with a more elegant solution that should definitely work, we will be putting it up a bit later when we have time to write it up.

      Hopefully within the next 8 hours as have a few things going on today.


    2. Avatar for Emmet
      Emmet on

      Hi Nick,

      We have now updated the tutorial to make use of a service file instead.

      Let us know if this fixes your issue.


  10. Avatar for Jonathan William
    Jonathan William on

    I tried this tutorial, and after the rasperry pi reboots, nothing happens. the pi boots right back to the desktop.

    I use a touchscreen display and the code from github https://github.com/goodtft/LCD-show.git

    does the touchscreen display and code incompatible with the steps shown in the tutorial?

    Thank you

    1. Avatar for Emmet
      Emmet on

      Hi Johnathon,

      It appears as if a few people are running into issues with the Chromium Kiosk booting at launch, we will look into this and comment again once we have resolved the issue people are running into.


    2. Avatar for Emmet
      Emmet on

      Hi Johnathon,

      We have just updated our Raspberry Pi Kiosk tutorial so it is automatically started up by a service instead, this change should fix your issues.


    3. Avatar for Jonathan William
      Jonathan William on

      The tutorial worked beautifully !

      Thank you

    4. Avatar for GazZebo
      GazZebo on

      Check the chromium executable is called chromium-browser,

      If it isn’t create an alias or edit the kiosk.sh

      On my x86 raspberry pi ISO i installed on a hyper-V virtual machine the chromium executable was just called ‘chromium’ and not chromium-browser.

  11. Avatar for Anna Furberg
    Anna Furberg on

    I am completely new to raspberry pi and I followed this tutorial really carefully but after rebooting nothing happened. It just starts with the desktop, no window open, it still goes to screensaver if left alone for a while. Do you have any idea what i might have done wrong?

    1. Avatar for Emmet
      Emmet on

      Hi Anna,

      I have just made a change to the tutorial that should improve the whole reboot process. This additional process will make use of a service file instead of modifying the LXDE autostart.


  12. Avatar for Liviu B
    Liviu B on

    Do you think this would work with a Raspberry Pi Zero W?

    1. Avatar for Gus
      Gus on

      It should work, the only thing that might be an issue is the performance.

    2. Avatar for Liviu B
      Liviu B on

      You’re right. I did it yesterday night and it’s extremely slow. Especially since I’m using kiosk to run animated GIF’s from a website. It works a bit faster when I’m closer to the wifi router, but it’s not seamless at all and has moments when the GIF looks rather like a still image.
      However your script and commands are working perfectly, thanks a lot. They are extremely helpful and I like that you explained each command line, especially as a total beginner like me.
      Moving forward I was thinking to try using a different OS, maybe Chromium OS. A bigger Raspberry is not do-able as a small size is very important to my project and I don’t want to have an LCD display any bigger than 2.8″ (currently using the PITFT 2.2″).

  13. Avatar for Earlo
    Earlo on

    Great tutorial for a novice like me. Im using it to display two weather pages. One from weather underground and the other a full screen radar. I do have a small issue, the second page requires a refresh because “my session timed out”. THe code above doesn’t work well with the first page. Is there and code to refresh only the second page? If not, no worries. Thanks again for the tutorial.

    1. Avatar for Gus
      Gus on

      Probably a better way to implement this but here is a quick suggestion.

      In my example, we add a count, if the modulus returns 0 then we’re on our second tab, we then perform a simple refresh.

      count = 0
      while true; do
         xdotool keydown ctrl+Tab; xdotool keyup ctrl+Tab;
         count=$($count + 1)
         if [ $($count % 2) = 0]; then
             xdotool keydown f5; xdotool keyup f5;
         sleep 10

      I haven’t tested this but in theory it should work.

    2. Avatar for Earlo
      Earlo on

      Thanks Gus will give it a try this weekend

  14. Avatar for Davide
    Davide on

    I have no lxsession folder inside .config
    How can i do? What i do wrong ?


    1. Avatar for Gus
      Gus on

      Hi Davide,

      We have updated the tutorial with a new location for lxsession as it was recently changed.

  15. Avatar for Andy Tincknell
    Andy Tincknell on

    What xdotool command (or other command) would we use to return to the homepage after perhaps 5 minutes of inaction. In other words, on my kiosk I want them to be able to visit sub-pages using links, but if they haven’t done anything after 5 minutes, I want it to return to the home screen for the next user.

    1. Avatar for Gus
      Gus on

      I haven’t tested this, but a common solution on the internet is to use the xprintidle package.

      sudo apt-get install xprintidle

      You should then be able to reference it in the bash script like as followed.


      I hope this helps, or at the very least puts you on the right track.

  16. Avatar for Alberto
    Alberto on

    Thank you very much for this guide.
    I followed all the steps but at number 10 I’m not able to modify the file /home/pi/.config/lxsession/LXDE-pi/autostart because the directory “lxsession” does not exist.
    I’m using Raspbian full version (Stretch with desktop, release date 2018-11-13).
    I will appreciate your help
    Many Thanks

    1. Avatar for Gus
      Gus on

      Hi Alberto,

      The location for lxsession changed recently. We have now updated the tutorial so it should now reference the correct location.

  17. Avatar for Erik
    Erik on

    Hi, great guide, you made my day!
    Just a little correction with the “lxsession autostart” path, with the last updates is changed from;



    1. Avatar for Gus
      Gus on

      Thanks Erik for the fix! We updated the tutorial with your suggested change.

  18. Avatar for Andrew
    Andrew on

    I have followed this guide as we are looking for a low cost way of running a machine in Kiosk mode. However, there doesn’t appear to be any way to control the browser in terms of going back to the previous page or returning to the home screen. I have missed something or is this how it was designed?

    1. Avatar for Gus
      Gus on

      This is how it was designed, you will need to rewrite a lot of the tutorial to achieve what you’re after. Not using unclutter and removing the –kiosk will get more to what you’re after but essentially all it will be doing is loading the browser automatically.

  19. Avatar for jrperry
    jrperry on

    Look for chrome ungoogled. Some went through the source and took out all the hooks.

  20. Avatar for Bonzadog
    Bonzadog on

    Very interesting. But I will not use google products due to their robust data collection methods.
    But it must work with other browsers.

    1. Avatar for Gus
      Gus on

      I can understand that.

      The same method should work with most other browsers. However, I haven’t tested it with anything other than Chromium.

Leave a Reply

Your email address will not be published. Required fields are marked *