Web Bluetooth API: Connect Hardware Using JavaScript
The Web Bluetooth API allows web applications to communicate directly with nearby Bluetooth Low Energy (BLE) peripheral devices securely and natively using JavaScript. This guide explains the core concepts behind the Web Bluetooth API, its security architecture, and the step-by-step implementation process required to discover, connect, read, and write data to peripheral hardware.
What is the Web Bluetooth API?
The Web Bluetooth API provides web developers with the ability to connect web pages directly to Bluetooth Low Energy (BLE) devices using the Generic Attribute Profile (GATT). Traditionally, communicating with external hardware required dedicated native applications built in languages like Swift, Kotlin, or C++. With Web Bluetooth, standard web browsers can interface directly with physical devices like heart rate monitors, smart light bulbs, industrial sensors, and IoT microcontrollers (e.g., Arduino, ESP32).
Core Concepts: Understanding BLE and GATT
Web Bluetooth operates strictly over Bluetooth Low Energy using the GATT hierarchy:
- Peripheral (Server): The physical hardware device broadcasting its presence (e.g., a smart scale or temperature sensor).
- Central (Client): The device running the browser initiating the connection.
- GATT Server: Hosted by the peripheral, containing one or more Services.
- Services: Collections of related functions or data points identified by 16-bit or 128-bit UUIDs (e.g., Battery Service, Heart Rate Service).
- Characteristics: The actual data values contained within a service. Characteristics support specific operations, such as Read, Write, or Notify.
- Descriptors: Metadata providing additional context for a characteristic (e.g., unit of measurement).
Security and Operational Prerequisites
Browsers enforce strict security mechanisms to protect users from unauthorized hardware access:
- Secure Context (HTTPS): Web Bluetooth is only
accessible on origins served via HTTPS or
localhost. - Explicit User Interaction: Hardware discovery cannot trigger automatically on page load. It must be initiated by an explicit user gesture, such as clicking a button or tapping a screen.
- User Consent: The browser displays a native device chooser dialog where the user must explicitly select and pair the hardware.
How JavaScript Connects to Peripheral Hardware
Connecting to a BLE device involves a sequential, Promise-based workflow:
1. Requesting the Device
Use navigator.bluetooth.requestDevice() with predefined
filters to scan for devices broadcasting specific services or matching
name patterns.
const device = await navigator.bluetooth.requestDevice({
filters: [{ services: ['heart_rate'] }],
// Or: acceptAllDevices: true, optionalServices: ['battery_service']
});2. Connecting to the GATT Server
Once the user selects a device, establish a connection to its GATT server:
const server = await device.gatt.connect();3. Accessing the Primary Service
Retrieve the specific service from the connected GATT server using standard names or custom UUIDs:
const service = await server.getPrimaryService('heart_rate');4. Retrieving Characteristics
Obtain a reference to the characteristic you want to read, write, or listen to:
const characteristic = await service.getCharacteristic('heart_rate_measurement');5. Performing Data Operations
Reading Data: Data is returned as a
DataViewwrapped in anArrayBuffer.const value = await characteristic.readValue(); const heartRate = value.getUint8(1);Writing Data: Send data directly to the device as an
ArrayBufferor typed array.const command = new Uint8Array([0x01]); await characteristic.writeValue(command);Receiving Real-Time Notifications: Subscribe to events when the hardware pushes updates dynamically.
await characteristic.startNotifications(); characteristic.addEventListener('characteristicvaluechanged', (event) => { const value = event.target.value; console.log('Update received:', value.getUint8(0)); });
6. Handling Disconnections
Always monitor hardware disconnections to update your application state gracefully:
device.addEventListener('gattserverdisconnected', () => {
console.log('Device disconnected.');
});Browser Compatibility
Web Bluetooth is supported natively in Chromium-based browsers, including Google Chrome, Microsoft Edge, and Opera across Android, ChromeOS, macOS, Linux, and Windows. Apple Safari and Mozilla Firefox do not currently support the Web Bluetooth API due to privacy and platform architecture policies.