BLEMeshJS
Guides

Provision a New Device

Bring an unprovisioned device into your mesh network end to end.

Use this when a device is advertising but not yet part of your mesh network.

Provisioning is the step that turns "nearby hardware" into a trusted mesh node with keys, address, and persistent network state.

Before you start

  • You already ran Setup Runtime.
  • Bluetooth is powered on.
  • The target device is in unprovisioned mode.

1. Scan and capture one unprovisioned candidate

import type { DiscoveredUnprovisionedPeripheral } from "@blemeshjs/sdk";

const candidate = await new Promise<DiscoveredUnprovisionedPeripheral>((resolve, reject) => {
  const offFound = mesh.provision.on("scan:new-peripheral", (peripheral) => {
    mesh.provision.stopScan();
    offFound();
    offError();
    resolve(peripheral);
  });

  const offError = mesh.provision.on("ble:error", (error) => {
    offFound();
    offError();
    reject(error);
  });

  mesh.provision.scan({ timeout: 15_000, notifyOnWaitingForAdvertisements: true });
});

⚠️ Gotcha

Web Bluetooth scan UX is browser-mediated. You should expect chooser-style selection behavior, then scan:new-peripheral fires for the selected device.

✅ Best practice

Keep scan timeouts short (10-20 seconds) and restart scans from explicit user actions.

2. Provision using the quick flow

await mesh.provision.quick(candidate);

quick(...) handles connect -> identify -> provisioning start -> completion, then persists state.

3. Verify provisioning result

console.log("Configured nodes:", mesh.configuredNodes?.length ?? 0);
console.log("Unconfigured nodes:", mesh.notConfiguredNodes?.length ?? 0);

At this point, you should have a node that no longer appears as unprovisioned and is now part of your mesh network.

If provisioning fails

  1. Call mesh.provision.disconnect() to reset local state.
  2. Put the device back into unprovisioned mode if required by hardware.
  3. Start a fresh scan and retry.

💡 Pro tip

If users must pick one physical device among many, run identify before provisioning in a manual flow:

mesh.provision.connect(candidate);
mesh.provision.identify(5);
mesh.provision.start();

If this worked, you are ready to send model commands.

Next, you will want to follow Control Device.

On this page