Case Study: Reframe — Building an AI Shopify App Solo, From First Commit to Paying Merchants
Most of what I write here is technical guides. This one is different: it’s a case study of Reframe, the AI Shopify app I built solo and still run — what I decided, what those decisions cost, and what came out the other end. If you’re evaluating whether to trust one engineer with a production AI system, this is the evidence. It’s deliberately not a tutorial; it’s about judgment, not implementation steps.
The product and the problem
Shopify merchants — especially dropshippers and small brands — get product photos from suppliers that look like they were taken in a warehouse, because they were. Studio photography is slow and expensive at catalog scale. Reframe turns those supplier photos into studio-quality product images: AI background removal, scene presets, batch processing across a whole catalog.
That one sentence hides the actual difficulty. The hard part of Reframe was never “call an image model.” It was building something a non-technical merchant trusts with their entire catalog, on infrastructure one person can run, at a cost structure that works when the product is priced for small businesses.
The constraints, honestly
Every architecture decision below traces back to four constraints:
- One person. I was the product manager, designer, engineer, and on-call rotation. Anything that needed babysitting was a liability, not a feature.
- GPU economics. Image models need GPUs; idle GPUs burn money. The workload is bursty — a merchant shows up with 400 photos, then nothing for hours. That rules out reserved GPU capacity and rules in serverless inference, which brings cold starts.
- Merchant trust. The customer doesn’t care about my pipeline. They uploaded photos of products they sell, and they need to know — at a glance — what happened to every one of them.
- Shopify’s platform. Webhooks, API rate limits, app review requirements, and an embedded-app UX you don’t fully control.
The decisions and what they bought
A deliberately boring core. Reframe is a Remix app on Postgres, deployed with zero-downtime deploys on Dokku on a VPS. Two processes: the web app and a polling worker. No message broker, no Kubernetes, no microservices. People are sometimes surprised that an “AI app” runs on something this plain — but the boring core is why one person can operate it. Every component I didn’t add is a component that has never paged me. The complexity budget was spent where it earns revenue: the pipeline.
Serverless GPUs, with the cold-start tax engineered around. Inference runs on Modal’s serverless GPUs, which solves the economics — I pay for compute when merchants are processing, nothing when they’re not. The cost is cold starts and concurrency limits, so the pipeline is built to hide them: while one batch’s results upload to Shopify, the next batch is already running inference, so the GPU never idles waiting on I/O. Jobs are split across fast and slow queues with independent concurrency limits, so a merchant’s quick single-photo edit never queues behind someone else’s 400-photo catalog run.
Reliability as a product feature, not an ops concern. This is the decision I’d defend hardest. In an AI pipeline, some jobs will fail — models time out, images are weird, third-party APIs hiccup. A solo-operated product can’t promise failures won’t happen, so Reframe is built so failures are never silent and never cost the merchant anything: every job has a clear visible state; failed jobs trigger automatic credit refunds with no support ticket needed; results sit in a 7-day review queue before archival so merchants can always see what happened to every photo and why; and worker-level error monitoring alerts me when something systemic breaks — before the support email arrives. Most days, the system handles its own bad news.
The unglamorous Shopify layer. Billing through Shopify’s subscription APIs, webhooks for the merchant lifecycle (install, uninstall, plan changes), transactional and lifecycle email via Resend. None of it is interesting to read about, all of it decides whether an app survives on the App Store.
Iterating with evidence instead of opinions
Shipping was the halfway point. What moved the business was treating product iteration as an engineering discipline:
- Session recordings over speculation. I used PostHog recordings to watch where merchants actually dropped off in onboarding — not where I assumed they did — and reworked that flow until it clicked. Churn fell.
- Model quality as a tracked metric. Merchants accept or reject each generated image; I track acceptance rates per model. When a model underperforms, that’s data, and it feeds straight into which models run in which presets.
- Usage-triggered outreach. Automated emails keyed to what a merchant has and hasn’t done in the app, monitored against churn until the numbers improved.
The pattern across all three: instrument first, then change things, then check the metric moved. The same loop I’d run on a client’s system.
Where it is now
Reframe is live on the Shopify App Store, revenue-generating, and processing thousands of merchant photos a month. It runs day to day without me in the loop — the worker retries what’s retryable, refunds what isn’t, and alerts me only for the genuinely new failure modes. It was built from first commit to first paying merchant by one person, and the operational design is the reason that’s sustainable rather than heroic.
There’s also a by-product: the tooling I built for image-model workflows became modl (no relation to Modal above — it’s my own open-source LoRA training and generation toolkit).
What this means if you’re hiring me
The transferable thing here isn’t the Shopify or the image models — it’s the shape of the work. Scope decided against real constraints; a system sized to the team that has to run it; reliability the customer can see; iteration driven by instrumentation rather than taste. That’s the same judgment I bring to a client’s billing system, search infrastructure, or AI pipeline.
If you want a production system built — or rescued — by someone who has run one with their own money on the line, let’s work together.
Related Articles
Automating E-Commerce Photography with AI
Why generative image editing failed for product photos, and the multi-model architecture that actually works — covering GPU deployment, cold starts, and the Build vs. Buy tradeoff.
Durable Agent Workflows on SQLite — Until You Need Temporal
Multi-step LLM agents fail halfway, wait on slow tools, and pause for human approval — so they need durable execution. The reflex is to reach for Temporal or Inngest on day one. I built crash-safe, resumable, human-pausable LLM workflows in ~200 lines on plain SQLite, then measured exactly where it runs out: a hard crash mid-run replays the finished steps and saves half the tokens, and the durable write ceiling is a flat ~1,000 steps/sec — far more than any LLM workflow needs. The honest conclusion: you graduate for architecture, not throughput.
One Day of Agent Observability: Five Bugs Found
I gave my kids' book agent proper logging in a morning — three plain files — and spent the afternoon fixing what the logs immediately caught: 73% of GPU time wasted, books in the wrong language, and two ways the model broke its own tool calls. Real numbers, same-day payback.
Do You Need a Glean? Onyx vs 80 Lines of Postgres
The enterprise-knowledge-search question is really build-vs-buy: pay for Glean, self-host the open-source Onyx, or build RAG on the Postgres you already run. Instead of a feature table, I stood up the full Onyx platform AND wrote the entire Postgres alternative in ~80 lines, pointed both at the same local Qwen 27B over the same company knowledge base, and asked the same questions. Both gave accurate, cited answers. The difference isn't quality — it's eleven containers and a connector marketplace versus one container and a prompt you own. Here's how to choose.