Inspiration
I'm always catching my Bluetooth devices, let it be my headphones, smartwatch or earbuds - dying or sitting at such a low percentage that I could only use it for a shorter time than I'd like to. I noticed that I would only find out the battery's percentage while it's connected to whatever I was using it on. Sure, apps exist that solve this. But when I sat down to think of a project idea, I started from a simple question: what's a frustration I actually live with, even if it's small? This was it. Something I could relate to, something I'd genuinely use. I wanted one clean dashboard that shows me the state of all my devices at a glance.
What it does
BatteryLens connects to your Bluetooth devices via the Web Bluetooth API and reads their battery levels directly in the browser. Devices appear in a widget grid with animated circular battery indicators and a device list with battery bars and relative timestamps. Last-known battery % is saved to localStorage so your devices stay visible even after closing the tab. You can rename any device inline, and if you change your mind a restore button snaps the name back. Six themes let you match the app to your vibe.
How we built it
Pure HTML, CSS, and JavaScript - no frameworks, no build tools, no backend. Bootstrap 5 for layout, Web Bluetooth API for device communication, localStorage for persistence. The architecture is five JS files loaded in order: utils, storage, bluetooth, ui, and app. The build followed a structured spec-driven workflow: scope → PRD → technical spec → build checklist → build. Every file, function, and data shape was planned before a single line of code was written.
Challenges we ran into
Web Bluetooth has some real quirks. The API generates a new device id on every requestDevice call, so the same physical device could be added twice - fixed by deduplicating on device name as a fallback. The connected status couldn't be stored in localStorage because stale badges would appear on reload, so live connection state had to be tracked separately in a runtime Set. Disconnect event listeners also stacked on reconnect, causing callbacks to fire multiple times - fixed by storing and removing the handler before re-attaching.
Accomplishments that we're proud of
Getting the Web Bluetooth API working reliably on Windows was harder than expected, and the reconnection flow - auto-retrying up to 3 times, updating battery and badge on success - works smoothly. The rename + restore feature wasn't in the original spec but felt like the right addition once the list was live.
What we learned
Writing a spec before building isn't just documentation - it's decision-making upfront. Every edge case I resolved in the spec (unsupported battery devices, reconnection retry strategy, localStorage shape) was one less blocker during the build. The spec-driven workflow made the actual coding feel structured and calm rather than chaotic.
What's next for BatteryLens
- Low battery notifications (browser Notifications API)
- Battery history chart per device
- Support for more device types as Web Bluetooth coverage improves
Built With
- bluetooth
- bootstrap-5
- css
- html
- javascript
- web
Log in or sign up for Devpost to join the conversation.