FeedFilters
Pricing Log in Sign up

Blog

  • All posts
  • Subscribe (Atom)

Recent

  • Where the cookie boundary didn't May 12, 2026
  • A CDN for most of it May 11, 2026
  • Done, not abandoned May 8, 2026
  • There's no catch May 7, 2026
  • Sixteen mockups May 6, 2026
  • From scripts to infrastructure May 5, 2026
  • Doing mail myself May 4, 2026
  • Easier now than later May 2, 2026

Archive

  • 2026 15 posts

An MVP in a day

April 20, 2026 · Kyle Cronin

What “MVP” meant for FeedFilters was small but specific. A user has to be able to sign up, add a feed, write a filter against it, and subscribe to the filtered output in their RSS reader. Without all four of those, nothing about the concept is testable. Everything else — polish, convenience features, admin tooling — could come later.

Day one didn’t get me there. Day one was the plumbing: a bootstrap script for the Linode host, a Docker setup that I’d flipped from Docker Desktop to OrbStack on my Mac, a Caddy reverse proxy configured to host multiple sites on the same box, and a GitHub Actions deploy workflow that pushed images to GHCR and pulled them on the host. None of that is the product. But all of it had to exist before the product could.

Day two is when the actual app showed up. In a single push I had schema and migrations for both databases, runtime config loading, full authentication (signup, email verification, login, sessions, logout), account settings (change email, change password, passkey management), feed add/edit/list, the filter engine itself with unit tests, the feed output endpoint with source caching, feed icon fetching, OPML import and export, an admin UI, SMTP wiring, folder support, and a first pass at rate limiting, error states, empty states, dark mode, and mobile layout.

Some of those decisions were obvious. A feed-filtering service has to fetch, parse, filter, and serve feeds, so the engine and the output endpoint were never in question. Others were less obvious. I went with passkeys and passwords from day one rather than adding passkeys later, which meant taking on the WebAuthn complexity up front (and getting bitten by a BE/BS-flag bug a few hours in). I split the data into two SQLite files, one for the application and one for metrics, to keep the operational schema from contending with the user-facing one. I shipped OPML import and export immediately because the people I’d want to use FeedFilters already have subscriptions sitting in some other reader, and their first interaction shouldn’t be retyping all of them. Dark mode and a mobile layout went in for the same reason — my own bar for “would I show this to a friend” included those.

I am still a little stunned by that list.

It’s not that any individual piece is hard. Auth is auth, CRUD is CRUD, parsing RSS is parsing RSS. But every one of those is its own little ecosystem of decisions: schema choices, edge cases, error paths, UI states, security details. Doing them all in a day, well enough that the concept of FeedFilters was actually testable end-to-end, would have been weeks of evening-and-weekend work for me alone. It wasn’t, because it wasn’t me alone.

The implementation experience was different from anything I’d done before. I spent most of that day at a level above the code — deciding what should exist, how the pieces should fit together, what the user flows should look like — and Claude did the typing. That isn’t to say I wasn’t reviewing what got produced. I reviewed all of it (sometimes by reading the code, sometimes by clicking through the running app), pushed back when I disagreed, and made the calls about which approaches to take. But the friction of producing code wasn’t the thing soaking up my attention. The design of the system was. There’s a real difference between a day where that’s what you’re doing and a day where you’re also fighting the language and the libraries to get the design typed out.

Working this way turns out to be a lot like writing. The hard part isn’t the first draft, it’s the revision. Trying to produce something polished on the first pass is slower than getting a rough version working and then sanding it down.

The MVP wasn’t pretty everywhere — some of those subsystems got real time spent on them later, and the proper design pass came much later still. But the product worked. I could create an account, add a feed, filter it, subscribe to the output in my feed reader, and watch the filtered version come through. That’s the moment the project went from idea to thing.

About· Help· Blog· Privacy & Terms
FeedFilters by Flat Six Software · © 2026