Skip to content

A one-person studio

I build apps by vibe coding.

Vibing Legends is a one-person software studio. AI writes the first draft, I read every diff, and tests hold the whole thing down. Here's the app that came out of working this way — and how it was put together.

shippedPF1e Campaigner · 19 source books · 5,609 pages curated

  • Next.js
  • React
  • TypeScript
  • Tailwind
  • Supabase
  • Postgres
  • Clerk
  • Swift
  • Python
  • Claude
  • Playwright
  • Vercel

The app

PF1e Campaigner.

A browser-based character builder and campaign manager for Pathfinder 1st Edition. It pairs a transparent rules engine — every derived stat expands to show its work — with realtime tools for a whole table: live combat sync, shared treasure, a session scheduler and homebrew authoring.

The PF1e Campaigner character sheet, showing derived stats with their stacking breakdowns expanded.
source books
19source books
pages curated
5,609pages curated
spells
1,800+spells
feats
1,270+feats
Visit the app(opens in a new tab)

How it's built

The decisions behind it.

The parts worth explaining — less the feature list, more why it holds together at this scale with one person building it.

Content as data, not code

The source books are curated into structured catalogs that live outside the app logic and are validated against the source on every build. Adding a feat is a data change, so the engine never gets edited to make room for one.

A conversational build loop

Features get described in prose, drafted by AI, then reviewed diff by diff before they land. The long tail — hundreds of archetypes, thousands of spells — is exactly the work that pays off when you take the typing out of it.

Correctness held down by tests

A rules engine is either right or it's useless. The catalogs carry floor checks, the derived-stat maths is unit tested, and Playwright drives the flows a player actually uses. Typed end to end, with CI gating every commit.

Every number shows its work

Each AC, save, skill and attack total expands into a stacking ledger, so you can see which feat, item, buff or condition moved it. That constraint shaped the data model far more than the UI.

Realtime assumed from day one

Live combat sync was in the data model at the start rather than bolted on later. Retrofitting multiplayer into something built single-player is the kind of rewrite this way of working exists to avoid.

Grounded AI, with evals

Rules questions are answered from the catalog via retrieval rather than from model memory, and a variant-evaluation harness scores changes against known-good answers. The failure mode here is a confident wrong answer, so it gets measured.

stackNext.js, React, TypeScript, Tailwind, Supabase, Postgres, Clerk

Approach

Vibe coding, minus the hand-waving.

Moving at the pace of conversation instead of the pace of tickets. It does not mean shipping whatever the model produced — here's what actually keeps it honest.

AI writes the draft

Most first drafts are generated. That's where the speed comes from — not from skipping steps, but from spending almost none of the day typing out code that was never in question.

A human reads every diff

Nothing lands unreviewed. Architecture, data model and the hard trade-offs are decided deliberately; generated code is a starting point, not a shipping artifact.

Tests are the safety net

Working this fast only holds up with types, unit tests, end-to-end coverage and CI on every commit. The boring parts are what make the quick parts safe.

Depth over breadth

One app, taken seriously, rather than a portfolio of demos. Rules-heavy products reward getting the domain properly modelled instead of shipping a thin shell.

The loop

What a build actually looks like.

The same four steps every time, whether it's a new feature or a whole app.

  1. 01

    Talk it through

    The product gets written down first — the flows, the edges, the parts that are genuinely hard. Nothing worth building comes out of a one-line brief.

  2. 02

    Get something running

    A deployed, real-data build early rather than a slide deck or a Figma file. It's much easier to react to software than to imagine it.

  3. 03

    Iterate in short loops

    Small changes, landed often, with types and tests from the first commit. Speed without a safety net stops being speed fairly quickly.

  4. 04

    Keep it maintainable

    Written so that the next person to open the repo — quite possibly me, a year later — can find their way around without a guided tour.

Questions

The ones you're already thinking.

What does “vibe coding” actually mean here?

Working at the pace of conversation rather than the pace of tickets, with AI writing a lot of the first draft. It doesn't mean nobody reads the output — I review every diff and own the architecture. The speed comes from removing the typing, not the thinking.

Doesn't that produce fragile code?

It does if you stop there. The counterweight is deliberately boring: static types, unit tests, end-to-end tests and CI on everything, exactly as you'd want on hand-written code. PF1e Campaigner is a rules engine — it's either correct or it's worthless — so it gets held to that.

Who builds these?

Just me. Vibing Legends is a one-person studio, which is part of why this way of working matters: it's what makes an app of this scope tractable for a single developer.

Are more apps coming?

Yes — a combat tracker, a standalone character sheet and some iOS work are all in progress. They'll be listed here once they're actually in production rather than while they're still half-built.

Are you taking on work?

This site exists to show what the studio has built rather than to sell anything. If it's relevant to something you're working on, send an email — always happy to talk.

Get in touch

Curious how it was built?

Happy to talk through the approach, the tooling, or any of the decisions behind the app.

hello@vibinglegends.com