LogicLab Pro on ESP32 A developer released LogicLab Pro on ESP32, a project that hosts a complete digital logic circuit simulator with an AI-assisted chat panel directly on an ESP32 board, served to any browser on the same Wi-Fi network. The web app's single-file HTML, 127,930 bytes uncompressed, is gzipped to 32,125 bytes, converted into a C array, stored in flash with PROGMEM, and streamed by the ESP32's built-in WebServer with a Content-Encoding: gzip header so the browser decompresses it. The sketch relies only on the WiFi, WebServer and ESPmDNS libraries from the ESP32 Arduino core, and a Python script, tools/embed_html.py, regenerates the index_html.h header after any HTML edit. Most ESP32 web projects serve a small control page with a few buttons. In this project I pushed that idea further: the ESP32 hosts LogicLab Pro , a complete digital logic circuit simulator with an AI-assisted chat panel. Anyone on the same Wi-Fi network can open the ESP32's address in a browser and start building and testing logic circuits on a phone, tablet or PC. The interesting part is how the web app gets onto the chip. The original single-file HTML app is about 128 KB. I compress it with gzip about 32 KB , convert it into a C array, store it in flash with PROGMEM, and let the ESP32's built-in WebServer send it with a Content-Encoding: gzip header. The browser decompresses it, so the page loads quickly and the ESP32 does no compression work at runtime. - One file to deploy. The whole web app lives inside the sketch. There is no filesystem to upload and no SD card to manage. - Small footprint. Gzip cuts the app from 127, 930 bytes to 32, 125 bytes. - No third-party libraries. The sketch uses only WiFi , WebServer and ESPmDNS , which ship with the ESP32 Arduino core. - Easy to update. Edit the HTML, run one Python command, re-upload. - logiclab pro v2.html is the original, unmodified web app. - tools/embed html.py gzips it and writes index html.h , a C header holding the bytes as a PROGMEM array. - The sketch connects to your Wi-Fi or starts its own access point as a fallback . - When a browser requests / , the ESP32 streams the gzip bytes with the right headers. - The browser unpacks the page and runs the simulator entirely on the client side. The ESP32 only delivers the file. Hardware - Any ESP32 development board for example ESP32 DevKit - Micro-USB or USB-C data cable, depending on the board Software - Arduino IDE 2.x - ESP32 Arduino core version 2.x or 3.x by Espressif - Python 3 only needed if you want to modify the web app LogicLabPro ESP32/├─ LogicLabPro ESP32.ino main sketch├─ config.h Wi-Fi and hostname settings├─ index html.h gzip-compressed web app auto-generated ├─ webapp/logiclab pro v2.html the original web app└─ tools/embed html.py HTML - index html.h converter Step-by-step buildStep 1: Install the ESP32 core - Open Arduino IDE and go to File Preferences . - In Additional boards manager URLs , add Espressif's package index URL listed in the ESP32 Arduino core documentation . - Open Tools Board Boards Manager , search for esp32 and install the package by Espressif Systems. - Select your board under Tools Board for example ESP32 Dev Module . The default partition scheme is fine. Download the project folder GitHub link: add your repository link and open LogicLabPro ESP32.ino in Arduino IDE. The folder name must match the sketch name, so keep LogicLabPro ESP32 . Open config.h and set your network name and password: define WIFI SSID "YOUR WIFI SSID" define WIFI PASS "YOUR WIFI PASSWORD" define WIFI TIMEOUT MS 15000 define AP SSID "LogicLab-ESP32" define AP PASS "logiclab123" define HOSTNAME "logiclab" If the ESP32 cannot join your network within the timeout, it starts its own access point named LogicLab-ESP32 and the app is available at 192.168.4.1 . Connect the board, choose the correct port under Tools Port , and click Upload . If the upload hangs on "Connecting...", hold the board's BOOT button until it starts. Open Serial Monitor at 115200 baud . After a successful connection you will see something like: === LogicLab Pro on ESP32 === WiFi Connected. IP: 192.168.x.x mDNS http://logiclab.local HTTP Open: http://192.168.x.x Type that address or http://logiclab.local into a browser on any device on the same network. LogicLab Pro loads. Add a photo or screenshot of the Serial Monitor output and the simulator running on a phone. Code walkthroughConverting the HTML The core of embed html.py is just a few lines: python import gzip, pathlibraw = pathlib.Path "webapp/logiclab pro v2.html" .read bytes gz = gzip.compress raw, compresslevel=9, mtime=0 ...then write the bytes out as a C array: const uint8 t INDEX HTML GZ PROGMEM = { 0x1f, 0x8b, ... }; const size t INDEX HTML GZ LEN = 32125; Run it from the project folder: python3 tools/embed html.py Serving the page void handleRoot { server.sendHeader "Content-Encoding", "gzip" ; server.sendHeader "Cache-Control", "no-cache" ; server.send P 200, "text/html; charset=utf-8", PGM P INDEX HTML GZ, INDEX HTML GZ LEN ;} The Content-Encoding: gzip header tells the browser to decompress the data. send P reads straight from flash, so the 32 KB array does not use RAM. if connectStation { Serial.printf " WiFi Connected. IP: %s\n", WiFi.localIP .toString .c str ;} else { startAccessPoint ; // SSID: LogicLab-ESP32}if MDNS.begin HOSTNAME { MDNS.addService "http", "tcp", HTTP PORT ;}server.on "/", HTTP GET, handleRoot ;server.on "/index.html", HTTP GET, handleRoot ;server.on "/health", HTTP GET, handleHealth ; // JSON statusserver.onNotFound handleNotFound ; // redirect to /server.begin ; The /health endpoint returns the mode station or AP , IP address, uptime and free heap as JSON, which is handy for quick debugging. LogicLab Pro loads Tailwind CSS , Google Fonts and the Gemini API from the internet. The ESP32 only serves the HTML; your browser fetches those resources. That means: - Station mode ESP32 joins your router or phone hotspot : everything works, as long as your device has internet. - Access-point mode: the client has no internet connection, so styling and the AI chat will not load. The AI chat also needs your own Gemini API key. The app asks for it in the browser and stores it in that browser's local storage, so the key never passes through the ESP32. Local storage is tied to the address you use, so if the ESP32's IP changes you may need to enter the key again. Using http://logiclab.local avoids that. - Edit webapp/logiclab pro v2.html . - Run python3 tools/embed html.py . - Re-upload the sketch. - Page loads but looks unstyled: the browser cannot reach the Tailwind CDN. Check that the client device has internet, or connect the ESP32 to a network that does. - logiclab.local does not resolve: mDNS support varies by operating system and network. Use the IP address from the Serial Monitor. - ESP32 starts in AP mode unexpectedly: double-check the SSID and password in config.h . The ESP32 connects only to 2.4 GHz networks. - Compile error about a missing header: make sure index html.h and config.h are in the same folder as the .ino file. - Bundle Tailwind and the fonts locally for example on LittleFS for a fully offline setup. - Add a WebSocket bridge so the simulated circuit can read and drive real ESP32 GPIO pins. - Add OTA updates so you can change the web app without a USB cable. - Add a simple captive portal for the access-point mode. With a gzip-compressed C array and the stock WebServer class, an ESP32 can host a surprisingly capable web application. The same technique works for dashboards, configuration pages and educational tools. Try it with your own single-file web app and share what you build. Explanations about web application performance Read more