Epiphany Lab / web and mobile
Hire on Upwork

I ship products, not prototypes.

Three products, built solo from first commit to store approval. All three are live right now: two on the App Store and Google Play, all three on the web. You can open every one of them before you decide whether to hire me.

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

Every link below opens a running product.

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 map view showing venue pins across Manhattan Tavo how it works screen
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 the part worth hiring for.

What I do for clients

What you can hire me for.

Ship a web app

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

Take it native

An existing web app onto iOS and Android through Capacitor, then through both store reviews. I have done this twice and both apps are live.

Wire in the hard integration

Stripe, OAuth, LLM APIs, maps, or a third-party data source. The kind that keeps working after you stop looking at it.

Fix the pipeline

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

Talk to your stakeholders

A decade as a sales engineer means I can run the technical conversation with your customer or your exec team, not just the one with your codebase.

Work solo, end to end

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.

That combination is the actual pitch. 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.