This documentation is best viewed on the documentation site rather than GitHub or NPM package site.
A TypeScript library for connecting to micro:bit devices via USB and Bluetooth. Works in browsers (via WebUSB and Web Bluetooth) and in native iOS/Android apps (Bluetooth only, via Capacitor).
Available on NPM. Migrating from an earlier version? See the migration guide.
| Feature | Web (browser) | Native (Capacitor) |
|---|---|---|
| USB connection | WebUSB | Not supported |
| Bluetooth connection | Web Bluetooth | iOS and Android |
| Flash via USB | Yes | Not supported |
| Flash via Bluetooth | Not supported | iOS and Android |
The library is split into separate entrypoints for tree-shaking. Import shared types from the root and connection-specific code from subpaths:
| Import path | Contents |
|---|---|
@microbit/microbit-connection |
Shared types and events (ConnectionStatus, DeviceConnection, FlashOptions, etc.) |
@microbit/microbit-connection/bluetooth |
createBluetoothConnection and Bluetooth connection types |
@microbit/microbit-connection/usb |
createUSBConnection and USB connection types |
@microbit/microbit-connection/universal-hex |
createUniversalHexFlashDataSource (depends on @microbit/microbit-universal-hex) |
@microbit/microbit-connection/radio-bridge |
Experimental. createRadioBridgeConnection for radio bridge via USB. Limited service support — see JSDoc for details. |
Instantiate a WebUSB connection using {@link @microbit/microbit-connection/usb!createUSBConnection | createUSBConnection} and use it to connect to a micro:bit.
import { createUSBConnection } from "@microbit/microbit-connection/usb";
const usb = createUSBConnection();
await usb.connect();
console.log("Connection status: ", usb.status); // "Connected"Flash a universal hex that supports both V1 and V2:
import { createUniversalHexFlashDataSource } from "@microbit/microbit-connection/universal-hex";
await usb.flash(createUniversalHexFlashDataSource(universalHexString), {
partial: true,
progress: (stage, percentage) => {
console.log(stage, percentage);
},
});This code will also work for non-universal hex files so is a good default for unknown hex files.
Alternatively, you can create and flash a hex for a specific micro:bit version by providing a function that takes a {@link @microbit/microbit-connection!BoardVersion} and returns a hex. This can reduce download size or help integrate with APIs that produce a hex for a particular device version. This example uses the @microbit/microbit-fs library which can return a hex based on board id.
import { MicropythonFsHex, microbitBoardId } from "@microbit/microbit-fs";
const micropythonFs = new MicropythonFsHex([
{ hex: microPythonV1HexFile, boardId: microbitBoardId.V1 },
{ hex: microPythonV2HexFile, boardId: microbitBoardId.V2 },
]);
// Add files to MicroPython file system here (omitted for simplicity)
// Flash the device
await usb.flash(
async (boardVersion) => {
return micropythonFs.getIntelHex(microbitBoardId[boardVersion]);
},
{
partial: true,
progress: (stage, percentage) => {
console.log(stage, percentage);
},
},
);The connection state after flashing differs between USB and Bluetooth because they connect to different parts of the micro:bit hardware:
-
USB connects to the interface chip (running DAPLink firmware), which is separate from the application processor that runs user code. Flashing does not affect the interface chip, so the USB connection remains in
"Connected"state and serial communication is automatically reinitialised. -
Bluetooth connects directly to the application processor (the Nordic nRF51/nRF52 running the user's program and BLE stack). This processor reboots after flashing, so the Bluetooth connection is necessarily lost. The connection is always left in
"Disconnected"state and callers must callconnect()again after flashing.
By default, a USB connection is automatically paused when the browser tab becomes hidden and reconnected when the tab becomes visible again. This frees the USB interface for other tabs or processes while the user isn't looking at the page. During this time the connection status is "Paused".
If reconnection fails when the tab becomes visible again (for example, because another process has claimed the USB interface), the connection transitions to "Disconnected".
To disable this behaviour, pass pauseOnHidden: false:
const usb = createUSBConnection({ pauseOnHidden: false });For more examples see the demo app source.
By default, the micro:bit's Bluetooth service is not enabled. Visit our Bluetooth tech site page to download a hex file that would enable the bluetooth service.
Instantiate a Bluetooth connection using {@link @microbit/microbit-connection/bluetooth!createBluetoothConnection | createBluetoothConnection} class and use it to connect to a micro:bit.
import { createBluetoothConnection } from "@microbit/microbit-connection/bluetooth";
const bluetooth = createBluetoothConnection();
await bluetooth.connect();
console.log("Connection status: ", bluetooth.status); // "Connected"For more examples see the demo app source.
Methods that interact with device features (reading sensors, writing to LEDs, serial communication, etc.) throw a {@link @microbit/microbit-connection!DeviceError | DeviceError} with code "not-connected" if called without an active connection:
import { DeviceError } from "@microbit/microbit-connection";
try {
const data = await bluetooth.getAccelerometerData();
} catch (e) {
if (e instanceof DeviceError && e.code === "not-connected") {
console.log("Connect to a micro:bit first");
}
}Open link hex files are not common. The most common source is the micro:bit CreateAI. Known issues:
-
iOS DFU classroom collision risk with open-link firmware: When performing DFU on iOS with open-link security firmware (no bonding), the Nordic DFU library scans for the bootloader by DFU service UUID and connects to the first matching device. If multiple micro:bits are in bootloader mode simultaneously, the wrong device could be targeted. This does not affect bonded firmware (where the bootloader uses whitelist-filtered advertising) or Android (which reconnects by MAC address).
-
V1 Android PIN dialog with open-link firmware: On Android with micro:bit V1, calling
createBondtriggers a passkey entry dialog because the V1 DAL declaresIO_CAPS_DISPLAY_ONLYeven in open-link mode. The micro:bit displays a PIN that the user must enter. This is a bug in the V1 DAL (V2 correctly usesIO_CAPS_NONE). There is no BLE-visible indicator of the security mode, so the library cannot detect this situation to avoid it. On V2 you get a harmless (but somewhat pointless) "just works" pairing dialog.
- Hex with no partial flashing or DFU control service (V1): Some older CreateAI data-collection hex files for micro:bit V1 fall into this category. There's nothing that can be done via Bluetooth. Workaround: flash via WebUSB or drag and drop from a computer. The equivalent V2 hex does have the Secure DFU service (but not partial flashing) which we support.
The hardware test app is a human-in-the-loop test runner for USB flashing. It covers partial and full flash, flash fallback paths, serial data integrity after flash, and reconnection after unplug. Run it with:
cd apps/hardware-test
npm run devThe tests prompt you for physical actions (plugging/unplugging) and verify the results automatically.
This software is under the MIT open source license.
We use dependencies via the NPM registry as specified by the package.json file under common Open Source licenses.
Full details of each package can be found by running license-checker:
$ npx license-checker --direct --summary --productionOmit the flags as desired to obtain more detail.
Trust, partnership, simplicity and passion are our core values we live and breathe in our daily work life and within our projects. Our open-source projects are no exception. We have an active community which spans the globe and we welcome and encourage participation and contributions to our projects by everyone. We work to foster a positive, open, inclusive and supportive environment and trust that our community respects the micro:bit code of conduct. Please see our code of conduct which outlines our expectations for all those that participate in our community and details on how to report any concerns and what would happen should breaches occur.