Firsthand
Mac and iPhone app pair for recording phone-in-hand product demos, composited live and finished in one take. 0→1 solo product: design, product direction, and shipping. Signed, notarized, self-updating, and taking payment.
- Role
- Product direction, design, every product decision, testing, quality bar
- Type
- 0→1 solo product, Mac + iOS + web
- Platform
- macOS 14+, iOS 17+, Next.js on Vercel
- Tools
- SwiftUI, AVFoundation, Core Image, Figma, Claude Code

Eight weeks from an idea to a signed, notarized, self-updating Mac app, an Apple-approved iPhone beta, and a working payment pipeline. Built solo, with Claude as the engineer.
The moment this started
I kept watching indie developers ship something good and then post a demo that undersold it. They all had tools. The tools are the problem, because they produce the wrong thing. Screen recorders make software look produced: smooth cursor easing, animated zooms, a soundtrack. Polished, and somehow less believable. The most persuasive demo I have ever seen was someone holding a phone across a table and saying look at this. The bet behind Firsthand is that authenticity converts better than polish, and that showing something unmediated builds more trust than a rendered screen capture.
Overview
Firsthand is a Mac app with an iPhone companion. The phone broadcasts its own screen over Wi-Fi while staying fully usable in your hand. The Mac composites that with your webcam and microphone in real time and writes a finished video the moment you stop recording. No editing timeline, no render step.

By the numbers
| Measure | Detail |
|---|---|
| Shipped | macOS app 1.0.2, iOS public TestFlight beta, marketing site |
| Code | 5,515 lines Swift (Mac), 1,131 Swift (iOS), 3,484 TypeScript (web) |
| Documentation | 2,577 lines across 8 living documents, 58 dated build entries |
| Releases | Three in eight days, two of them fixing what real testing found |
The problem, by who has it
The indie developer who is also their own marketer. They build it, demo it, cut it for socials and post it, with no team to hand any of it to. Every hour spent in an editor is an hour not spent building.
The viewer. Produced demos have taught people to discount what they are watching. A demo that looks expensive reads as a claim rather than evidence.
The tools themselves. Screen recorders optimise for polish because polish is what they can automate. None of them can show a real hand using a real phone, which is the only thing that reads as proof.
North star
Three principles follow from it.
No timeline editor. Ever. The moment Firsthand ships keyframes and multi-track editing it becomes a worse Screen Studio instead of the only Firsthand. Finished when you stop talking is not achievable if there is an edit step, and offering one makes the fast path read as the compromise. Trim only.
The phone stays usable. The premise is a demo of the app being used. A frozen or mirrored screen would break the illusion the product exists to create. This forced Wi-Fi and a broadcast extension over a simpler wired capture.
Nothing leaves your Mac. No account, no cloud, no telemetry, no analytics, no crash reporting. Verifiable rather than asserted: the App Privacy answer is Data Not Collected, confirmed by grep.

Process
The sequence was positioning, then roadmap, then the capture pipeline, then the surfaces around it. Three documents were written before most of the interface existed and were kept current for the whole build: POSITIONING (who it is for and who it is not), ROADMAP (phases and non-negotiable principles), PROJECT (a dated build record, 58 entries).
It reads like process theatre, and it earned its keep. Eight weeks in I could not have reconstructed why half the decisions were made. The documents were the difference between a project I could still reason about and one I would have had to re-derive.
Decisions
No Screen Recording permission. Ever. The most alarming permission a Mac app can request, and Firsthand does not need it, because the phone sends its own screen. Writing Ever into onboarding turned a description into a commitment, and six weeks later two roadmap features collided with it. Mac screen sharing came off the roadmap. The live streaming work became a separate product.
Licences verified offline, with no customer database. Ed25519 signed keys, verified locally by the app. An online licence check would have quietly contradicted the promise that nothing leaves your Mac. Signing is deterministic, so a given email always produces the identical key, which removes the database entirely: reissuing a lost key is recomputation, and webhook retries are idempotent. The cost is that the signing key becomes irreplaceable.
Free forever with a watermark, rather than a trial. A time-limited trial produces a deadline. A watermark produces distribution, because every free user posting a demo is an advertisement, and the upgrade motive arrives at the moment they care how it looks.
Deleting the waitlist. It existed only because there had been no way to hand someone the app. Once the Mac app was a public download and the iPhone app an open beta, it was a gate with nothing behind it. Its form was also failing in production. Wiring up storage for a list I no longer wanted would have been work in the wrong direction.
Ship the updater before shipping to strangers. Auto-updates went in before the first public download, and were verified on a throwaway release published to an unadvertised feed, so the first time the update path ran for real it had already run for real. Immediately vindicated: 1.0 shipped with a broken microphone and 1.0.1 reached those users automatically.
What went wrong
The microphone entitlement, twice. Hardened Runtime and the App Sandbox spell it differently. With the wrong key macOS refuses audio before the permission system is consulted, so no prompt can appear and the app never shows up in System Settings at all. Diagnosed in July, fixed in a generated file, silently deleted by every subsequent project regeneration, and shipped broken in 1.0. The rule it produced: never hand-edit a generated file, because that fix is temporary by construction.
Testing on the machine that built it. Camera permission looked granted because it had been, months earlier. The camera pip appeared to jump corners, which turned out to be the layout reflowing whenever the phone feed stuttered. The window would not resize below 900x600. All invisible on my Mac, all obvious on a tester's.

Silent failure. The Mac would wait forever for a phone that insisted it was broadcasting, because Local Network access had been refused once, months earlier, and macOS never asks again. Nothing on either device said so.
The webhook that was never called. Paddle delivered three times per purchase and every attempt returned a redirect, because the destination was the bare domain rather than www. Browsers follow that silently. Paddle does not. Nothing reached the site, so nothing appeared in the logs, which is exactly what working code looks like.
Learnings
A promise is only worth something while it constrains you. No Screen Recording permission cost a feature and a product. If it had been free to keep, there would be no way to show it was true.
The AI can be confident and wrong; the test is right. The payment webhook assumed Paddle sends the buyer's email. It sends a customer ID. Left alone, every purchase would have taken the money and sent nothing, silently. A simulator run before going live caught it.
Remove the human from copying secrets. Two of the four payment failures were a mistyped API key and a private key whose header lines a password manager had stripped. The fix was a CLI that cannot mistype or reformat.
Read the sender's own record. Paddle stores the HTTP status it received for every delivery attempt. That distinguished never arrived from arrived and failed in one query, and meant no purchase had to be re-bought.
Numbers you invent will drift. The thank-you receipt hardcoded its figures, so the order number matched nothing in the payment dashboard and the item line and total both read $99, double-counting a purchase that was $86.09 plus tax.
What was designed
Mac app: capture pipeline, live compositor, canvas system with aspect and background control, device frame, lower third, takes drawer, trim, pre-flight readiness check, global hotkey, menu-bar quick record, four-step onboarding, licence activation. iPhone app: broadcast extension, pairing, first-run. Web: 12-page marketing site, pricing with checkout, licence fulfilment, download redirects, update feed.
What comes next
App Store submission for the iPhone app, which currently ships as an open TestFlight beta that expires every 90 days. Paddle live switch, pending seller verification. And one open architectural decision that gets more expensive daily: Firsthand records only the flattened composite, so every take recorded today can never be reframed, and reframe-after-recording is the headline feature of the next phase.
Reflection
The gap between design and shipped software is narrower than it was, and it closed while nobody was looking. What did not change is that judgement is the scarce input. Nothing ever told me not to build a timeline editor, or that the free tier should watermark instead of expire, or that the waitlist should be deleted rather than repaired. Implementation stopped being the bottleneck. Knowing what to build, and what to refuse, became the whole job.
Showing the full case study.
