A developer at Flourish built three fully syncing mobile apps using Claude as the primary coding agent, keeping costs to £18/month on a standard Claude plan. The apps cover restaurant recommendations, face recognition training for prosopagnosia, and a custom Spotify album organizer. None of them are formally released. All three are functional, installed on an Android phone, and sync to a self-hosted server.
This is a detailed look at how the project was structured, what actually worked, and where the approach breaks down at scale.
The Three Apps
Each app solves a specific personal problem the developer could not fix with existing tools:
- Places: A replacement for Google Maps lists, which the developer found annoying to use and did not want to keep personal data locked in a free service.
- People: A face recognition trainer using spaced repetition to help the developer, who is face blind, remember people met while networking in a large city.
- Music (Toucan): A custom Spotify player built to solve the long-standing absence of folder organization for albums on Spotify. The developer attempted to switch back to buying MP3s first, found it too complicated, and built this instead.
Toucan is the only app publicly available. You can try it at toucan.flourish.org (choose “local only” to play with it without creating an account). The source code is on sourcehut.
Architecture: Local-First with Yjs and Hocuspocus

The standard path for apps like these is to build a personal SaaS: your own web server, your own database, a mobile app on top. The developer considered this and rejected it as clunky and excessive for personal use.
Instead, the project uses the local-first software model. Data lives primarily on each device. A sync server moves it between them in the background. Operations are fast because they run locally. Think Dropbox, but for structured data in databases rather than files.
For the sync layer, the developer chose Yjs, the most widely used local-first protocol. The server backend uses Hocuspocus, a less common server that writes to a SQLite database, making hosting and backups straightforward. One caveat: the data format inside the SQLite file is opaque and binary, not easily readable or portable.
The developer noted that no standard personal data sync server exists at the level of Nextcloud’s modest popularity. That gap required picking an obscure option rather than a well-maintained standard.
For the front end, the apps are JavaScript progressive web apps (PWAs). Installed via Chrome on Android, they behave identically to native apps. The same codebase runs on mobile and desktop. Firefox installation did not work. The developer considered building the UI in Rust with Tauri but chose the simpler path.
Sync runs to a self-hosted server at a local ISP rather than a third-party cloud service, which the developer preferred given that some data (faces, names on restaurant recommendations) is private.
️ Development Process

The developer used Claude Opus on an £18/month plan for almost all of the coding. A collaborator named Fable helped with initial planning, though the developer notes that several of those early decisions turned out to be wrong and were refactored later anyway.
The workflow follows a pattern that has become standard in LLM-assisted development:
- Large features get a written plan in a
plans/directory first. - The developer edits the plan and makes decisions on it.
- Context window is cleared, then the agent implements the plan.
- UX and design changes get a Claude artifact showing multiple design options before any code is written.
- Bugs and tasks are tracked in a plaintext TODO.md file. The agent checks items off when done. The developer QAs and deletes them.
The developer deliberately stayed on the £18/month plan rather than upgrading to a more expensive tier. When hitting the 5-hour token window, the developer used !sleep 3h to pause Claude and Ctrl+B to background it (avoiding a 2-minute timeout). Claude resumes after the specified delay with limits reset, even without the developer present.
What Made the Agent Work Well
Two practices had outsized impact on output quality: strict TypeScript configuration with 100% test coverage, and a bespoke snapshot testing tool.
The developer references Jonathan Lange’s Galahad Principle on why 100% coverage specifically (not 95%, not 99%) creates a qualitatively different feedback loop for AI agents. The agents respond to these automated checks and use them to self-correct without human intervention.
The snapshot tool was built by Claude itself early in the project. A headless browser takes screenshots of every page in the application. The tool includes a web view for the developer, JSON output for the LLM, pixel diffing, filter and view options, basic performance measurements, and command-line flags to snapshot against another branch.
This proved critical during two large refactors, one to TypeScript and one to Preact (a lighter-weight React alternative). Both refactors completed without breaking anything. The developer confirmed pixel-perfect parity before and after each one.
Self-Improvement Loop
Following advice from Jyn, the developer added a lightweight self-improvement mechanism. A prompt in AGENTS.md instructs the agent to log anything it found difficult into SELF-IMPROVE.md, along with a count of how often the same problem recurs. The developer reviews this file and schedules fixes based on what shows up most often.
This surfaced issues including visually unstable snapshots, repeated churn in node_modules, performance problems, and missing tooling. The developer describes the mechanism as primitive but expects this category of AI developer experience work to become a significant part of the job in coming years.
One Serious Bug
A new list-reordering feature was never tested before the developer used it live on the phone. It deleted an entire list and all its contents. The bug was incorrect array manipulation in the local-first storage engine.
The agent helped recover the data, added logging to make sync behavior visible, and updated documentation to prevent the same mistake. No data was permanently lost, but it was a close call on a production database.
The Catch: Why This Does Not Scale Yet
The developer is direct about why these apps are not ready for other users despite being functionally polished:
- UX feedback is the bottleneck. Getting to a good mobile UX requires dozens of rounds of detailed product feedback. The developer logged and acted on dozens of items per app across months of daily use. Few people will do this work.
- Cross-platform frameworks are still clunky. PWAs are not familiar to most users. Widget sets that look good on both web and mobile are limited. Deployment is specialist work.
- Code ownership feels fuzzy. The developer has not closely reviewed the code and acknowledges this directly. For open source, the question of how to communicate quality and maintainability when the author has not deeply read their own codebase is unresolved.
- Local-first has no standard platform. There is no equivalent of having an email address for personal data sync. The infrastructure work to make that normal in 2026 does not have a clear path forward.
The developer closes with an open question: how do large collaborative open-source projects get developed with LLM agents in a way that genuinely benefits users? No answer is given. It is an honest ending for a project that is, by the developer’s own description, dangerously close to something other people could use but not quite there yet.


