Browser-based flash programmer for STM32 microcontrollers that expose the factory ROM bootloader over USB DFU. No drivers, no desktop software, no installation required.
Accepts: .hex (Intel HEX) or .bin files
Erases: only the flash sectors touched by the file — all other flash is left intact
Browser: Google Chrome (web), or the standalone Electron app (macOS / Windows / Linux)
The tool communicates using ST's DfuSe protocol over the standard ROM USB DFU bootloader (VID 0x0483 / PID 0xDF11). The flash sector map is read automatically from the DfuSe interface string descriptor, so any device that correctly exposes that descriptor should work without changes.
| Device | Board | Result |
|---|---|---|
| STM32F723 | Custom PCB | ✅ Fully working |
These devices share the same ROM bootloader protocol. They have not yet been independently validated — community reports welcome (see below).
| Series | Example parts |
|---|---|
| STM32F2 | F205, F207, F215, F217 |
| STM32F4 | F401, F405, F407, F411, F429, F446, F469 |
| STM32F7 | F722, F730, F745, F746, F756, F765, F767, F769, F777 |
| STM32H7 | H723, H743, H745, H750, H753, H755, H757 |
| STM32L4 | L433, L475, L476, L496 (USB-capable variants) |
| STM32G4 | G431, G474, G491 (USB-capable variants) |
| STM32U5 | U535, U545, U575, U585 |
Note: Only STM32 devices with a USB Full-Speed or High-Speed peripheral and a DFU-capable ROM bootloader are supported. Devices that use UART/I²C DFU or require a separate ST-LINK connection are not supported.
If you have tested this tool on a device not listed above, please open a validation issue with your results. Reports help build a verified compatibility list for the community.
The Electron build runs as a native desktop app — no browser, no HTTP server, no Chrome required. USB device access is granted automatically.
Node.js 18 or later — download from nodejs.org.
cd /path/to/stm32-web-programmer
npm installnpm startBuild for your current platform only:
npm run dist:mac # → dist/ (arm64 + x64 .dmg)
npm run dist:win # → dist/ (.exe NSIS installer, x64)
npm run dist:linux # → dist/ (.AppImage, x64)Build all platforms at once (requires macOS for the mac target):
npm run distOutput is placed in the dist/ folder.
macOS Gatekeeper warning: The app is unsigned. On first launch, right-click the
.appinside the.dmgand choose Open, then confirm. Subsequent launches work normally.
Linux USB access: The AppImage needs permission to access USB devices without root. Create a udev rule once:
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="df11", MODE="0666"' \ | sudo tee /etc/udev/rules.d/49-stm32-dfu.rules sudo udevadm control --reload-rules && sudo udevadm triggerReplug the STM32 after applying the rule.
If you prefer to use Chrome without installing Node.js, serve the files over a local HTTP server. WebUSB requires a secure context (localhost or https://) — opening index.html directly as a file:// URL will not work.
No. WebUSB requires a secure context — either https:// or localhost. Opening index.html as a file:// URL will show a "WebUSB not available" error. You must serve it through a local HTTP server (see below). No internet connection is needed; the server runs entirely on your machine.
Open a terminal, navigate to the project folder, and run the command for your OS.
Python 3 ships with macOS (10.15+):
cd /path/to/stm32-web-programmer
python3 -m http.server 8080cd /path/to/stm32-web-programmer
python3 -m http.server 8080If Python 3 is not installed: sudo apt install python3 (Debian/Ubuntu) or sudo dnf install python3 (Fedora).
Option A — Python (recommended if installed):
cd C:\path\to\stm32-web-programmer
python -m http.server 8080Download Python from python.org if needed. Check "Add python.exe to PATH" during install.
Option B — PowerShell, no install required:
cd C:\path\to\stm32-web-programmer
$listener = [System.Net.HttpListener]::new()
$listener.Prefixes.Add("http://localhost:8080/")
$listener.Start()
Write-Host "Serving on http://localhost:8080 — press Ctrl+C to stop"
while ($listener.IsListening) {
$ctx = $listener.GetContext()
$file = Join-Path (Get-Location) $ctx.Request.Url.LocalPath.TrimStart('/')
if (Test-Path $file -PathType Leaf) {
$bytes = [System.IO.File]::ReadAllBytes($file)
$ctx.Response.OutputStream.Write($bytes, 0, $bytes.Length)
}
$ctx.Response.Close()
}Option C — Node.js (if installed):
cd C:\path\to\stm32-web-programmer
npx serve .Once the server is running, open Google Chrome and go to:
http://localhost:8080
Leave the terminal open while you use the tool. Press Ctrl+C to stop the server when done.
The exact method varies by device, but the general approach is:
- Pull BOOT0 high (connect to VCC via a solder bridge, switch, or jumper). Some boards have a dedicated BOOT button — hold it while resetting.
- Reset the device (press the reset button or cycle power).
- The STM32 enumerates as a USB DFU device — no firmware is running at this point.
Verify it is visible:
- macOS / Linux:
lsusb→STMicroelectronics STM Device in DFU Mode - Windows: Device Manager → Universal Serial Bus devices →
STM Device in DFU Mode
Drag and drop a .hex or .bin file onto the drop zone, or click to browse.
- HEX files: target flash addresses are read automatically from the file.
- BIN files: enter the Flash address where the binary should be placed (default
0x08000000).
Click Connect Device.
- Electron app: the STM32 DFU device is selected automatically — no picker appears.
- Chrome browser: a USB device picker appears; select the STM32 DFU entry.
The device name and detected sector map appear on success.
Click Program Flash. Progress is shown in three phases:
| Bar | What it tracks |
|---|---|
| Erase | Sectors erased vs. total sectors to erase |
| Write | KB written vs. total KB |
| Verify | KB read back and confirmed (if enabled) |
Options:
| Checkbox | Default | Effect |
|---|---|---|
| Verify after write | On | Reads every written byte back and compares to the source |
| Leave DFU & reset | On | Triggers the bootloader to jump to 0x08000000 after programming |
| Symptom | Cause | Fix |
|---|---|---|
| "WebUSB not available" | Opened as file:// in browser |
Use the Electron app, or serve via http://localhost:8080 in Chrome |
| Device not listed in picker | Not in DFU mode | Check BOOT0 is high and reset the board |
| "Access denied" or "device in use" | Another tool has the device open | Close STM32CubeProgrammer, dfu-util, etc. |
| Verify mismatch | Write error or wrong target address | Check the hex/bin targets the correct flash region; retry |
| Device disconnects mid-write | USB cable or power issue | Use a short, quality cable; retry |
| "Cannot reach idle state" | Device stuck in error state | Disconnect, power-cycle the board, reconnect |
| Parameter | Value |
|---|---|
| USB VID | 0x0483 (STMicroelectronics) |
| USB PID | 0xDF11 (DFU ROM bootloader) |
| Transfer size | 2048 bytes |
| Protocol | DFU 1.1 + ST DfuSe extensions |
See PROGRAMMER.md for protocol details and the flash sector map.
Copyright © 2026 DBML Group Inc. Released under the MIT License.