11. Output WebGL Content on a Screen

This tutorial shows how to install and modify a container that outputs web browser and webGL content.


The Arduino Portenta X8's processor NXP® i.MX 8M Mini Processor is capable of 3D rendering by using OpenGL to process the 3D-related calculations, allowing us to display 3D content on a screen or video output.

In this tutorial, we will render web content from the internet using WebGL and display it on a screen, using a USB Hub. We will go through the steps to set up, install and modify the video output.


  • Learn how to setup the Video Output
  • Learn how to get the required container
  • Learn how to run the container
  • Learn how to change the video output

Required Hardware and Software

  • Arduino Portenta X8
  • USB-C® cable (either USB-C® to USB-A or USB-C® to USB-C®)
  • USB-C® hub with HDMI
  • External monitor
  • HDMI cable


Install The Container

There are two ways to get the container, either through

or downloading the container from portenta-containers repository.

With Foundries.io:

If you use Foundries.io, you can switch the current

of your device to
by switching the app from a terminal on your computer:

1//Change the app to an existing one
2fioctl devices config updates --apps "x-kiosk-imx8-webgl" <deviceName> -f <yourFactoryName>
4//Make a clean installation with no containers
5fioctl devices config updates --apps "," <deviceName> -f <yourFactoryName>
7//If you are getting issues doing so, make sure you are logged correctly with your token
8//You can logout:
9fioctl logout
11//Then log in again and follow the instructions
12fioctl login

You will now see the home screen for a few seconds and then it will fade out and open the Aquarium 3D from WebGL samples - Aquarium.

With downloaded repository:

If you downloaded the portenta-containers repository, you will need to connect your board directly to your computer and run the

adb shell
, then push the container to your Portenta X8.

Connect to a Wi-Fi®

Check the available Wi-Fi® access points by using the

nmcli de wifi
command. You will be able to see an output laying out
, and its other elements.

1nmcli de wifi
5 AA:BB:CC:DD:EE:FF <yourAP-SSID> Infra X 130 Mbit/s -- * WPA2

The Wi-Fi® details can be saved using the following commands in sequence:

1nmcli c add type wifi con-name <customName> ifname wlan0 ssid <SSID>
2nmcli con modify <customName> wifi-sec.key-mgmt wpa-psk
3nmcli con modify <customName> wifi-sec.psk <PASSWORD>
4nmcli con up <customName>
6//To disconnect from a custom connection
7nmcli con down <customName>
9//To delete a saved connection
10nmcli c delete <customName>

If the LED is illuminating Green, then we know it has been correctly connected. If you want to check it in your terminal, you can use the following commands:

1nmcli de
5usb0 ethernet connected usbrndis
6usb1 ethernet connected usbecm
7wlan0 wifi connected <customName>
8docker0 bridge connected (externally) docker0

The output table will display information regarding active connections as well as the Wi-Fi® connection in which we are interested.

Get Your Board's IP

The IP information of the board can be obtained using

ifconfig wlan0
command. It will show different IP information composed of
, and

1ifconfig wlan0
4wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
5 inet <localIP> netmask broadcast <broadcastIP>

Test your IP connection by exiting the

adb shell
, you can use CTRL+Z or type
, then try to connect through SSH using following command:

1ssh fio@<localIP>

To connect through SSH it will request the user's password, which is "fio". If you have trouble connecting with the SSH, please check the troubleshooting section at the end of this tutorial.

Copy/Push the Docker-Compose.yml

You can push the docker-compose.yml, a file that describes the app in ASCII format, from your computer using a terminal on the file's directory. The following command is used to send the composer to the Portenta X8:

1scp <folderName> fio@<portentaX8-IP>:<desiredPath>

Video Output Setup

Now we need a USB Hub that has an available video output connector, for example, an HDMI cable. Connect the Portenta X8 to the USB Hub as a Host, the video connector to a display, and the power supply USB to your computer. It is optional but we could also connect a USB mouse to the hub. The setup should look like as follows:

X8 usb hub setup

As a reference, a list of validated USB-C® to HDMI hubs that you can use are: TPX00145 and TPX00146.

By default, if you connect the board to a display, you will see the "home screen" with the

Arduino PRO
background wallpaper, and a bottom bar with a real-time clock.

You can interact with the interface by plugging USB devices into your hub, like a mouse or a keyboard.

X8 home-screen
X8 home-screen

If you need to change the resolution of your display/monitor to improve the video output quality, you need to add a specific resolution to the configuration file of the graphical server (Weston on Portenta X8). To do so, you need to generate the right Modeline, i.e. a row that specifies a custom mode for the graphical interface to correctly drive the display.

In the next steps, we provide an example of a 1600 x 758 display running at 60Hz. If you need to modify the modeline and generate a new one, you can use

command, which is already installed in the Linux image running on your Portenta X8 (see here to get more information).

To get started in modifying the resolution of your display, connect to your Portenta X8 through ADB (check this link to learn how to do it).

At this point, you are ready to modify the

file with
command as follows:

1sudo vim /etc/xdg/weston/weston.ini

You can now add the following lines to the


3mode=98.00 1600 1680 1840 2080 758 761 771 787 -hsync +vsync

Save the file and exit. To see the changes in place, you have to reboot your Portenta X8 by using the command

sudo systemctl reboot
. When the board gets started again, you will be able to see your display with the right resolution.

Running The Image

If you obtained the app descriptor, structured through docker-compose.yml, from Foundries.io, it will run automatically after a few seconds.

On the other hand, if you copied from the repository, you will need to initialize with docker by accessing your Portenta X8 through SSH, going to the directory where you have copied it, and running it from that directory using following commands:

1//Connect to your device
2ssh fio@<portentaX8-IP>
4//Change directory
5cd <composerPath>
7//Compose with docker
8docker compose up --detach
10//Stop the docker-compose
11docker compose stop

Edit The Output

It is possible to change the web output URL by editing the

file, using the following commands:

1//Connect to your device
2ssh fio@<portentaX8-IP>
4//Change directory
5cd <composerPath>
7//Edit the file with VIM
8vim docker-compose.yml

Once you are inside the VIM editor, to edit the file you will need to press insert and replace the URL as shown in the screenshot.

VIM editing docker-compose.yml
VIM editing docker-compose.yml

To save the changes, press the ESC key and type

. This will write and quit the VIM editor. After editing the file, you will need to compose the container again to make the changes take effect.


In this tutorial, we went through how to connect the board and display something on a screen. Using a container from FoundriesFactories or by downloading it and uploading it to your Portenta X8. Lastly, we showed how to edit the video output by editing the container.

Next Steps

  • Make your own HTML content, push it to your device, and output the desired content.
  • You could make an app that shows information about the weather on the web and have that on a display.


  • If you tried to connect with
    and you get a fingerprint issue, you will need to remove the IP and fingerprint on your
    file. On Windows, the file is located at
    and try again with the ssh connection. An example is as follows:
1$portenta-x8: ssh-keygen -R <name or IP address of the host>

Suggest changes

The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.


The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.