This example demonstrates the full lifecycle: requesting a port, creating the transport/loader, connecting, reading a file, flashing, resetting, and disconnecting.
import {
ESPLoader,
Transport,
LoaderOptions,
FlashOptions,
FlashModeValues,
FlashFreqValues,
FlashSizeValues,
} from "esptool-js";
async function flashFirmware() {
try {
// 1. Request serial port
const port = await navigator.serial.requestPort();
// 2. Create transport and loader
const transport = new Transport(port, true);
const esploader = new ESPLoader({
transport,
baudrate: 115200,
terminal: {
clean: () => console.clear(),
writeLine: (data) => console.log(data),
write: (data) => console.log(data),
},
});
// 3. Connect to device
const chipName = await esploader.main();
console.log(`Connected to: ${chipName}`);
// 4. Load firmware (example: from a file input)
const fileInput = document.getElementById("firmwareFile") as HTMLInputElement;
const file = fileInput.files[0];
const firmwareData = new Uint8Array(await file.arrayBuffer());
// 5. Flash firmware
const flashOptions: FlashOptions = {
fileArray: [{ data: firmwareData, address: 0x1000 }],
flashMode: "dio" as FlashModeValues,
flashFreq: "40m" as FlashFreqValues,
flashSize: "4MB" as FlashSizeValues,
eraseAll: false,
compress: true,
reportProgress: (fileIndex, written, total) => {
console.log(`Progress: ${((written / total) * 100).toFixed(1)}%`);
},
};
await esploader.writeFlash(flashOptions);
console.log("Firmware flashed successfully!");
// 6. Reset device
await esploader.after("hard_reset");
// 7. Disconnect
await transport.disconnect();
} catch (error) {
console.error("Error:", error);
}
}