A single <script> tag. One custom element. Your visitors flash ESP32, ESP8266, and ESP32-S3 devices directly from the browser — no boot button, no IDE, no drivers, no uploads. Now with serial monitor, light/dark themes, and auto-connect.
ESP Flash Button is a browser-based firmware installer you embed on your website. It uses the Web Serial API to communicate with ESP32, ESP8266, and ESP32-S3 microcontrollers — no software installation, no IDE, no USB driver configuration.
The entire flash process happens in the browser. Here's what happens when a user clicks your button.
Drop these into any HTML page. No build step, no npm, no framework.
<!-- Add this once, anywhere in your page --> <script src="https://esp-flash-button.pages.dev/esp-flash-button.js"></script>
<esp-flash-button manifest="https://yoursite.com/firmware/manifest.json"> </esp-flash-button>
button-style attribute to choose a predefined style, or slot="activate" to supply your own button.<!-- Built-in styles: minimal, outline, ghost, gradient, neon --> <esp-flash-button manifest="https://yoursite.com/firmware/manifest.json" button-style="gradient" label="Install My Firmware"> </esp-flash-button> <!-- Fully custom button via slot --> <esp-flash-button manifest="https://yoursite.com/firmware/manifest.json"> <button slot="activate" class="my-custom-btn"> Download Firmware </button> </esp-flash-button>
theme, show-baud, or erase-first attributes.<esp-flash-button manifest="https://yoursite.com/firmware/manifest.json" theme="light" show-baud erase-first label="Install Firmware"> </esp-flash-button>
<script> document.querySelector('esp-flash-button') .addEventListener('flash-success', (e) => { console.log('Flashed!', e.detail); // e.detail = { chip, flashSize, duration, filesCount } }); document.querySelector('esp-flash-button') .addEventListener('flash-error', (e) => { console.error('Failed:', e.detail); }); </script>
Every attribute you can set on the <esp-flash-button> element.
| Attribute | Default | Description |
|---|---|---|
| manifest | required | Absolute URL to your firmware manifest JSON file. |
| label | "Install Firmware" | Text shown on the default flash button. Ignored when using a slotted button. |
| button-style | "default" | Button appearance. One of: default, minimal, outline, ghost, gradient, neon. See showcase below. |
| theme | "dark" | Modal color scheme. dark or light. Can also set via CSS custom properties. |
| baud | 460800 | Flash baud rate. For ESP8266/ESP8285, capped to 115200 automatically. |
| show-baud | — | Boolean. When present, shows a baud rate dropdown (9600–921600) in the ready panel so users can adjust flash speed. |
| erase-first | false | Boolean. When present, erases entire flash before writing. Users can also toggle this via a checkbox in the UI. |
| no-auto-connect | — | Boolean. When present, disables auto-connect. Users will always see the "Connect Device" button and must manually select their serial port. |
| Event | Detail | Description |
|---|---|---|
| flash-success | { chip, flashSize, duration, filesCount } | Fired after firmware is written and device has reset. |
| flash-error | { title, message } | Fired if the flash process fails. |
Set button-style to one of these values. Each is rendered live below.
Set theme="light" for a light modal, or override individual CSS custom properties.
esp-flash-button or any ancestor element. The component inherits them automatically.esp-flash-button { --efb-accent: #2266ff; /* Primary accent (default red) */ --efb-bg-surface: #1a1a2e; /* Modal background */ --efb-bg-card: #222244; /* Card backgrounds */ --efb-text-primary: #eee; /* Primary text */ --efb-success: #44dd88; /* Success indicators */ --efb-warning: #ffaa00; /* Warning indicators */ --efb-font-mono: 'Fira Code'; /* Monospace font */ }
--efb-bg-base, --efb-bg-surface, --efb-bg-card, --efb-bg-status, --efb-bg-hover, --efb-border, --efb-border-subtle, --efb-border-card, --efb-text-primary, --efb-text-secondary, --efb-text-muted, --efb-text-dim, --efb-text-faint, --efb-accent, --efb-accent-hover, --efb-accent-dark, --efb-accent-darker, --efb-accent-light, --efb-accent-bright, --efb-success, --efb-success-dark, --efb-success-darker, --efb-success-hover, --efb-warning, --efb-font, --efb-font-mono, --efb-radius-sm, --efb-radius-md, --efb-radius-lg, --efb-radius-btn.If a user has previously authorized a serial port on your site, the component reconnects automatically — no browser dialog needed.
navigator.serial.getPorts(). If a previously authorized port is found, it reconnects automatically and shows a "Flash Firmware" button directly — the user never sees a port selection dialog.<esp-flash-button>. The first time, users see the standard port picker; on subsequent visits, they connect instantly. When auto-connected, a Change Port button lets users pick a different device. Developers can disable auto-connect entirely with the no-auto-connect attribute.After flashing, users can open a full-featured serial monitor directly in the browser — no separate terminal app needed.
ReadableStream for zero-latency streaming.A simple JSON file that tells the component what firmware to flash and for which chips. Host it on your server alongside your .bin files.
Access-Control-Allow-Origin: * to your server responses.
{ "name": "My ESP32 Project", "version": "1.0.0", "builds": [ { "chipFamily": "ESP32", "parts": [ { "path": "firmware.bin", "offset": 0 } ] } ] }
{ "name": "My Firmware", "version": "2.1.0", "new_install_prompt_erase": true, "funding_url": "https://ko-fi.com/yourproject", "builds": [ { "chipFamily": "ESP32", "parts": [ { "path": "bootloader.bin", "offset": 4096 }, { "path": "partitions.bin", "offset": 32768 }, { "path": "boot_app0.bin", "offset": 57344 }, { "path": "firmware.bin", "offset": 65536 } ] }, { "chipFamily": "ESP32-S3", "parts": [ { "path": "firmware-s3.bin", "offset": 0 } ] }, { "chipFamily": "ESP8266", "parts": [ { "path": "firmware-8266.bin", "offset": 0 } ] } ] }
true, the erase checkbox is checked by default and a yellow info banner explains that flash memory will be erased. Users can uncheck to skip erase.A comprehensive feature set for embedding firmware installation on any website.
theme="light" or override 25+ CSS custom properties for a fully custom look.navigator.serial.getPorts() to reconnect to previously authorized ports automatically.show-baud.slot="activate".A detailed feature comparison. ESP Flash Button is the more capable, faster, and better-looking alternative.
ESP Flash Button supports all ESP32-family chips supported by esptool-js. Any board with a USB-to-serial converter works.
baud attribute, or expose the baud selector to users with show-baud.button-style attribute to pick from 6 built-in templates (default, minimal, outline, ghost, gradient, neon), or use slot="activate" to supply your own custom button element.theme attribute to "light" for a light mode, or override individual CSS custom properties like --efb-accent, --efb-bg-surface, and --efb-text-primary on the esp-flash-button element.navigator.serial.getPorts() returns the previously authorized port and the component reconnects automatically.Your manifest and .bin files must allow cross-origin requests from the page embedding the button. Add these headers to your server:
# Apache (.htaccess) Header set Access-Control-Allow-Origin "*" # Nginx add_header Access-Control-Allow-Origin *; # Cloudflare Pages (_headers) /firmware/* Access-Control-Allow-Origin: * # Express / Node.js app.use('/firmware', (req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); next(); });