ESP32 Flappybird, or how to serve large websites from ESP32

Serve complex websites or webapps from a ESP32 module, is that even possible?

With the ESP32 module you can quickly and easily Encode and decode Base64 strings (what is Base64?). This can be achieved by integrating the external C-class base64.h.

This comes pre instsalled with ESP32 in Arduino IDE

Anyone who has ever programmed a web server in Arduino IDE, knows the pain and how ugly the whole thing gets quickly. Let’s look at the following example. This is the HTML-Code to display two buttons.

Good luck changing some html code here!

There has to be some solution to program whole webpage stuff outside of Arduino IDE and in the end copy it somehow to the ESP module.

The idea is to encode the whole website into a Base64 string and save it as a c++ string in Arduino IDE. If the website is requested from a client, the corresponding Base64 string is decoded and sent directly to the client.

Since the ESP32 is supporting hardware encoding and decoding of base64 strings through crypto, we should be able to do this quickly on the fly.

This has the advantage that we’re able to develop the website or webapp in parallel and e.g. if necessary, we can automatically convert the source into a Base64 code via a custom interface. From there you can integrate it into Arduino IDE. If changed, the files can be edited natively as HTML or JavasScript. You just have to replace the updated string in the Arduino IDE.

A quick test has shown that this works. Is this also possible for larger websites? To keep up the motivation we took an HTML5 game. The code comes from and has been adapted by us so that it can be delivered completely in one file. First of all, the following must be done:

  • Include all external CSS codes in the HTML page
  • Integrate all external Javascript files as inline Javascript via <script>…</script>
  • Convert all images to data-uris
  • Convert all audio files to data-uris

You can create data URIs online in various places, for example here:

At last, you have a single HTML file that contains all the elements of the website. We went ahead and encoded the whole website into a base64 string. Aaaaaand…. unfortunately, the test failed. Apparently the string is too long for ESP32 to encode it and the module resets after a crash. Too little RAM?

So back into the IDE and divide the code into smaller pieces. To be able to make changes easily in the future, the code is divided as follows:

jQuery is huge (123kB)! We could probably ditch jQuery for some vanilla javascript. But not for today, because size is, what we want. That’s why we divide jQuery into three parts.

Since the main.js file (which we renamed into game for convenience), also contains the audio files (+/- 10kB each), we unfortunately have to split this file as well.

The splitted files are all minimized (if not already done) . You can do taht easily in To do this, just type “js minifier” in duckduckgo and you will get a form where you can minimize the code:

The minimized code is then converted into a Base64 code. For example here:

Now the whole Base64 codes are stored as a string and decoded and served at the appropriate place in the program to the client.

Looks a lot neater, doesn’t it? And that’s all for a website with a size of about 500kB and over 50 files!

The finished code can be found on Github including the individual program parts:

You can load the ino-file via Arduino-IDE to your ESP32 module after you have adapted your wifi data accordingly. Or you can change the code so that you can access the ESP32 module directly with the wifi of your device. You either give your device the IP yourself via your network administration or it will be assigned automatically and is printed in the Arduino ide Serial Monitor. Now enter the IP in your browser and start playing!

Have fun playing!

Alternative Solution

With SPIFFS you can create a Filesystem on your ESP32 Modul and upload the HTML, CSS and JS files directly to it. Here’s an example on how to do this:

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

− 2 = 2