Tom / Approach / 04 · Build

"How I build
full stack."

How I've built with engineers, and how I use AI to build fullstack myself. From only knowing front-end and design, to shipping full apps end-to-end.

How I work with engineers

The design isn't done until the thing on the user's screen matches the intent. Hand-off is where the collaboration starts, not where it ends.

Where the real collaboration happens

The interesting work happens after the spec is done. At Metaboly, we had a spike in sign-up drop-off that I couldn't reproduce in testing. I went across devices, browsers and OS settings: nothing. The issue turned out to be a third-party UI library rendering the sign-up form's input fields invisible for users on system dark mode. The inputs were there; they just couldn't be seen. We found it by going into Hotjar, identifying exactly where people were abandoning the flow, then watching session recordings until we saw someone hit the broken state on their device. The engineer patched it the same afternoon. Without the recordings we might have tested for weeks and never seen it.

At Stashrun, I prototyped the post-game stash reveal and the engineer wired up the data side, but the curves felt wrong on live values. We met in the middle: adjusted easing on my end, a cleaner data binding on his. That conversation only happened because QA surfaced the bug on real data, not a static prototype.

Tom is like a designer, PM and founder combined. He can anticipate technical blockers. His flows are clear and he always makes sure we fully understand what we're building and why before we start.
Vikram Modh
Vikram Modh
Senior Software Engineer, Stashrun

What that looks like in practice

  • All states, upfront. Figma frames covering the happy path, edge cases, loading, and errors, so nothing needs guessing mid-build.
  • Annotated specs. Behaviour, copy edge cases, transition timing, accessibility, API latency handling.
  • Structured tickets. Title, description, acceptance criteria, attachments. Clear enough that context doesn't get lost in Slack.
  • On-device QA. Real network, real data. Bugs go back into Linear with screen recordings, side-by-sides, and a clear blocker vs. polish call.
  • Design adapts to constraints. If the framework pushes back, I find a path that works for both sides; no one wastes sprints on a fight that doesn't need to happen.
Stashrun
Inbox
My issues
Projects
iOS App
Design System
Teams
In Progress 6
Backlog 14
Done 31
v0 QA: UI Polish
12 issues · filed by Tom
In Progress
SR-142 Post-game stash reveal: easing snaps on Android real data Bug
SR-138 Terminal typewriter: line height collapses at 360px viewport Design
Backlog
SR-135 Onboarding CTA: bottom sheet clips behind home indicator iPhone SE Bug
SR-131 My Runs empty state: illustration overflows on Android 720p Design
SR-129 Coin counter: font tabular nums not applied, digits jump on update Bug
Done 31
SR-117 Game screen: tap zone 8px short of 44pt minimum Bug
SR-112 Login: keyboard pushes content off-screen on iPhone 12 mini Bug
+ 24 more resolved issues
Illustrative Linear tickets, real system, sanitised issue titles

The QA system built from scratch at Stashrun

When I joined Stashrun there was no QA process. No spec for what "done" meant, no system for filing bugs, no way to track whether a fix actually shipped. I built one before the first release went out.

QA Store
  • UI comparison across devices
  • Documented issues with screen recordings
  • Discussion threads per product feature
How to QA
  1. Open QA doc & find the screen
  2. Compare design vs. build side-by-side
  3. Screen record the issue on device
  4. Log to Linear: title, severity, recording
  5. Mark status: Blocker / Polish / Done
  6. Re-test on device after fix ships
Scope
  • Onboarding
  • Game
  • Post-game
  • My Runs
  • Starting a Run
  • Supplementary pages
  • Login / Signup
v0 UI QA Figma board, all sections

Now: full apps end-to-end with Claude Code

What used to need a team (PM, design, implementation) I now run solo, with Claude Code as my pair. I scope the problem, design the flows, and ship it in code, most often Next.js and React. The handoff overhead is gone, and iteration that took days now takes minutes.

Scope

I define the brief, decide scope, and write the acceptance criteria. The same content I used to put in Linear tickets, now spoken into Claude.

Curate

First move is tone and mood. Clinical? Warm? Expert? Approachable? Everything hangs off this answer: type, colour, motion, copy. I collate moodboards for my own inspiration and feed them into Claude so the build inherits the right feel.

Design

I craft the bones and crown jewels by hand. Layouts, hero elements, and the key interaction points that anchor the UX. Claude constructs the connective tissue between them.

Refine

Smooth out rough edges and if that doesn’t work, repeat the previous step. Once I’m happy with the broad strokes of the live result, I push the details into shape, and refine the moments that don’t quite land yet. Small prompts, small commits, fast feedback.

Implementation

Claude writes the React/Next code. I direct, refactor where needed, and review the visual and code output with a fine tooth comb to own the final shape of the product inside and out.

Worked examples. This portfolio you’re reading is built this way end-to-end: full-stack Next.js, custom GSAP scroll animations, embedded live-prototype iframe, the lot. So is the Stashrun terminal prototype ↗ shown in section 03 of that case study.

The bottleneck isn’t code anymore. It’s developed through taste and product judgement, which has been honed by years of experience. Knowing what to build, what to leave out, and what’s worth fighting for is the part that still needs a designer’s brain.

Next Approach 05 · Point of view