Web-Based Firmware Flashing¶
Flash your ESP32 directly from your browser using the Web Serial API - no Python, no esptool, no command-line complexity.
Overview¶
The web flasher provides a browser-based interface for flashing firmware to ESP32 devices. This is especially useful when:
Working in GitHub Codespaces or remote development containers
USB passthrough to containers is not available
You want a simple one-click flashing experience
You need to flash from environments without Python/esptool
Quick Start¶
Build firmware:
idf.py buildStart web flasher server:
./tools/web-flasher/start-web-flasher.sh
Forward port 8001 in VS Code (Ports tab)
Open the forwarded URL in Chrome/Edge/Opera
Click “Connect and Flash ESP32” and select your device
Features¶
✅ Browser-based - No installation required
✅ One-click operation - Flash bootloader, partition table, and application
✅ Serial monitor - View ESP32 output in browser
✅ Progress tracking - Real-time flashing status
✅ Codespaces compatible - Works in remote environments
Browser Requirements¶
Supported Browsers¶
The web flasher requires the Web Serial API:
Chrome 89+
Edge 89+
Opera 75+
Warning
Firefox and Safari do not yet support the Web Serial API.
Hardware Requirements¶
ESP32 connected via USB to your local computer (not the container)
USB cable with data lines (not charge-only cable)
Usage Guide¶
Step 1: Build Firmware¶
Build your project first:
cd /workspaces/esp32-template # Or your project directory
idf.py build
This generates the required binary files:
build/bootloader/bootloader.binbuild/partition_table/partition-table.binbuild/your-project-name.bin
Step 2: Start Web Server¶
Run the web flasher server:
./tools/web-flasher/start-web-flasher.sh
This automatically:
Generates
build/flasher-manifest.jsonwith flash offsetsStarts HTTP server on port 8001
Serves the web flasher interface
Step 3: Port Forwarding¶
In VS Code (GitHub Codespaces):
Open the Ports tab (next to Terminal)
Click Forward a Port
Enter
8000Set visibility to Public if accessing from different network
Click on the forwarded URL to open in browser
Step 4: Connect and Flash¶
In the browser:
Connect ESP32 via USB to your local computer
Click “Connect and Flash ESP32”
Select your ESP32’s serial port from the browser dialog
Click Install to start flashing
The flasher will:
Erase flash (if needed)
Flash bootloader at offset 0x1000
Flash partition table at offset 0x8000
Flash application at offset 0x10000
Show real-time progress
Step 5: Monitor Output¶
After flashing:
✅ “Installation successful” message appears
📡 Serial console shows ESP32 output
🔄 Option to reconnect or flash again
Architecture¶
How It Works¶
┌─────────────────┐
│ GitHub │
│ Codespaces │
│ Container │
│ │
│ ┌───────────┐ │
│ │ HTTP │ │ Port 8001 forwarded
│ │ Server │◄─┼──────────────────────┐
│ └───────────┘ │ │
│ │ │
│ ┌───────────┐ │ │
│ │ Firmware │ │ ▼
│ │ Binaries │ │ ┌──────────────┐
│ └───────────┘ │ │ Browser │
└─────────────────┘ │ (Chrome) │
└──────┬───────┘
│ Web Serial API
│
┌──────▼───────┐
│ USB │
└──────┬───────┘
│
┌──────▼───────┐
│ ESP32 │
└──────────────┘
Components¶
HTTP Server (
flasher_server.py)Serves web interface and firmware files
Provides manifest.json with flash offsets
Web Interface (
web-flasher.html)Built on ESP Web Tools library
Handles Web Serial API communication
Provides UI for connection and monitoring
Manifest Generator (
generate-flasher-manifest.sh)Scans build directory for binaries
Generates ESP Web Tools compatible manifest
Extracts project name from CMakeLists.txt
Manifest Format¶
The build/flasher-manifest.json tells the browser what to flash:
{
"name": "your-project-name",
"version": "1.0.0",
"builds": [
{
"chipFamily": "ESP32",
"parts": [
{
"path": "../build/bootloader/bootloader.bin",
"offset": 4096
},
{
"path": "../build/partition_table/partition-table.bin",
"offset": 32768
},
{
"path": "../build/your-project-name.bin",
"offset": 65536
}
]
}
]
}
Troubleshooting¶
Port 8001 Already in Use¶
Symptom: Server fails to start with “Address already in use”
Solution:
# Stop any running web flasher
./tools/web-flasher/stop-web-flasher.sh
# Or manually kill process
pkill -f flasher_server.py
lsof -ti:8001 | xargs kill -9
Serial Port Not Appearing¶
Symptom: Browser dialog shows no serial ports
Possible Causes:
ESP32 not connected - Check USB connection to local computer
Wrong cable - Ensure cable has data lines (not charge-only)
Driver missing - Install CH340/CP2102 USB-to-serial drivers
Browser permission - Allow serial port access in browser
Solution:
Try different USB port
Restart ESP32 (press reset button)
Check Device Manager (Windows) /
ls /dev/tty*(Mac/Linux)Grant browser serial port permissions
Flash Failed or Timeout¶
Symptom: Flashing starts but fails partway through
Solutions:
Put ESP32 in download mode manually:
Hold BOOT button
Press RESET button
Release RESET
Release BOOT
Check serial connection:
Try different USB cable
Connect directly (avoid USB hubs)
Verify firmware build:
idf.py build ls -lh build/*.bin build/bootloader/*.bin build/partition_table/*.bin
Firefox/Safari Not Working¶
Symptom: Web flasher doesn’t load or connect button missing
Cause: Web Serial API not supported in Firefox/Safari
Solution: Use Chrome, Edge, or Opera browser
References¶
See Also¶
QEMU Emulator Guide - Testing without hardware using QEMU
Debugging Guide - GDB debugging workflows