@jts-web/web-ble-lite
v0.0.0
Published
A lightweight, cross-browser wrapper for the Web Bluetooth API (BLE/GATT)
Maintainers
Readme
@jts-web/web-ble-lite
A lightweight, cross-browser wrapper for the Web Bluetooth API (BLE/GATT) designed for modern web applications.
Features
- 🎯 Simple API - Easy-to-use functions for Bluetooth Low Energy operations
- 🔍 Browser Detection - Automatic detection and helpful error messages
- 📦 Lightweight - Minimal dependencies, small bundle size
- 🛡️ Type Safe - Full TypeScript support with comprehensive type definitions
- 🔌 Cross-Browser - Works with Chrome and Edge (with graceful degradation for others)
Installation
npm install @jts-web/web-ble-liteBrowser Support
| Browser | Support | Notes | | ----------- | ---------------- | ----------------------------------------- | | Chrome | ✅ Full | Version 56+ (Desktop, Android, Chrome OS) | | Edge | ✅ Full | Version 79+ (Chromium-based) | | Safari | ❌ Not Supported | Web Bluetooth API is not available | | Firefox | ❌ Not Supported | Web Bluetooth API is not available |
Important Notes
- HTTPS Required: Web Bluetooth requires a secure context (HTTPS) or
localhost - User Gesture: Device requests must be triggered by a user action (click, touch, etc.)
- Safari/Firefox: These browsers do not support the Web Bluetooth API. The library will provide clear error messages when used in unsupported browsers.
Quick Start
import {
isAvailable,
requestDevice,
connect,
readCharacteristic,
writeCharacteristic,
startNotifications,
disconnect,
} from "@jts-web/web-ble-lite";
// Check if Web Bluetooth is available
const available = await isAvailable();
if (!available) {
console.error("Web Bluetooth is not available");
return;
}
// Request a device
const device = await requestDevice({
filters: [{ services: ["battery_service"] }],
});
// Connect to the device
const { gatt } = await connect(device);
// Read a characteristic
const value = await readCharacteristic(
device,
"battery_service",
"battery_level"
);
// Write to a characteristic
await writeCharacteristic(
device,
"heart_rate_service",
"heart_rate_control_point",
new Uint8Array([1])
);
// Start receiving notifications
await startNotifications(
device,
"heart_rate_service",
"heart_rate_measurement",
(data) => {
console.log("Received data:", data);
}
);
// Disconnect when done
disconnect(device);API Reference
Browser Detection
detectBrowser(): BrowserInfo
Detects the current browser and Web Bluetooth support.
import { detectBrowser } from "@jts-web/web-ble-lite";
const browser = detectBrowser();
console.log(browser.name); // "Chrome", "Edge", "Safari", "Firefox", or "Unknown"
console.log(browser.supportsWebBluetooth); // true or falseAvailability
isAvailable(): Promise<boolean>
Checks if Web Bluetooth is available in the current browser and environment.
const available = await isAvailable();Device Management
requestDevice(opts: RequestDeviceOptions): Promise<DeviceHandle>
Requests a Bluetooth device from the user.
const device = await requestDevice({
filters: [{ services: ["battery_service"] }, { name: "My Device" }],
optionalServices: ["heart_rate_service"],
// OR
acceptAllDevices: true,
});Options:
filters: Array of filters to match devicesoptionalServices: Array of service UUIDs to requestacceptAllDevices: If true, shows all nearby devices
Throws:
NotSupportedError: If Web Bluetooth is not availablePermissionDeniedError: If user denies permission
connect(handle: DeviceHandle): Promise<{ device: BluetoothDevice; gatt: BluetoothRemoteGATTServer }>
Connects to a Bluetooth device.
const { device, gatt } = await connect(deviceHandle);disconnect(handle: DeviceHandle): void
Disconnects from a Bluetooth device.
disconnect(deviceHandle);Characteristics
readCharacteristic(handle: DeviceHandle, service: UUID, characteristic: UUID): Promise<DataView>
Reads a characteristic value.
const value = await readCharacteristic(
deviceHandle,
"battery_service",
"battery_level"
);
// value is a DataView
const batteryLevel = value.getUint8(0);writeCharacteristic(handle: DeviceHandle, service: UUID, characteristic: UUID, data: BufferSource): Promise<void>
Writes a value to a characteristic.
await writeCharacteristic(
deviceHandle,
"heart_rate_service",
"heart_rate_control_point",
new Uint8Array([1])
);startNotifications(handle: DeviceHandle, service: UUID, characteristic: UUID, onData: (v: DataView) => void): Promise<void>
Starts receiving notifications from a characteristic.
await startNotifications(
deviceHandle,
"heart_rate_service",
"heart_rate_measurement",
(data) => {
const heartRate = data.getUint8(1);
console.log("Heart rate:", heartRate);
}
);stopNotifications(handle: DeviceHandle, service: UUID, characteristic: UUID): Promise<void>
Stops receiving notifications from a characteristic.
await stopNotifications(
deviceHandle,
"heart_rate_service",
"heart_rate_measurement"
);Error Handling
The library provides specific error classes for different scenarios:
import {
NotSupportedError,
PermissionDeniedError,
DeviceDisconnectedError,
} from "@jts-web/web-ble-lite";
try {
const device = await requestDevice({ acceptAllDevices: true });
} catch (error) {
if (error instanceof NotSupportedError) {
console.error("Web Bluetooth not supported:", error.browser);
// Error message includes browser-specific guidance
} else if (error instanceof PermissionDeniedError) {
console.error("User denied permission");
} else {
console.error("Other error:", error);
}
}Type Definitions
All types are exported for use in your TypeScript projects:
import type {
DeviceHandle,
RequestDeviceOptions,
BrowserInfo,
} from "@jts-web/web-ble-lite";Examples
Battery Level Monitor
import {
requestDevice,
connect,
readCharacteristic,
} from "@jts-web/web-ble-lite";
async function monitorBattery() {
const device = await requestDevice({
filters: [{ services: ["battery_service"] }],
});
await connect(device);
// Read battery level every second
setInterval(async () => {
const value = await readCharacteristic(
device,
"battery_service",
"battery_level"
);
const level = value.getUint8(0);
console.log(`Battery: ${level}%`);
}, 1000);
}Heart Rate Monitor
import {
requestDevice,
connect,
startNotifications,
disconnect,
} from "@jts-web/web-ble-lite";
async function monitorHeartRate() {
const device = await requestDevice({
filters: [{ services: ["heart_rate"] }],
});
await connect(device);
await startNotifications(
device,
"heart_rate",
"heart_rate_measurement",
(data) => {
const flags = data.getUint8(0);
const rate16 = flags & 0x1;
let heartRate;
if (rate16) {
heartRate = data.getUint16(1, true);
} else {
heartRate = data.getUint8(1);
}
console.log(`Heart rate: ${heartRate} bpm`);
}
);
// Stop after 30 seconds
setTimeout(() => {
disconnect(device);
}, 30000);
}Development
# Install dependencies
npm install
# Build
npm run build
# Lint
npm run lint
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with UI
npm run test:ui
# Run tests with coverage
npm run test:coverageTesting
The library includes comprehensive tests using Vitest. Tests cover:
- ✅ Error classes (NotSupportedError, PermissionDeniedError, DeviceDisconnectedError)
- ✅ Browser detection (Chrome, Edge, Safari, Firefox, Unknown)
- ✅ Web Bluetooth availability checks
- ✅ Device request and connection handling
- ✅ Characteristic read/write operations
- ✅ Notification start/stop functionality
- ✅ Error handling for unsupported browsers
Running Tests
# Run all tests once
npm test
# Run tests in watch mode (re-runs on file changes)
npm run test:watch
# Open Vitest UI for interactive testing
npm run test:ui
# Generate coverage report
npm run test:coverageTest Structure
src/index.test.ts- Main test file with unit tests for all exported functionssrc/test/setup.ts- Test setup file with mocks and helpers for browser environment simulation
Tests use jsdom to simulate a browser environment and mock the Web Bluetooth API for testing without requiring actual Bluetooth hardware.
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
