Writing · · 2 min read

We ran our own admin on our own modules — and it made the product better

We sell composable, source-visible modules — auth, payments, admin, audit — that you compose into a backend you own. Until recently, our own platform used zero of them. The admin and api were entirely bespoke. For a product whose whole pitch is “use our modules,” that's a credibility gap. So we started running part of our own admin on our own modules.

Two things happened. We proved it works — and the moment we tried to use our own product for real, it showed us exactly where it fell short.

What we moved onto modules

  • Passkey login. Our admin's WebAuthn code was ~300 lines of bespoke logic. We extracted and re-shaped it into a real module (passkey-auth) — 33 tests, source-visible, now a public catalog entry. It returns a verified user; our host still mints the session (clean boundary).
  • The users admin reads. The list and detail endpoints now run on our admin-shell module instead of hand-rolled queries.

Then our own module wasn't good enough — so we fixed it

The users list shows a workspace_count per user — a correlated subquery. But admin-shell's data gateway only did SELECT <columns> FROM <one table>. It literally couldn't express the query our own admin needed.

We didn't find that in a roadmap meeting. We found it the second we tried to use the thing. So instead of working around it, we added a SQL-safe computed-column capability to admin-shell: developer-authored, read-only SQL expressions declared in the registry — excluded from writes, filters, and sort, with the identifier-validation model fully intact (we audited it for injection paths; there are none). Now every consumer of the module gets that capability for free.

That's the real argument for dogfooding: it's the fastest product feedback loop there is. Using your own product turns “someday” gaps into shipped improvements.

What we deliberately did NOT move (and why)

Honesty beats a bigger claim. These stayed bespoke on purpose:

  • Deployment, provisioning, Cloudflare, Stripe sync — orchestration and external-API state machines, not CRUD. Forcing them into a CRUD module would be fake dogfooding.
  • Domain actions (disable a user, change a plan, revoke a key) — actions, not generic CRUD; they stay bespoke endpoints.
  • Workspaces & tickets reads — not migrated yet; the users slice proves the pattern, the rest is follow-on.

So the honest claim isn't “we run entirely on our own modules.” It's: our users-admin reads and passkey auth run on our own modules, and using them made the product measurably better. The orchestration-heavy internals are still bespoke — by design.

The point

Composable, source-visible modules aren't just how we tell you to build. They're how we're starting to build, too — and the proof is that using them is already changing the product. If you want a backend you compose and own, the modules are right here:

pnpm create microservices-app@latest

Browse the module catalog or start from the quickstart.