Epiphany Lab / web and mobile

Four products, built solo and shipped.

From first commit to store approval. All four are live right now: two on the App Store and Google Play, all four on the web. famula, the newest, has its iOS and Android apps in store review. Every one of them is open to try.

4products live
4app store listings
2native platforms
10+yrs in software
Selected work

Every link below opens a running product.

famula

Your partner who works while you are away · Web, with iOS and Android in store review

famula is your partner for the everyday things that quietly eat your time and money. Tell it what you would like looked after, connect an account, and it gets on with it, even while you are away.

It notices what you would want to know before you do: a bill that crept up, a subscription you stopped using, a refund that never came through. Then it follows through, and tells you what it did, as it happens.

A few things famula does for you

  • Finds a cheaper phone, internet or insurance plan, and helps you switch
  • Tells you when a bill goes up, and finds the subscriptions you stopped using
  • Plans the week's dinners and fills the grocery cart
  • Chases a refund or a disputed charge until it is settled
  • Watches something you want and tells you when it hits your price
  • Reads a bill or letter you share, and reminds you before anything is due
famula's welcome: Hi, I'm famula. I work while you are away. A conversation with famula: a cancelled subscription, a question about the refund, and famula reporting the refund secured
Tavo app icon

Tavo

Real-time city discovery · iOS, Android, Web

A live map of what is actually happening around you right now. Venues, events and crowd-sourced signals on one surface, ranked so a single category cannot flood the map.

The hard part was never the map. It was making a cold-start location product feel alive in any city on the first open, which meant aggregating several event providers behind one schema, scoring them for quality, and sampling the results for variety rather than just proximity.

What I built

  • Next.js on Vercel with Supabase Postgres and row-level security
  • A live event pipeline over Ticketmaster and SeatGeek, normalised into one schema
  • Google Maps with custom clustering and a diversity-sampled feed
  • Native iOS and Android through Capacitor, both approved and published
  • Stripe subscriptions, with native paywalls suppressed to stay inside Apple's IAP rules
  • Push notifications via OneSignal and APNs
Next.jsTypeScript SupabasePostgreSQL CapacitorGoogle Maps StripeVercel
Tavo home screen: Ask Tavo, Start a Vibe, and a live feed of nearby places Ask Tavo answering with a pick from the live nearby feed
Tonecraft app icon

Tonecraft

AI conversation simulator · iOS, Android, Web

Practice a difficult conversation before you have it. Describe the situation, set your intent and tone, then walk six turns against a simulated counterpart and get a confidence score, a risk forecast and a message you can actually send.

A different shape of problem from Tavo: no map, no third-party data, but a stateful multi-turn LLM flow that has to stay coherent across turns and degrade safely when the model does something unexpected. It ships as one container, which keeps the whole thing cheap to run and trivial to reason about.

What I built

  • React and Vite front end, FastAPI and Python back end
  • One Docker container on Fly.io with a persistent volume and an HTTP health check
  • Multi-turn LLM flow with scoring and outcome prediction
  • Google OAuth, session handling, and a free tier that needs no card
  • Stripe subscriptions on monthly and annual plans
  • Transactional email and Sentry error tracking
  • Native iOS and Android through Capacitor, both published
ReactVite PythonFastAPI DockerFly.io StripeOAuth
Tonecraft landing screen Tonecraft conversation setup screen

StripeRescue

B2B SaaS · Stripe revenue recovery · Web

Failed payments, expired cards and silent churn cost subscription businesses real money every month. StripeRescue connects to an existing Stripe account read-only, finds the leak, retries intelligently, and sends the recovery email that actually brings the customer back.

The interesting half is the second product inside it: it also opens a pull request against the customer's repo with the card-update UI, webhook hardening and retry logic that subscription apps routinely miss. Two OAuth integrations, two very different trust boundaries, one onboarding flow that has to feel safe enough to connect both.

What I built

  • Next.js on Vercel with Supabase behind it
  • Stripe Connect, with a read-only audit path as its own low-commitment funnel
  • GitHub integration that opens code patches against a customer repo
  • Webhook ingestion for payment failure and churn events
  • Two-tier subscription pricing with a 30 day free trial
Next.jsTypeScript SupabaseStripe Connect GitHub APIWebhooks Vercel
StripeRescue landing page
AI in production

Not "I can call an API". The parts that break.

Every product on this page has a language model somewhere in its critical path, which means I have spent my time on grounding, structured output and failover rather than on prompt demos.

Grounding, so it stops inventing

Tavo's assistant answers over live venue data. Getting it to stop naming places that do not exist took re-injecting the candidate set on every turn, replacing free-text place names with a structured id token, dropping temperature, and matching on the last mention rather than the first. When it still drifts, it falls back to the real feed instead of guessing.

Failover across providers

One shared streaming layer fronts three inference providers and moves to the next on any non-200 or network error, so a single vendor outage does not take a feature down. Streaming is server-sent events, so the interface fills in as tokens arrive.

Multi-turn state that holds

Tonecraft simulates a six-turn conversation where each turn depends on the last, then scores confidence and forecasts risk. The hard part is coherence across turns and degrading safely when the model returns something unexpected.

Cost control as a design constraint

Consumer apps cannot absorb frontier-model pricing per interaction. These run on small fast models with capped output, chosen per task, because the product has to stay solvent at the price the user actually pays.

AI that writes code, reviewed by a human

StripeRescue opens pull requests against a customer's repository with the card-update UI, webhook hardening and retry logic that subscription apps miss. It proposes; a person merges.

Knowing when not to use it

Most of what these products do is ordinary engineering. A model is used where it earns its latency and its cost, and nowhere else. That judgement is most of the work.

Capabilities

What the work covers.

Web apps, end to end

Next.js or React, with auth, payments and a real database. Deployed, monitored, and documented down to the deploy path.

Native from a web app

An existing web app onto iOS and Android through Capacitor, then through both store reviews. Done twice; both apps are live.

The hard integrations

Stripe, OAuth, LLM APIs, maps, third-party data sources. The kind that has to keep working after everyone stops looking at it.

Build and release pipelines

Builds that fail, deploys nobody trusts, a release process that needs one person present. I have untangled all three.

The conversation around the code

A decade as a sales engineer, running technical evaluations with customers and exec teams as well as with the codebase.

One person, front to back

Every product on this page was built by one person: schema, API, front end, native shell, payments, store submission.

TypeScriptReactNext.js PythonFastAPINode.js PostgreSQLSupabaseDocker CapacitoriOSAndroid StripeOAuthLLM APIs VercelFly.ioSentry
Background

Ten years explaining software. Then I went and built some.

I spent a decade as a sales engineer and solutions architect at Port, Lacework, Spot.io, SignalFx and Couchbase, running technical evaluations for Fortune 500 buyers and building the demos and proofs of concept that decided them. Before that I wrote C++ and JavaScript on the mortgage-backed securities analytics team at Bloomberg.

I have sat on the other side of enough technical evaluations to know which corners get cut and which ones get found, and I write the code myself. Degrees from the University of Pennsylvania and the University of Delaware.