Turn one app into everyone's app
toolsJune 10, 20265 min read
By

Turn one app into everyone's app

I had a weather page with four pinned family cities and exactly one configuration: mine. This is a build log about making it everyone's — converting a single-instance app into one anybody can spin up their own copy of, sharing the tenancy core across apps, reusing the renderer untouched, and surfacing the whole thing as a tile in an add-ons marketplace.

I have a public weather page with four pinned family cities, an animated sky, and a little colored mark for each person. It's one of my favorite things on the site — and it has exactly one configuration: mine. This is a build log about making it everyone's: taking a single-instance app and turning it into one anybody can spin up their own copy of, then putting that capability where people can find it.

One app, then many

My add-ons marketplace already lists a few of the site's own apps as launchable tiles — open the tile and you land in the app. The next move is to make those apps multi-tenant: give one a notion of instances, members, and per-instance data, and the marketplace tile stops meaning "open my app" and starts meaning "spin up your own."

Weather is the first conversion. Any signed-in person 1-clicks a board at /w/<slug>, adds the cities they care about (search powered by a key-free geocoder, or one tap for "use my location"), labels who lives where, and invites family by email to share the view. The public /weather showcase stays exactly as it was — four fixed cities, no account — as the front window.

The tenancy core is shared, not copy-pasted

The unglamorous half of multi-tenancy is the same every time: friendly unique slugs, email normalization, deriving a stable short id for each member. My first multi-tenant app (shared to-do boards) already had all of that, so the real work was extracting it. The slug/email/member-id primitives now live in one framework-agnostic module; the to-do boards re-export them for back-compat and the weather boards import them directly. A new tenant app composes the primitives instead of pasting the adjective/noun word-lists a third time.

On top of that sit three small tables — instances, members, locations — with row-level security on and no anonymous policy at all. The browser never holds a database key; it polls gated API routes, and every one of them resolves the caller to a membership before returning a byte.

Reuse the renderer, don't fork it

The temptation with "now make it configurable" is to copy the pretty component and start hacking. Instead I made the existing dashboard props-driven: it takes a list of locations, a forecast URL, and a storage key, and its defaults reproduce the public page byte-for-byte. A tenant board hands it the board's saved cities and a per-board forecast feed and gets the same animated sky, the same glass cards, the same "who lives here" marks — for free.

I also hoisted the actual upstream forecast fetch into a single module that both the public page and the boards call, so the two surfaces physically can't drift on the query or the shape of the data. One renderer, one data layer, two front doors.

Then a v2 pass to make it feel finished

Shipping the feature and finishing it are different jobs. The polish pass added the things you only notice once real people touch it: board cards that show role and a live city/people count, a warmer first-run state than "no boards yet," and a copy-link button so sharing doesn't depend on an email actually arriving.

The hardening pass closed the quiet edges. Tapping "use my location" twice used to add the same place twice — now a pure, tested helper folds coordinates into a ~110-meter cell and rejects the duplicate. There's a per-board member cap so an invite box can't fan out forever, and rate limits on the two writes that have a cost (creating a board, sending an invite). None of it changes what the app does; it just refuses to do the wrong thing.

The point isn't weather

The point is that the second conversion is cheaper than the first, and the third cheaper than the second. With the tenancy core shared and the renderer already props-driven, turning the next single-instance app into a spin-up-your-own one is mostly "add three tables and a marketplace tile" rather than a rewrite. A personal chore board, a household budget, a trip log — each is now a short hop. Weather just happened to have the prettiest renderer to prove it on.

Experience it yourselfSee the public weather dashboard →
Experience it yourselfBrowse the add-ons marketplace →
ShareXLinkedInHacker NewsEmail

Get the next one

An occasional note when something genuinely new ships here — essays, free tools, projects. No schedule, no filler, easy out.

Need something like this built?

I design and ship AI tools, full-stack apps, and data pipelines — end to end, to production. Tell me the problem in a sentence; I'll give you an honest read on fit within a day.

Work with me →