nrfutil-web
v1.0.0
Published
Flash nRF52 firmware from the browser using Web Serial — no drivers, no desktop app required
Maintainers
Readme
nrfutil-web
Flash nRF52 firmware from the browser using Web Serial — no drivers, no desktop app required.
Features
- Uses the browser's Web Serial API
- Compatible with the Adafruit nRF52 bootloader DFU protocol
- Accepts ZIP packages generated by adafruit-nrfutil directly
- Supports Application, SoftDevice, Bootloader, and SD+BL updates
- Progress callback support
- TypeScript support with type definitions included
- Single dependency:
jszip
Requirements
- A browser that supports Web Serial API (Chrome, Edge, etc.)
- A DFU package in ZIP format generated by adafruit-nrfutil
Installation
pnpm add nrfutil-web
# or
npm install nrfutil-webUsage
Basic usage
import { performDfu, enterDfuMode } from "nrfutil-web";
// 1. Connect to the application port
const appPort = await navigator.serial.requestPort();
// 2. Trigger DFU mode via 1200bps touch
await enterDfuMode(appPort);
// 3. Wait for the device to re-enumerate, then select the DFU port
const dfuPort = await navigator.serial.requestPort();
// 4. Fetch firmware and flash
const zipData = await fetch("/firmware.zip").then(r => r.arrayBuffer());
await performDfu(dfuPort, zipData, {
onProgress: ({ percent, message }) => {
console.log(`${percent}% - ${message}`);
},
});API Reference
performDfu(port, zipData, options?)
Performs the DFU firmware update.
| Parameter | Type | Description |
|---|---|---|
| port | SerialPortLike | WebSerial port |
| zipData | ArrayBuffer | DFU package ZIP |
| options.onProgress | ProgressCallback | Progress callback |
| options.ackTimeout | number | ACK timeout in ms (default: 5000) |
| options.maxRetries | number | Max retries per packet (default: 3) |
| options.singleBank | boolean | Single bank mode (default: true) |
enterDfuMode(port, waitTime?)
Sends a 1200bps touch to trigger DFU mode on the device.
| Parameter | Type | Description |
|---|---|---|
| port | SerialPortLike | WebSerial port |
| waitTime | number | Wait time after touch in ms (default: 1500) |
ProgressCallback
type ProgressCallback = (progress: {
sent: number; // Bytes sent so far
total: number; // Total bytes to send
percent: number; // Progress (0–100)
message: string; // Current operation description
}) => void;Advanced usage
Lower-level APIs are also available for advanced use cases.
import { DfuSerialTransport, parseDfuPackage } from "nrfutil-web";
// Parse the ZIP manually
const images = await parseDfuPackage(zipData);
// Operate the transport directly
const transport = new DfuSerialTransport(port, { ackTimeout: 10000 });
await transport.open();
await transport.sendPacket(payload);
await transport.close();Development
# Install dependencies
pnpm install
# Build
pnpm build
# Run tests
pnpm test
# Start demo page (examples/index.html)
pnpm devArchitecture
src/
├── index.ts # Public API
├── dfu.ts # DFU main controller
├── transport.ts # Serial transport (HCI / SLIP / ACK)
├── package.ts # DFU ZIP package parser
├── dfu-protocol.ts # Protocol constants and packet builders
├── hci.ts # HCI packet handling
├── slip.ts # SLIP encode / decode
└── crc16.ts # CRC-16 calculationLicense
BSD-3-Clause
