gzl.dev/blog
field notes, mostly
18 posts
August 27, 2026
7 min
Nine ways to say yes
I taught a Light Phone to speak an Oura ring's protocol over BLE. Then I spent a week failing to tap a button that doesn't exist.
Light PhoneBrightOuraBluetoothAndroid
August 21, 2026
6 min
Field notes on LightOS
What the Light Phone III's OS actually is underneath: Android with the Google removed, hardware that talks in key events, and conventions nobody voted on.
Light PhoneLightOSAndroid
August 21, 2026
1 min
A tape recorder, not a voice recorder
BrightRecorder: clips named for where and when, tapes that are just folders of WAVs, and the wheel finally doing the job it was born for.
Light PhoneBrightRecorder
August 18, 2026
2 min
Why I put an app store on a phone designed to have none
Yes, I see the irony. The argument for building it, why there's no server behind it, and the afternoon I accidentally dropped everyone's apps from the index.
Light PhoneBrightMarket
August 14, 2026
2 min
A good fork says thank you
A lot of what I ship is other people's work with my name nearer the top than it deserves. Some rules I try to fork by.
Light Phoneopen source
August 11, 2026
2 min
My bug reports file themselves
Shake the phone three times and the app files its own GitHub issue. Then an AI triages the queue every hour — under strict instructions that guessing is worse than waiting.
Light PhoneAItooling
August 8, 2026
2 min
Fifteen copies of the same file
The least interesting code I maintain is the code I'd save first in a fire. On finally building the shared library.
Light PhoneKotlin
August 8, 2026
2 min
BrightMarket is out
The app store ships: browse on a desktop, install by QR, track updates on the phone, and get your own app into the catalog.
Light PhoneBrightMarket
August 7, 2026
2 min
One column of scores
Twenty-two leagues from four keyless public APIs, in one grayscale column. How BrightSports gets scores with no account and no push.
Light PhoneBrightSports
August 6, 2026
3 min
The MetroCard inside my phone
I dissolved a transit card in acetone and moved its nervous system into the battery compartment. Tap-to-pay is back, sort of.
Light PhonehardwareNFC
August 6, 2026
2 min
Every button does what you tell it to
The follow-up to the keylayout post: BrightControl itself, why the defaults took longer than the code, and the trust problem with accessibility services.
Light PhoneBrightControldesign
August 5, 2026
1 min
Roll is out
The camera app ships: a filter wheel on real hardware, purikura with four-shot strips, date backs, and a privacy lesson from launch day.
Light PhoneRoll
August 4, 2026
2 min
The keylayout file Light left behind
The scroll wheel is just key events. Everything I learned reading Generic.kl off the phone, and the accessibility service that became BrightControl.
Light PhoneAndroid
August 2, 2026
3 min
Rewriting the camera
Roll's whole design is one gesture, stolen from a contact sheet. Plus the filters that got away from me — purikura on a monochrome phone, and datamoshing experiments that mostly produce mud.
Light Phonedesign
July 29, 2026
1 min
A QR scanner, and its desktop twin
The modern world hands you addresses as QR codes and the Light Phone couldn't read them. A scanner for the phone, a generator page for every other screen.
Light PhoneLightQR
March 22, 2026
1 min
BasilNet, a year later
What broke, what I'd trim, and how the media server quietly became infrastructure for everything else I build.
Dockerhomelabself-hosting
March 8, 2026
1 min
I built a bad DSLR on purpose
It took worse pictures than my phone. It's one of the most useful things I've ever built.
hardwarephotography
January 10, 2025
1 min
Building BasilNet: My Home Server Stack
How I built a 15-service media server with Docker Compose, Gluetun VPN, and Home Assistant integrations.
Dockerhomelabself-hosting
← all posts
August 8, 2026 · 2 min

BrightMarket is out

Light PhoneBrightMarket

BrightMarket shipped yesterday. It’s two halves that meet in the middle.

The browsing lives on the desktop. brightmarket.gzl.dev is a real catalog — read about a tool, decide if you want it, scan its code with the phone, and it opens in BrightMarket ready to install. Browsing on a big screen, installing on the small one.

The tracking lives on the phone. The other half watches GitHub releases and tells you when something’s out of date. It’ll track any repo that publishes APKs, including ones that have nothing to do with the catalog, so you give up nothing you already follow. And you don’t rebuild your setup by hand: import your Obtainium export and it takes the lot. Catalog apps become normal entries. Everything else is tracked exactly as it was.

The choice at first launch

The part I sweated most: a gallery on your phone is a scrollable feed, and a scrollable feed on a Light Phone kind of defeats the point. So the app asks, first thing. Keep browsing on the phone if you want it, or go extra light, and the phone only ever shows what you’ve installed and what needs updating. New apps arrive by scanning a code off the desktop. You can still patch something at 2 a.m. without finding a laptop. You just can’t wander.

The friction is asymmetric on purpose. Turning browsing on is one tap. Turning it back off means scanning a code from the desktop page. Falling off the wagon should be slightly harder than climbing back on. I wrote about why the app is built this way separately.

What’s in it

At launch: the twenty-odd apps I’ve built for my own phone plus my forks of community tools — a camera, an ebook reader, RSS and newsletter readers, a TOTP authenticator, live scores, subway times, an Apple TV remote, a notebook, a couple of games. All free, all open source.

Getting your own app in

If you’ve made something for the LPIII, add it. Open the submit page, sign in with GitHub, pick a repo of yours that has a release, done. The sign-in asks for read:user and nothing else: it can see which public repos you own and can’t write anywhere.

Everything after that is a script. It checks that the release has an APK attached, reads the applicationId out of the APK itself rather than trusting what the form told it, and opens a pull request. Once that lands, the next index build picks your app up and it shows in the catalog.

Two things worth knowing before you submit. The repo has to publish a real release with the APK attached, not just source. And the applicationId is what the update tracker keys on, so changing it later breaks the update path for everyone who already installed you.

Launch day, honestly

The best bug reports arrived within hours. Uninstalling wasn’t obvious enough — fixed. Adding a repo required making a QR code when typing a URL would do — added. This is the whole reason to ship: a week of real users beats a month of me squinting at my own UI. If Light eventually ships an official tools store, I genuinely hope it’s better than mine. Until then: brightmarket.gzl.dev/apk on the phone, and everything else installs from inside.