How to Upload a Frontend to ESP32

Uploading code to an ESP32 microcontroller is not limited to firmware alone—you can upload almost any type of data, including frontend assets, to your microcontroller. Most tutorials focus on uploading firmware to a microcontroller, but what if you want to upload a website or frontend files instead? In this article, we will explore how uploading works in embedded systems and how to store and serve a frontend from an ESP32.

Before starting, make sure you have the necessary prerequisites for ESP32 development. In this guide, we use a combination of VS Code IDE, PlatformIO extension, and the Arduino framework.

What Does “Upload” Mean?

Uploading refers to transferring data into a microcontroller’s non-volatile memory, such as Flash, EEPROM, SPIFFS, or an SD card. Typically, we upload the firmware—the program code that the microcontroller executes—but you can also upload additional files, such as frontend assets, to the microcontroller.

ESP32 Memory Overview

ESP32 contains several types of memory:

  1. ROM: Read-only memory inside the chip containing system code provided by Espressif, typically around 448 KB.

  2. SRAM (RAM): On-chip memory for temporary data storage during program execution, approximately 520 KB.

  3. Flash: External memory connected via SPI, used for storing firmware, filesystem data, and other non-volatile information. Flash size varies between 1 MB and 16 MB depending on the module.

  4. RTC Memory: Small on-chip memory (about 8 KB) used to store data during deep sleep or for timer functionality

 
Flash Memory Partitioning

Before uploading your code, it is important to define how flash memory is partitioned. Flash memory is divided into several sections:

  1. Bootloader

  2. Partition Table

  3. Factory App

  4. OTA App

  5. NVS / EEPROM

  6. SPIFFS / LittleFS

The SPIFFS / LittleFS partition is a filesystem where user files, such as frontend assets, are stored. Both SPIFFS and LittleFS are types of file systems.

  • SPIFFS: Older filesystem, now deprecated.

  • LittleFS: Recommended modern filesystem, with real directory structures, better stability, faster performance, and more resistance to corruption.

To configure LittleFS in PlatformIO, set the following in your platformio.ini:

board_build.filesystem = littlefs
 board_build.filesystem_size = 2MB
 

This defines LittleFS as the filesystem and allocates 2 MB of flash memory for it.

Preparing and Uploading Frontend Files

When uploading frontend files, it is important to minimize their size to save microcontroller resources. At the beginning of development, choose the frontend technology carefully. For very small projects, writing raw HTML, CSS, and JavaScript without libraries can produce minimal bundle sizes.

For more advanced projects, frameworks are often necessary. Selecting a framework with a small output size is crucial. For example, Vue.js is lightweight, feature-complete, and works well with Tailwind CSS for styling. Using this combination without additional libraries, you can keep the bundle size under 100 KB.

After developing your frontend, build it in production mode. For Vue.js, run:

npm run build

This produces a dist folder containing index.html and an assets directory.

PlatformIO Filesystem Structure

 

In PlatformIO, the data/ directory corresponds to the microcontroller’s filesystem. Everything inside this directory will be uploaded to LittleFS. To upload:

  1. Upload firmware first:     pio run -t upload

or use the GUI upload button.

  1. Upload filesystem data:   pio run -t uploadfs

Note: Running uploadfs clears all existing data in the filesystem and transfers the contents of the data/ directory to LittleFS.

Serving Frontend Files on ESP32

Once uploaded, your files can be served from ESP32 using the ESPAsyncWebServer library. Here’s a minimal example to serve a frontend built with Vue.js:

 
				
					// main.cpp
#include 
#include 
#include "LittleFS.h"
#include 

AsyncWebServer server(80);

void setup() {
    LittleFS.begin(true);
    server.serveStatic("/", LittleFS, "/").setDefaultFile("index.html");
    server.begin();
}


void loop() {
    // Nothing needed here
}
				
			

Notes:

  • In Single Page Applications (SPA) like Vue.js, all routes must serve index.html for proper functioning.

  • Static files like CSS and JS are automatically served from LittleFS.

Additional Optimization

For better performance and lower memory usage:

  • Consider Gzipping frontend assets to reduce the transferred data size.

  • Minimize external libraries in your frontend bundle.

  • Optimize images and assets for embedded devices.

We plan to cover advanced optimization strategies in a follow-up article.

References

 
[1] ESP32 vs Code PlatformIO: Upload Files to Filesystem SPIFFS | Random Nerd Tutorials. 23 Dec. 2020, randomnerdtutorials.com/esp32-vs-code-platformio-spiffs
 
[2] Sanghvi, Yash. “How to Set Partitions in ESP32 – Iotespresso.com.” Iotespresso.com, 21 Apr. 2021, iotespresso.com/how-to-set-partitions-in-esp32/. Accessed 5 Nov. 2025.
 
[3] Input Data on HTML Form ESP32/ESP8266 Web Server Arduino IDE | Random Nerd Tutorials. 29 Aug. 2019, randomnerdtutorials.com/esp32-esp8266-input-data-html-form

دیدگاه‌ خود را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

پیمایش به بالا